Merge branch 'dev' into hash-problem

This commit is contained in:
Hakim El Hattab 2019-03-21 09:03:27 +01:00 committed by GitHub
commit b5fe0f8126
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 2050 additions and 820 deletions

View File

@ -1,5 +1,5 @@
language: node_js language: node_js
node_js: node_js:
- 4 - 11
after_script: after_script:
- npm run build -- retire - npm run build -- retire

View File

@ -1,7 +1,11 @@
/* global module:false */ /* global module:false */
module.exports = function(grunt) { module.exports = function(grunt) {
var port = grunt.option('port') || 8000; const sass = require('node-sass');
var root = grunt.option('root') || '.';
require('load-grunt-tasks')(grunt);
let port = grunt.option('port') || 8000;
let root = grunt.option('root') || '.';
if (!Array.isArray(root)) root = [root]; if (!Array.isArray(root)) root = [root];
@ -15,7 +19,7 @@ module.exports = function(grunt) {
' * http://revealjs.com\n' + ' * http://revealjs.com\n' +
' * MIT licensed\n' + ' * MIT licensed\n' +
' *\n' + ' *\n' +
' * Copyright (C) 2018 Hakim El Hattab, http://hakim.se\n' + ' * Copyright (C) 2019 Hakim El Hattab, http://hakim.se\n' +
' */' ' */'
}, },
@ -35,6 +39,10 @@ module.exports = function(grunt) {
}, },
sass: { sass: {
options: {
implementation: sass,
sourceMap: false
},
core: { core: {
src: 'css/reveal.scss', src: 'css/reveal.scss',
dest: 'css/reveal.css' dest: 'css/reveal.css'
@ -145,27 +153,10 @@ module.exports = function(grunt) {
options: { options: {
livereload: true livereload: true
} }
},
retire: {
js: [ 'js/reveal.js', 'lib/js/*.js', 'plugin/**/*.js' ],
node: [ '.' ]
} }
}); });
// Dependencies
grunt.loadNpmTasks( 'grunt-contrib-connect' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
grunt.loadNpmTasks( 'grunt-contrib-jshint' );
grunt.loadNpmTasks( 'grunt-contrib-qunit' );
grunt.loadNpmTasks( 'grunt-contrib-uglify' );
grunt.loadNpmTasks( 'grunt-contrib-watch' );
grunt.loadNpmTasks( 'grunt-autoprefixer' );
grunt.loadNpmTasks( 'grunt-retire' );
grunt.loadNpmTasks( 'grunt-sass' );
grunt.loadNpmTasks( 'grunt-zip' );
// Default task // Default task
grunt.registerTask( 'default', [ 'css', 'js' ] ); grunt.registerTask( 'default', [ 'css', 'js' ] );

View File

@ -1,4 +1,4 @@
Copyright (C) 2018 Hakim El Hattab, http://hakim.se, and reveal.js contributors Copyright (C) 2019 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

File diff suppressed because one or more lines are too long

30
css/reset.css Normal file
View File

@ -0,0 +1,30 @@
/* http://meyerweb.com/eric/tools/css/reset/
v4.0 | 20180602
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
main, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, menu, nav, section {
display: block;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -153,7 +153,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -11,8 +11,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
* GLOBAL STYLES * GLOBAL STYLES
*********************************************/ *********************************************/
body { body {
background: #222; background: #191919;
background-color: #222; } background-color: #191919; }
.reveal { .reveal {
font-family: "Source Sans Pro", Helvetica, sans-serif; font-family: "Source Sans Pro", Helvetica, sans-serif;
@ -149,7 +149,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;
@ -270,4 +270,4 @@ body {
*********************************************/ *********************************************/
@media print { @media print {
.backgrounds { .backgrounds {
background-color: #222; } } background-color: #191919; } }

View File

@ -152,7 +152,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -155,7 +155,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -153,7 +153,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -147,7 +147,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -149,7 +149,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -152,7 +152,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -156,7 +156,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -153,7 +153,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -16,7 +16,7 @@
// Override theme settings (see ../template/settings.scss) // Override theme settings (see ../template/settings.scss)
$backgroundColor: #222; $backgroundColor: #191919;
$mainColor: #fff; $mainColor: #fff;
$headingColor: #fff; $headingColor: #fff;

View File

@ -28,6 +28,8 @@ $heading2Size: 2.11em;
$heading3Size: 1.55em; $heading3Size: 1.55em;
$heading4Size: 1.00em; $heading4Size: 1.00em;
$codeFont: monospace;
// Links and actions // Links and actions
$linkColor: #13DAEC; $linkColor: #13DAEC;
$linkColorHover: lighten( $linkColor, 20% ); $linkColorHover: lighten( $linkColor, 20% );

View File

@ -162,16 +162,16 @@ body {
text-align: left; text-align: left;
font-size: 0.55em; font-size: 0.55em;
font-family: monospace; font-family: $codeFont;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0,0,0,0.3); box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
} }
.reveal code { .reveal code {
font-family: monospace; font-family: $codeFont;
text-transform: none; text-transform: none;
} }

View File

@ -149,7 +149,7 @@ body {
font-family: monospace; font-family: monospace;
line-height: 1.2em; line-height: 1.2em;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); }
.reveal code { .reveal code {
font-family: monospace; font-family: monospace;

View File

@ -12,13 +12,14 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<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">
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/reveal.css"> <link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/black.css" id="theme"> <link rel="stylesheet" href="css/theme/black.css" id="theme">
<!-- Theme used for syntax highlighting of code --> <!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css"> <link rel="stylesheet" href="lib/css/monokai.css">
<!-- Printing and PDF exports --> <!-- Printing and PDF exports -->
<script> <script>
@ -93,7 +94,10 @@
Press <strong>ESC</strong> to enter the slide overview. Press <strong>ESC</strong> to enter the slide overview.
</p> </p>
<p> <p>
Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out. Hold down the <strong>alt</strong> key (<strong>ctrl</strong> in Linux) and click on any element to zoom towards it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Click again to zoom back out.
</p>
<p>
(NOTE: Use ctrl + click in Linux.)
</p> </p>
</section> </section>
@ -195,16 +199,16 @@
</section> </section>
<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png"> <section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png">
<h2>Image Backgrounds</h2> <h2>Image Backgrounds</h2>
<pre><code class="hljs">&lt;section data-background="image.png"&gt;</code></pre> <pre><code class="hljs html">&lt;section data-background="image.png"&gt;</code></pre>
</section> </section>
<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png" data-background-repeat="repeat" data-background-size="100px"> <section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png" data-background-repeat="repeat" data-background-size="100px">
<h2>Tiled Backgrounds</h2> <h2>Tiled Backgrounds</h2>
<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre> <pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
</section> </section>
<section data-background-video="https://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" data-background-color="#000000"> <section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm" data-background-color="#000000">
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;"> <div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
<h2>Video Backgrounds</h2> <h2>Video Backgrounds</h2>
<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre> <pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre>
</div> </div>
</section> </section>
<section data-background="http://i.giphy.com/90F8aUepslB84.gif"> <section data-background="http://i.giphy.com/90F8aUepslB84.gif">
@ -217,7 +221,7 @@
<p> <p>
Different background transitions are available via the backgroundTransition option. This one's called "zoom". Different background transitions are available via the backgroundTransition option. This one's called "zoom".
</p> </p>
<pre><code class="hljs">Reveal.configure({ backgroundTransition: 'zoom' })</code></pre> <pre><code class="hljs javascript">Reveal.configure({ backgroundTransition: 'zoom' })</code></pre>
</section> </section>
<section data-transition="slide" data-background="#b5533c" data-background-transition="zoom"> <section data-transition="slide" data-background="#b5533c" data-background-transition="zoom">
@ -225,25 +229,32 @@
<p> <p>
You can override background transitions per-slide. You can override background transitions per-slide.
</p> </p>
<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background-transition="zoom"&gt;</code></pre> <pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background-transition="zoom"&gt;</code></pre>
</section>
<section data-background-iframe="https://hakim.se" data-background-interactive>
<div style="position: absolute; width: 40%; right: 0; box-shadow: 0 1px 4px rgba(0,0,0,0.5), 0 5px 25px rgba(0,0,0,0.2); background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px; font-size: 20px; text-align: left;">
<h2>Iframe Backgrounds</h2>
<p>Since reveal.js runs on the web, you can easily embed other web content. Try interacting with the page in the background.</p>
</div>
</section> </section>
<section> <section>
<h2>Pretty Code</h2> <h2>Pretty Code</h2>
<pre><code class="hljs" data-trim contenteditable> <pre><code class="hljs" data-trim data-line-numbers="4,8-9">
function linkify( selector ) { import React, { useState } from 'react';
if( supports3DTransforms ) {
var nodes = document.querySelectorAll( selector ); function Example() {
const [count, setCount] = useState(0);
for( var i = 0, len = nodes.length; i &lt; len; i++ ) { return (
var node = nodes[i]; &lt;div&gt;
&lt;p&gt;You clicked {count} times&lt;/p&gt;
if( !node.className ) { &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
node.className += ' roll'; Click me
} &lt;/button&gt;
} &lt;/div&gt;
} );
} }
</code></pre> </code></pre>
<p>Code syntax highlighting courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p> <p>Code syntax highlighting courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
@ -384,7 +395,6 @@ Reveal.addEventListener( 'customevent', function() {
</div> </div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script> <script src="js/reveal.js"></script>
<script> <script>
@ -393,17 +403,16 @@ Reveal.addEventListener( 'customevent', function() {
Reveal.initialize({ Reveal.initialize({
controls: true, controls: true,
progress: true, progress: true,
history: true,
center: true, center: true,
hash: true,
transition: 'slide', // none/fade/slide/convex/concave/zoom transition: 'slide', // none/fade/slide/convex/concave/zoom
// More info https://github.com/hakimel/reveal.js#dependencies // More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [ dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, { src: 'plugin/highlight/highlight.js', async: true },
{ src: 'plugin/search/search.js', async: true }, { src: 'plugin/search/search.js', async: true },
{ src: 'plugin/zoom-js/zoom.js', async: true }, { src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true } { src: 'plugin/notes/notes.js', async: true }

View File

@ -6,11 +6,12 @@
<title>reveal.js</title> <title>reveal.js</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/reveal.css"> <link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/black.css"> <link rel="stylesheet" href="css/theme/black.css">
<!-- Theme used for syntax highlighting of code --> <!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css"> <link rel="stylesheet" href="lib/css/monokai.css">
<!-- Printing and PDF exports --> <!-- Printing and PDF exports -->
<script> <script>
@ -29,7 +30,6 @@
</div> </div>
</div> </div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script> <script src="js/reveal.js"></script>
<script> <script>
@ -41,7 +41,7 @@
{ src: 'plugin/markdown/marked.js' }, { src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' }, { src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true }, { src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } } { src: 'plugin/highlight/highlight.js', async: true }
] ]
}); });
</script> </script>

File diff suppressed because it is too large Load Diff

71
lib/css/monokai.css Normal file
View File

@ -0,0 +1,71 @@
/*
Monokai style - ported by Luigi Maselli - http://grigio.org
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #272822;
color: #ddd;
}
.hljs-tag,
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-strong,
.hljs-name {
color: #f92672;
}
.hljs-code {
color: #66d9ef;
}
.hljs-class .hljs-title {
color: white;
}
.hljs-attribute,
.hljs-symbol,
.hljs-regexp,
.hljs-link {
color: #bf79db;
}
.hljs-string,
.hljs-bullet,
.hljs-subst,
.hljs-title,
.hljs-section,
.hljs-emphasis,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #a6e22e;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-selector-id {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

6
lib/js/head.min.js vendored

File diff suppressed because one or more lines are too long

2
lib/js/promise.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -20,24 +20,26 @@
"url": "git://github.com/hakimel/reveal.js.git" "url": "git://github.com/hakimel/reveal.js.git"
}, },
"engines": { "engines": {
"node": ">=4.0.0" "node": ">=9.0.0"
}, },
"devDependencies": { "devDependencies": {
"express": "^4.16.2", "express": "^4.16.2",
"grunt": "^1.0.1", "grunt": "^1.0.3",
"grunt-cli": "^1.3.2",
"grunt-autoprefixer": "^3.0.4", "grunt-autoprefixer": "^3.0.4",
"grunt-cli": "^1.2.0", "grunt-contrib-connect": "^2.0.0",
"grunt-contrib-connect": "^1.0.2", "grunt-contrib-cssmin": "^3.0.0",
"grunt-contrib-cssmin": "^2.2.1", "grunt-contrib-jshint": "^2.0.0",
"grunt-contrib-jshint": "^1.1.0", "grunt-contrib-qunit": "^3.1.0",
"grunt-contrib-qunit": "^2.0.0",
"grunt-contrib-uglify": "^3.3.0", "grunt-contrib-uglify": "^3.3.0",
"grunt-contrib-watch": "^1.0.0", "grunt-contrib-watch": "^1.1.0",
"grunt-sass": "^2.0.0", "grunt-sass": "^3.0.2",
"grunt-retire": "^1.0.7",
"grunt-zip": "~0.17.1", "grunt-zip": "~0.17.1",
"load-grunt-tasks": "^4.0.0",
"node-sass": "4.11.0",
"mustache": "^2.3.0", "mustache": "^2.3.0",
"socket.io": "^1.7.3" "socket.io": "^2.2.0",
"typescript": "^3.3.3333"
}, },
"license": "MIT" "license": "MIT"
} }

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
<link rel="stylesheet" href="../../css/reveal.css"> <link rel="stylesheet" href="../../css/reveal.css">
<link rel="stylesheet" href="../../css/theme/white.css" id="theme"> <link rel="stylesheet" href="../../css/theme/white.css" id="theme">
<link rel="stylesheet" href="../../lib/css/zenburn.css"> <link rel="stylesheet" href="../../lib/css/monokai.css">
</head> </head>
<body> <body>
@ -109,7 +109,6 @@
</div> </div>
</div> </div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.js"></script> <script src="../../js/reveal.js"></script>
<script> <script>
@ -122,7 +121,6 @@
// Optional libraries used to extend on reveal.js // Optional libraries used to extend on reveal.js
dependencies: [ dependencies: [
{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: '../highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, { src: '../highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },

View File

@ -7,13 +7,11 @@
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
root.marked = require( './marked' ); root.marked = require( './marked' );
root.RevealMarkdown = factory( root.marked ); root.RevealMarkdown = factory( root.marked );
root.RevealMarkdown.initialize();
} else if( typeof exports === 'object' ) { } else if( typeof exports === 'object' ) {
module.exports = factory( require( './marked' ) ); module.exports = factory( require( './marked' ) );
} else { } else {
// Browser globals (root is window) // Browser globals (root is window)
root.RevealMarkdown = factory( root.marked ); root.RevealMarkdown = factory( root.marked );
root.RevealMarkdown.initialize();
} }
}( this, function( marked ) { }( this, function( marked ) {
@ -199,81 +197,108 @@
*/ */
function processSlides() { function processSlides() {
var sections = document.querySelectorAll( '[data-markdown]'), return new Promise( function( resolve ) {
section;
for( var i = 0, len = sections.length; i < len; i++ ) { var externalPromises = [];
section = sections[i]; [].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) {
if( section.getAttribute( 'data-markdown' ).length ) { if( section.getAttribute( 'data-markdown' ).length ) {
var xhr = new XMLHttpRequest(), externalPromises.push( loadExternalMarkdown( section ).then(
url = section.getAttribute( 'data-markdown' );
datacharset = section.getAttribute( 'data-charset' );
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
if( datacharset != null && datacharset != '' ) {
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
}
xhr.onreadystatechange = function() {
if( xhr.readyState === 4 ) {
// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
// Finished loading external file
function( xhr, url ) {
section.outerHTML = slidify( xhr.responseText, { section.outerHTML = slidify( xhr.responseText, {
separator: section.getAttribute( 'data-separator' ), separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-separator-vertical' ), verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
notesSeparator: section.getAttribute( 'data-separator-notes' ), notesSeparator: section.getAttribute( 'data-separator-notes' ),
attributes: getForwardedAttributes( section ) attributes: getForwardedAttributes( section )
}); });
},
} // Failed to load markdown
else { function( xhr, url ) {
section.outerHTML = '<section data-state="alert">' + section.outerHTML = '<section data-state="alert">' +
'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
'Check your browser\'s JavaScript console for more details.' + 'Check your browser\'s JavaScript console for more details.' +
'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' + '<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
'</section>'; '</section>';
} }
) );
}
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
section.outerHTML = slidify( getMarkdownFromSlide( section ), {
separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
notesSeparator: section.getAttribute( 'data-separator-notes' ),
attributes: getForwardedAttributes( section )
});
}
else {
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
}
});
Promise.all( externalPromises ).then( resolve );
} );
}
function loadExternalMarkdown( section ) {
return new Promise( function( resolve, reject ) {
var xhr = new XMLHttpRequest(),
url = section.getAttribute( 'data-markdown' );
datacharset = section.getAttribute( 'data-charset' );
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
if( datacharset != null && datacharset != '' ) {
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
}
xhr.onreadystatechange = function( section, xhr ) {
if( xhr.readyState === 4 ) {
// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
resolve( xhr, url );
} }
}; else {
xhr.open( 'GET', url, false ); reject( xhr, url );
try { }
xhr.send();
}
catch ( e ) {
alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
} }
}.bind( this, section, xhr );
} xhr.open( 'GET', url, true );
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
section.outerHTML = slidify( getMarkdownFromSlide( section ), { try {
separator: section.getAttribute( 'data-separator' ), xhr.send();
verticalSeparator: section.getAttribute( 'data-separator-vertical' ), }
notesSeparator: section.getAttribute( 'data-separator-notes' ), catch ( e ) {
attributes: getForwardedAttributes( section ) alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
}); resolve( xhr, url );
}
} } );
else {
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
}
}
} }
/** /**
* Check if a node value has the attributes pattern. * Check if a node value has the attributes pattern.
* If yes, extract it and add that value as one or several attributes * If yes, extract it and add that value as one or several attributes
* the the terget element. * to the target element.
* *
* You need Cache Killer on Chrome to see the effect on any FOM transformation * You need Cache Killer on Chrome to see the effect on any FOM transformation
* directly on refresh (F5) * directly on refresh (F5)
@ -342,44 +367,47 @@
*/ */
function convertSlides() { function convertSlides() {
var sections = document.querySelectorAll( '[data-markdown]'); var sections = document.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
for( var i = 0, len = sections.length; i < len; i++ ) { [].slice.call( sections ).forEach( function( section ) {
var section = sections[i]; section.setAttribute( 'data-markdown-parsed', true )
// Only parse the same slide once var notes = section.querySelector( 'aside.notes' );
if( !section.getAttribute( 'data-markdown-parsed' ) ) { var markdown = getMarkdownFromSlide( section );
section.setAttribute( 'data-markdown-parsed', true ) section.innerHTML = marked( markdown );
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
var notes = section.querySelector( 'aside.notes' ); section.parentNode.getAttribute( 'data-element-attributes' ) ||
var markdown = getMarkdownFromSlide( section ); DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
section.getAttribute( 'data-attributes' ) ||
section.innerHTML = marked( markdown ); section.parentNode.getAttribute( 'data-attributes' ) ||
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) || DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
section.parentNode.getAttribute( 'data-element-attributes' ) ||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
section.getAttribute( 'data-attributes' ) ||
section.parentNode.getAttribute( 'data-attributes' ) ||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
// If there were notes, we need to re-add them after
// having overwritten the section's HTML
if( notes ) {
section.appendChild( notes );
}
// If there were notes, we need to re-add them after
// having overwritten the section's HTML
if( notes ) {
section.appendChild( notes );
} }
} } );
return Promise.resolve();
} }
// API // API
return { var RevealMarkdown = {
/**
* Starts processing and converting Markdown within the
* current reveal.js deck.
*
* @param {function} callback function to invoke once
* we've finished loading and parsing Markdown
*/
init: function( callback ) {
initialize: function() {
if( typeof marked === 'undefined' ) { if( typeof marked === 'undefined' ) {
throw 'The reveal.js Markdown plugin requires marked to be loaded'; throw 'The reveal.js Markdown plugin requires marked to be loaded';
} }
@ -392,14 +420,14 @@
}); });
} }
// marked can be configured via reveal.js config options
var options = Reveal.getConfig().markdown; var options = Reveal.getConfig().markdown;
if( options ) {
if ( options ) {
marked.setOptions( options ); marked.setOptions( options );
} }
processSlides(); return processSlides().then( convertSlides );
convertSlides();
}, },
// TODO: Do these belong in the API? // TODO: Do these belong in the API?
@ -409,4 +437,10 @@
}; };
// Register our plugin so that reveal.js will call our
// plugin 'init' method as part of the initialization
Reveal.registerPlugin( 'markdown', RevealMarkdown );
return RevealMarkdown;
})); }));

File diff suppressed because one or more lines are too long

View File

@ -7,33 +7,28 @@
var RevealMath = window.RevealMath || (function(){ var RevealMath = window.RevealMath || (function(){
var options = Reveal.getConfig().math || {}; var options = Reveal.getConfig().math || {};
options.mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js'; var mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
options.config = options.config || 'TeX-AMS_HTML-full'; var config = options.config || 'TeX-AMS_HTML-full';
options.tex2jax = options.tex2jax || { var url = mathjax + '?config=' + config;
inlineMath: [['$','$'],['\\(','\\)']] ,
skipTags: ['script','noscript','style','textarea','pre'] };
loadScript( options.mathjax + '?config=' + options.config, function() { var defaultOptions = {
messageStyle: 'none',
tex2jax: {
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
},
skipStartupTypeset: true
};
MathJax.Hub.Config({ function defaults( options, defaultOptions ) {
messageStyle: 'none',
tex2jax: options.tex2jax,
skipStartupTypeset: true
});
// Typeset followed by an immediate reveal.js layout since for ( var i in defaultOptions ) {
// the typesetting process could affect slide height if ( !options.hasOwnProperty( i ) ) {
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] ); options[i] = defaultOptions[i];
MathJax.Hub.Queue( Reveal.layout ); }
}
// Reprocess equations in slides when they turn visible }
Reveal.addEventListener( 'slidechanged', function( event ) {
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
} );
} );
function loadScript( url, callback ) { function loadScript( url, callback ) {
@ -64,4 +59,34 @@ var RevealMath = window.RevealMath || (function(){
} }
return {
init: function() {
defaults( options, defaultOptions );
defaults( options.tex2jax, defaultOptions.tex2jax );
options.mathjax = options.config = null;
loadScript( url, function() {
MathJax.Hub.Config( options );
// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
MathJax.Hub.Queue( Reveal.layout );
// Reprocess equations in slides when they turn visible
Reveal.addEventListener( 'slidechanged', function( event ) {
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
} );
} );
}
}
})(); })();
Reveal.registerPlugin( 'math', RevealMath );

View File

@ -347,6 +347,8 @@
upcomingSlide, upcomingSlide,
layoutLabel, layoutLabel,
layoutDropdown, layoutDropdown,
pendingCalls = {},
lastRevealApiCallId = 0,
connected = false; connected = false;
var SPEAKER_LAYOUTS = { var SPEAKER_LAYOUTS = {
@ -382,6 +384,10 @@
else if( data.type === 'state' ) { else if( data.type === 'state' ) {
handleStateMessage( data ); handleStateMessage( data );
} }
else if( data.type === 'return' ) {
pendingCalls[data.callId](data.result);
delete pendingCalls[data.callId];
}
} }
// Messages sent by the reveal.js inside of the current slide preview // Messages sent by the reveal.js inside of the current slide preview
else if( data && data.namespace === 'reveal' ) { else if( data && data.namespace === 'reveal' ) {
@ -398,6 +404,23 @@
} ); } );
/**
* Asynchronously calls the Reveal.js API of the main frame.
*/
function callRevealApi( methodName, methodArguments, callback ) {
var callId = ++lastRevealApiCallId;
pendingCalls[callId] = callback;
window.opener.postMessage( JSON.stringify( {
namespace: 'reveal-notes',
type: 'call',
callId: callId,
methodName: methodName,
arguments: methodArguments
} ), '*' );
}
/** /**
* Called when the main window is trying to establish a * Called when the main window is trying to establish a
* connection. * connection.
@ -512,28 +535,34 @@
} }
function getTimings() { function getTimings( callback ) {
var slides = Reveal.getSlides(); callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) {
var defaultTiming = Reveal.getConfig().defaultTiming; callRevealApi( 'getConfig', [], function ( config ) {
if (defaultTiming == null) { var defaultTiming = config.defaultTiming;
return null; if (defaultTiming == null) {
} callback(null);
var timings = []; return;
for ( var i in slides ) {
var slide = slides[i];
var timing = defaultTiming;
if( slide.hasAttribute( 'data-timing' )) {
var t = slide.getAttribute( 'data-timing' );
timing = parseInt(t);
if( isNaN(timing) ) {
console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
timing = defaultTiming;
} }
}
timings.push(timing); var timings = [];
} for ( var i in slideAttributes ) {
return timings; var slide = slideAttributes[ i ];
var timing = defaultTiming;
if( slide.hasOwnProperty( 'data-timing' )) {
var t = slide[ 'data-timing' ];
timing = parseInt(t);
if( isNaN(timing) ) {
console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
timing = defaultTiming;
}
}
timings.push(timing);
}
callback( timings );
} );
} );
} }
@ -541,15 +570,15 @@
* Return the number of seconds allocated for presenting * Return the number of seconds allocated for presenting
* all slides up to and including this one. * all slides up to and including this one.
*/ */
function getTimeAllocated(timings) { function getTimeAllocated( timings, callback ) {
var slides = Reveal.getSlides(); callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
var allocated = 0; var allocated = 0;
var currentSlide = Reveal.getSlidePastCount(); for (var i in timings.slice(0, currentSlide + 1)) {
for (var i in slides.slice(0, currentSlide + 1)) { allocated += timings[i];
allocated += timings[i]; }
} callback( allocated );
return allocated; } );
} }
@ -571,12 +600,51 @@
pacingMinutesEl = pacingEl.querySelector( '.minutes-value' ), pacingMinutesEl = pacingEl.querySelector( '.minutes-value' ),
pacingSecondsEl = pacingEl.querySelector( '.seconds-value' ); pacingSecondsEl = pacingEl.querySelector( '.seconds-value' );
var timings = getTimings(); var timings = null;
if (timings !== null) { getTimings( function ( _timings ) {
pacingTitleEl.style.removeProperty('display');
pacingEl.style.removeProperty('display'); timings = _timings;
if (_timings !== null) {
pacingTitleEl.style.removeProperty('display');
pacingEl.style.removeProperty('display');
}
// Update once directly
_updateTimer();
// Then update every second
setInterval( _updateTimer, 1000 );
} );
function _resetTimer() {
if (timings == null) {
start = new Date();
_updateTimer();
}
else {
// Reset timer to beginning of current slide
getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
var slideEndTiming = slideEndTimingSeconds * 1000;
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
var currentSlideTiming = timings[currentSlide] * 1000;
var previousSlidesTiming = slideEndTiming - currentSlideTiming;
var now = new Date();
start = new Date(now.getTime() - previousSlidesTiming);
_updateTimer();
} );
} );
}
} }
timeEl.addEventListener( 'click', function() {
_resetTimer();
return false;
} );
function _displayTime( hrEl, minEl, secEl, time) { function _displayTime( hrEl, minEl, secEl, time) {
var sign = Math.sign(time) == -1 ? "-" : ""; var sign = Math.sign(time) == -1 ? "-" : "";
@ -618,52 +686,26 @@
function _updatePacing(diff) { function _updatePacing(diff) {
var slideEndTiming = getTimeAllocated(timings) * 1000; getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
var currentSlide = Reveal.getSlidePastCount(); var slideEndTiming = slideEndTimingSeconds * 1000;
var currentSlideTiming = timings[currentSlide] * 1000;
var timeLeftCurrentSlide = slideEndTiming - diff;
if (timeLeftCurrentSlide < 0) {
pacingEl.className = 'pacing behind';
}
else if (timeLeftCurrentSlide < currentSlideTiming) {
pacingEl.className = 'pacing on-track';
}
else {
pacingEl.className = 'pacing ahead';
}
_displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
var currentSlideTiming = timings[currentSlide] * 1000;
var timeLeftCurrentSlide = slideEndTiming - diff;
if (timeLeftCurrentSlide < 0) {
pacingEl.className = 'pacing behind';
}
else if (timeLeftCurrentSlide < currentSlideTiming) {
pacingEl.className = 'pacing on-track';
}
else {
pacingEl.className = 'pacing ahead';
}
_displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
} );
} );
} }
// Update once directly
_updateTimer();
// Then update every second
setInterval( _updateTimer, 1000 );
function _resetTimer() {
if (timings == null) {
start = new Date();
}
else {
// Reset timer to beginning of current slide
var slideEndTiming = getTimeAllocated(timings) * 1000;
var currentSlide = Reveal.getSlidePastCount();
var currentSlideTiming = timings[currentSlide] * 1000;
var previousSlidesTiming = slideEndTiming - currentSlideTiming;
var now = new Date();
start = new Date(now.getTime() - previousSlidesTiming);
}
_updateTimer();
}
timeEl.addEventListener( 'click', function() {
_resetTimer();
return false;
} );
} }
/** /**

View File

@ -11,24 +11,28 @@
*/ */
var RevealNotes = (function() { var RevealNotes = (function() {
var notesPopup = null;
function openNotes( notesFilePath ) { function openNotes( notesFilePath ) {
if (notesPopup && !notesPopup.closed) {
notesPopup.focus();
return;
}
if( !notesFilePath ) { if( !notesFilePath ) {
var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path
jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path
notesFilePath = jsFileLocation + 'notes.html'; notesFilePath = jsFileLocation + 'notes.html';
} }
var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' ); notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );
if( !notesPopup ) { if( !notesPopup ) {
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' ); alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
return; return;
} }
// Allow popup window access to Reveal API
notesPopup.Reveal = window.Reveal;
/** /**
* Connect to the notes window through a postmessage handshake. * Connect to the notes window through a postmessage handshake.
* Using postmessage enables us to work in situations where the * Using postmessage enables us to work in situations where the
@ -52,9 +56,28 @@ var RevealNotes = (function() {
clearInterval( connectInterval ); clearInterval( connectInterval );
onConnected(); onConnected();
} }
if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
callRevealApi( data.methodName, data.arguments, data.callId );
}
} ); } );
} }
/**
* Calls the specified Reveal.js method with the provided argument
* and then pushes the result to the notes frame.
*/
function callRevealApi( methodName, methodArguments, callId ) {
var result = Reveal[methodName].apply( Reveal, methodArguments );
notesPopup.postMessage( JSON.stringify( {
namespace: 'reveal-notes',
type: 'return',
result: result,
callId: callId
} ), '*' );
}
/** /**
* Posts the current slide data to the notes window * Posts the current slide data to the notes window
*/ */
@ -128,20 +151,28 @@ var RevealNotes = (function() {
} }
if( !/receiver/i.test( window.location.search ) ) { return {
init: function() {
// If the there's a 'notes' query set, open directly if( !/receiver/i.test( window.location.search ) ) {
if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
openNotes();
}
// Open the notes when the 's' key is hit // If the there's a 'notes' query set, open directly
Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() { if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
openNotes(); openNotes();
} ); }
} // Open the notes when the 's' key is hit
Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
openNotes();
} );
return { open: openNotes }; }
},
open: openNotes
};
})(); })();
Reveal.registerPlugin( 'notes', RevealNotes );

View File

@ -200,7 +200,7 @@ function Hilitor(id, tag)
toggleSearch(); toggleSearch();
} }
}, false ); }, false );
if( window.Reveal ) Reveal.registerKeyboardShortcut( 'Ctrl-Shift-F', 'Search' ); if( window.Reveal ) Reveal.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
closeSearch(); closeSearch();
return { open: openSearch }; return { open: openSearch };
})(); })();

View File

@ -1,29 +1,34 @@
// Custom reveal.js integration // Custom reveal.js integration
(function(){ var RevealZoom = (function(){
var revealElement = document.querySelector( '.reveal' );
if( revealElement ) {
revealElement.addEventListener( 'mousedown', function( event ) { return {
var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt'; init: function() {
var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : defaultModifier ) + 'Key'; Reveal.getRevealElement().addEventListener( 'mousedown', function( event ) {
var zoomLevel = ( Reveal.getConfig().zoomLevel ? Reveal.getConfig().zoomLevel : 2 ); var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt';
if( event[ modifier ] && !Reveal.isOverview() ) { var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : defaultModifier ) + 'Key';
event.preventDefault(); var zoomLevel = ( Reveal.getConfig().zoomLevel ? Reveal.getConfig().zoomLevel : 2 );
zoom.to({ if( event[ modifier ] && !Reveal.isOverview() ) {
x: event.clientX, event.preventDefault();
y: event.clientY,
scale: zoomLevel,
pan: false
});
}
} );
zoom.to({
x: event.clientX,
y: event.clientY,
scale: zoomLevel,
pan: false
});
}
} );
}
} }
})(); })();
Reveal.registerPlugin( 'zoom', RevealZoom );
/*! /*!
* 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

View File

@ -0,0 +1 @@
window.externalScriptSequence += 'A';

View File

@ -0,0 +1 @@
window.externalScriptSequence += 'B';

View File

@ -0,0 +1 @@
window.externalScriptSequence += 'C';

View File

@ -0,0 +1 @@
window.externalScriptSequence += 'D';

View File

@ -0,0 +1,2 @@
Source: https://freesound.org/people/fennelliott/sounds/379419/
License: CC0 (public domain)

Binary file not shown.

View File

@ -30,11 +30,15 @@
<h2>Empty Slide</h2> <h2>Empty Slide</h2>
</section> </section>
<section>
<h2>Auto-playing audio</h2>
<audio src="assets/beeping.wav" data-autoplay></audio>
</section>
</div> </div>
</div> </div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.js"></script> <script src="../../js/reveal.js"></script>
<script> <script>

View File

@ -82,6 +82,14 @@
\] \]
</section> </section>
<section>
<h3>TeX Macros</h3>
Here is a common vector space:
\[L^2(\R) = \set{u : \R \to \R}{\int_\R |u|^2 &lt; +\infty}\]
used in functional analysis.
</section>
<section> <section>
<section> <section>
<h3>The Lorenz Equations</h3> <h3>The Lorenz Equations</h3>
@ -153,13 +161,20 @@
\] \]
</div> </div>
</section> </section>
<section>
<h3>TeX Macros</h3>
Here is a common vector space:
\[L^2(\R) = \set{u : \R \to \R}{\int_\R |u|^2 &lt; +\infty}\]
used in functional analysis.
</section>
</section> </section>
</div> </div>
</div> </div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.js"></script> <script src="../../js/reveal.js"></script>
<script> <script>
@ -170,11 +185,16 @@
math: { math: {
// mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js', // mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
config: 'TeX-AMS_HTML-full' config: 'TeX-AMS_HTML-full',
TeX: {
Macros: {
R: '\\mathbb{R}',
set: [ '\\left\\{#1 \\; ; \\; #2\\right\\}', 2 ]
}
}
}, },
dependencies: [ dependencies: [
{ src: '../../lib/js/classList.js' },
{ src: '../../plugin/math/math.js', async: true } { src: '../../plugin/math/math.js', async: true }
] ]
}); });

View File

@ -122,7 +122,6 @@
</div> </div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.js"></script> <script src="../../js/reveal.js"></script>
<script> <script>

View File

@ -81,7 +81,6 @@
</div> </div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.js"></script> <script src="../../js/reveal.js"></script>
<script> <script>

View File

@ -0,0 +1,78 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Test Async Dependencies</title>
<link rel="stylesheet" href="../css/reveal.css">
<link rel="stylesheet" href="qunit-2.5.0.css">
</head>
<body style="overflow: auto;">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div class="reveal" style="display: none;">
<div class="slides">
<section>Slide content</section>
</div>
</div>
<script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script>
<script>
var externalScriptSequence = '';
var scriptCount = 0;
QUnit.config.autostart = false;
QUnit.module( 'Async Dependencies' );
QUnit.test( 'Async scripts are loaded', function( assert ) {
assert.expect( 5 );
var done = assert.async( 5 );
function callback( event ) {
if( externalScriptSequence.length === 1 ) {
assert.ok( externalScriptSequence === 'A', 'first callback was sync script' );
done();
}
else {
assert.ok( true, 'async script loaded' );
done();
}
if( externalScriptSequence.length === 4 ) {
assert.ok( externalScriptSequence.indexOf( 'A' ) !== -1 &&
externalScriptSequence.indexOf( 'B' ) !== -1 &&
externalScriptSequence.indexOf( 'C' ) !== -1 &&
externalScriptSequence.indexOf( 'D' ) !== -1, 'four unique scripts were loaded' );
done();
}
scriptCount ++;
}
Reveal.initialize({
dependencies: [
{ src: 'assets/external-script-a.js', async: false, callback: callback },
{ src: 'assets/external-script-b.js', async: true, callback: callback },
{ src: 'assets/external-script-c.js', async: true, callback: callback },
{ src: 'assets/external-script-d.js', async: true, callback: callback }
]
});
});
QUnit.start();
</script>
</body>
</html>

View File

@ -0,0 +1,54 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Test Dependencies</title>
<link rel="stylesheet" href="../css/reveal.css">
<link rel="stylesheet" href="qunit-2.5.0.css">
</head>
<body style="overflow: auto;">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div class="reveal" style="display: none;">
<div class="slides">
<section>Slide content</section>
</div>
</div>
<script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script>
<script>
window.externalScriptSequence = '';
Reveal.addEventListener( 'ready', function() {
QUnit.module( 'Dependencies' );
QUnit.test( 'Load synchronous scripts', function( assert ) {
assert.strictEqual( window.externalScriptSequence, 'ABC', 'Loaded and executed in order' );
});
} );
Reveal.initialize({
dependencies: [
{ src: 'assets/external-script-a.js' },
{ src: 'assets/external-script-b.js' },
{ src: 'assets/external-script-c.js' }
]
});
</script>
</body>
</html>

View File

@ -0,0 +1,74 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Test Grid</title>
<link rel="stylesheet" href="../css/reveal.css">
<link rel="stylesheet" href="qunit-2.5.0.css">
</head>
<body style="overflow: auto;">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div class="reveal" style="display: none;">
<div class="slides">
<section>0</section>
<section>
<section>1.1</section>
<section>1.2</section>
<section>1.3</section>
<section>1.4</section>
</section>
<section>
<section>2.1</section>
<section>2.2</section>
<section>2.3</section>
<section>2.4</section>
</section>
</div>
</div>
<script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script>
<script>
Reveal.addEventListener( 'ready', function() {
QUnit.module( 'Grid Navigation' );
QUnit.test( 'Disabled', function( assert ) {
Reveal.right();
Reveal.down();
Reveal.down();
assert.deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined }, 'Correct starting point' );
Reveal.right();
assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: undefined }, 'Moves to top when going to adjacent stack' );
});
QUnit.test( 'Enabled', function( assert ) {
Reveal.configure({ navigationMode: 'grid' });
Reveal.slide( 0, 0 );
Reveal.right();
Reveal.down();
Reveal.down();
assert.deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined }, 'Correct starting point' );
Reveal.right();
assert.deepEqual( Reveal.getIndices(), { h: 2, v: 2, f: undefined }, 'Remains at same vertical index when going to adjacent stack' );
});
} );
Reveal.initialize();
</script>
</body>
</html>

View File

@ -66,8 +66,7 @@
Test Test
![Example Picture](examples/assets/image2.png) ![Example Picture](examples/assets/image2.png) <!-- {_class="reveal stretch"} -->
<!-- {_class="reveal stretch"} -->
</script> </script>
</section> </section>
@ -122,7 +121,6 @@
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="../plugin/markdown/marked.js"></script> <script src="../plugin/markdown/marked.js"></script>
<script src="../plugin/markdown/markdown.js"></script> <script src="../plugin/markdown/markdown.js"></script>

View File

@ -13,24 +13,25 @@
<body style="overflow: auto;"> <body style="overflow: auto;">
<div id="qunit"></div> <div id="qunit"></div>
<div id="qunit-fixture"></div> <div id="qunit-fixture"></div>
<div class="reveal" style="display: none;"> <div class="reveal" style="display: none;">
<div class="slides"> <div class="slides">
<section data-markdown="simple.md" data-separator="^\r?\n\r?\n\r?\n" data-separator-vertical="^\r?\n\r?\n"></section> <!-- <section data-markdown="simple.md" data-separator="^\r?\n\r?\n\r?\n" data-separator-vertical="^\r?\n\r?\n"></section> -->
</div> </div>
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="../plugin/highlight/highlight.js"></script> <script src="../plugin/highlight/highlight.js"></script>
<script src="../plugin/markdown/marked.js"></script> <script src="../plugin/markdown/marked.js"></script>
<script src="../plugin/markdown/markdown.js"></script> <script src="../plugin/markdown/markdown.js"></script>
<script src="qunit-2.5.0.js"></script> <script src="qunit-2.5.0.js"></script>
<script src="test-markdown-external.js"></script> <!-- <script src="test-markdown-external.js"></script> -->
<!-- Test disabled 28/2/2019 by Hakim Markdown plugin needs to be updated to load extenal files asycnhronously -->
</body> </body>
</html> </html>

View File

@ -31,7 +31,6 @@
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script> <script src="qunit-2.5.0.js"></script>

View File

@ -116,7 +116,6 @@
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="../plugin/markdown/marked.js"></script> <script src="../plugin/markdown/marked.js"></script>
<script src="../plugin/markdown/markdown.js"></script> <script src="../plugin/markdown/markdown.js"></script>

View File

@ -40,7 +40,6 @@
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="../plugin/markdown/marked.js"></script> <script src="../plugin/markdown/marked.js"></script>
<script src="../plugin/markdown/markdown.js"></script> <script src="../plugin/markdown/markdown.js"></script>

View File

@ -22,7 +22,7 @@
<section> <section>
<h1>1</h1> <h1>1</h1>
<img data-src="fake-url.png"> <img data-src="">
</section> </section>
<section> <section>
@ -73,7 +73,6 @@
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script> <script src="qunit-2.5.0.js"></script>

92
test/test-plugins.html Normal file
View File

@ -0,0 +1,92 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Test Plugins</title>
<link rel="stylesheet" href="../css/reveal.css">
<link rel="stylesheet" href="qunit-2.5.0.css">
</head>
<body style="overflow: auto;">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div class="reveal" style="display: none;">
<div class="slides">
<section>Slide content</section>
</div>
</div>
<script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script>
<script>
QUnit.module( 'Plugins' );
var initCounter = { PluginB: 0, PluginC: 0, PluginD: 0 };
// Plugin with no init method
var PluginA = {};
// Plugin with init method
var PluginB = { init: function() {
initCounter['PluginB'] += 1;
} };
// Async plugin with init method
var PluginC = { init: function() {
return new Promise(function( resolve ) {
setTimeout( () => {
initCounter['PluginC'] += 1;
resolve();
}, 1000 );
});
} };
// Plugin initialized after reveal.js is ready
var PluginD = { init: function() {
initCounter['PluginD'] += 1;
} };
Reveal.registerPlugin( 'PluginA', PluginA );
Reveal.registerPlugin( 'PluginB', PluginB );
Reveal.registerPlugin( 'PluginC', PluginC );
Reveal.initialize();
QUnit.test( 'Can initialize synchronously', function( assert ) {
assert.strictEqual( initCounter['PluginB'], 1 );
Reveal.registerPlugin( 'PluginB', PluginB );
assert.strictEqual( initCounter['PluginB'], 1, 'prevents duplicate registration' );
});
QUnit.test( 'Can initialie asynchronously', function( assert ) {
assert.expect( 3 );
var done = assert.async( 2 );
assert.strictEqual( initCounter['PluginC'], 0, 'async plugin not immediately initialized' );
Reveal.addEventListener( 'ready', function() {
assert.strictEqual( initCounter['PluginC'], 1, 'finsihed initializing when reveal.js dispatches "ready"' );
done();
Reveal.registerPlugin( 'PluginD', PluginD );
assert.strictEqual( initCounter['PluginD'], 1, 'plugin registered after reveal.js is ready still initiailizes' );
done();
});
} );
</script>
</body>
</html>

139
test/test-state.html Normal file
View File

@ -0,0 +1,139 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Test State</title>
<link rel="stylesheet" href="../css/reveal.css">
<link rel="stylesheet" href="qunit-2.5.0.css">
</head>
<body style="overflow: auto;">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div class="reveal" style="display: none;">
<div class="slides">
<section>No state</section>
<section id="slide2" data-state="state1">State 1</section>
<section data-state="state1">State 1</section>
<section data-state="state2">State 2</section>
<section>
<section>No state</section>
<section data-state="state1">State 1</section>
<section data-state="state3">State 3</section>
<section>No state</section>
</section>
<section>No state</section>
</div>
</div>
<script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script>
<script>
Reveal.addEventListener( 'ready', function() {
QUnit.module( 'State' );
QUnit.test( 'Fire events when changing slide', function( assert ) {
assert.expect( 2 );
var state1 = assert.async();
var state2 = assert.async();
var _onState1 = function( event ) {
assert.ok( true, 'state1 fired' );
state1();
}
var _onState2 = function( event ) {
assert.ok( true, 'state2 fired' );
state2();
}
Reveal.addEventListener( 'state1', _onState1 );
Reveal.addEventListener( 'state2', _onState2 );
Reveal.slide( 1 );
Reveal.slide( 3 );
Reveal.removeEventListener( 'state1', _onState1 );
Reveal.removeEventListener( 'state2', _onState2 );
});
QUnit.test( 'Fire state events for vertical slides', function( assert ) {
assert.expect( 2 );
var done = assert.async( 2 );
var _onState1 = function( event ) {
assert.ok( true, 'state1 fired' );
done();
}
var _onState3 = function( event ) {
assert.ok( true, 'state3 fired' );
done();
}
Reveal.addEventListener( 'state1', _onState1 );
Reveal.addEventListener( 'state3', _onState3 );
Reveal.slide( 0 );
Reveal.slide( 4, 1 );
Reveal.slide( 4, 2 );
Reveal.removeEventListener( 'state1', _onState1 );
Reveal.removeEventListener( 'state3', _onState3 );
});
QUnit.test( 'No events if state remains unchanged', function( assert ) {
var stateChanges = 0;
var _onEvent = function( event ) {
stateChanges += 1;
}
Reveal.addEventListener( 'state1', _onEvent );
Reveal.slide( 0 ); // no state
Reveal.slide( 1 ); // state1
Reveal.slide( 2 ); // state1
Reveal.prev(); // state1
Reveal.next(); // state1
Reveal.slide( 4, 1 ); // state1
Reveal.slide( 0 ); // no state
Reveal.removeEventListener( 'state1', _onEvent );
assert.strictEqual( stateChanges, 1, 'no event was fired when going to slide with same state' );
});
QUnit.test( 'Event order', function( assert ) {
var _onEvent = function( event ) {
assert.ok( Reveal.getCurrentSlide() == document.querySelector( '#slide2' ), 'correct current slide immediately after state event' );
}
Reveal.addEventListener( 'state1', _onEvent );
Reveal.slide( 0 );
Reveal.slide( 1 );
Reveal.removeEventListener( 'state1', _onEvent );
});
} );
Reveal.initialize();
</script>
</body>
</html>

View File

@ -21,9 +21,9 @@
<section data-background-image="examples/assets/image1.png"> <section data-background-image="examples/assets/image1.png">
<h1>1</h1> <h1>1</h1>
<img data-src="fake-url.png"> <img data-src="">
<video data-src="fake-url.mp4"></video> <video data-src=""></video>
<audio data-src="fake-url.mp3"></audio> <audio data-src=""></audio>
<aside class="notes">speaker notes 1</aside> <aside class="notes">speaker notes 1</aside>
</section> </section>
@ -76,7 +76,6 @@
</div> </div>
<script src="../lib/js/head.min.js"></script>
<script src="../js/reveal.js"></script> <script src="../js/reveal.js"></script>
<script src="qunit-2.5.0.js"></script> <script src="qunit-2.5.0.js"></script>

View File

@ -262,6 +262,7 @@ Reveal.addEventListener( 'ready', function() {
QUnit.test( 'Current fragment', function( assert ) { QUnit.test( 'Current fragment', function( assert ) {
var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' ); var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
var lastFragmentIndex = [].slice.call( fragmentSlide.querySelectorAll( '.fragment' ) ).pop().getAttribute( 'data-fragment-index' );
Reveal.slide( 2, 0 ); Reveal.slide( 2, 0 );
assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' ); assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
@ -274,6 +275,10 @@ Reveal.addEventListener( 'ready', function() {
Reveal.slide( 3, 0, 0 ); Reveal.slide( 3, 0, 0 );
assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' ); assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
Reveal.slide( 2, 1, -1 );
Reveal.prev();
assert.strictEqual( fragmentSlide.querySelector( '.fragment.current-fragment' ).getAttribute( 'data-fragment-index' ), lastFragmentIndex, 'last fragment is current fragment when returning from future slide' );
}); });
QUnit.test( 'Stepping through fragments', function( assert ) { QUnit.test( 'Stepping through fragments', function( assert ) {