1
0
mirror of https://github.com/hakimel/reveal.js.git synced 2025-09-15 00:52:11 +02:00

Compare commits

..

73 Commits
0.3.0 ... 1.2.0

Author SHA1 Message Date
Hakim El Hattab
f59e64a571 better example of state usage 2012-04-04 00:59:35 -04:00
Hakim El Hattab
d3e2a95d77 new example 2012-04-02 17:57:14 -03:00
Hakim El Hattab
0d9a6419bb change back state event scope, document level makes more sense as that's where the state class is applied 2012-03-30 23:59:19 -04:00
Hakim El Hattab
8dc7ae85a1 adjustments to custom state events 2012-03-30 23:51:37 -04:00
Andy Matthews
2c78eea0ca Firing custom event based on data-state name. This allows developers to trigger custom javascript code on a per slide basis. 2012-03-30 06:51:54 -05:00
Hakim El Hattab
831236890c now capturing data-state on slides and lifting it to document element classList when slide is open 2012-03-30 00:13:45 -04:00
Hakim El Hattab
0cd3b8d430 merge prev/next navigation pull request with modifications 2012-03-28 01:16:16 -04:00
Catalin Buzoiu
732ed921eb Implemented correct Previous and Next navigation for both mouse scroll and wireless presenter. 2012-03-27 18:45:04 +03:00
Hakim El Hattab
be76bf3d23 classList polyfill included for ie9 2012-03-24 12:48:16 -04:00
Hakim El Hattab
87529c4adc delay hash changes to avoid transition lag in chrome and enable history by default (closes #22) 2012-03-24 12:36:34 -04:00
Hakim El Hattab
b72bee3219 don't overwrite existing classes on slides (closes #23) 2012-03-24 12:27:25 -04:00
Hakim El Hattab
cd66a6574d Merge pull request #21 from archive/master
Added support for wireless presenter
2012-03-19 18:54:34 -07:00
Anders
b6030d5c7a added support for wireless presenter 2012-03-19 23:20:40 +01:00
Hakim El Hattab
a77842521e Merge pull request #20 from Fil/master
reveal.js was failing when the hash was of an unexpected format
2012-03-18 14:14:52 -07:00
Fil
81cda2145f Do not fail on other kinds of hashes 2012-03-15 18:00:26 +01:00
Hakim El Hattab
7f3bf1409e new example 2012-03-05 16:47:02 -05:00
Hakim El Hattab
67add62316 new examples 2012-03-02 02:05:06 -05:00
Hakim El Hattab
f27db1dc84 default hash updates to false, see http://code.google.com/p/chromium/issues/detail?id=62820 2012-02-29 19:24:57 -05:00
Hakim El Hattab
ba8fc0bc35 fix reference to old 'hasClass' method 2012-02-17 23:37:14 -05:00
Hakim El Hattab
a53b315e24 new example 2012-02-17 23:36:54 -05:00
Hakim El Hattab
38b229a22f tweaked mouse wheel navigation 2012-01-14 19:22:27 -08:00
Hakim El Hattab
17854e892b Merge pull request #13 from naugtur/master
Mouse scroll handling
2012-01-14 19:13:19 -08:00
Hakim El Hattab
896e0b7010 removed history comment in js 2012-01-14 18:41:55 -08:00
Hakim El Hattab
284610dab0 added usage instructions to readme 2012-01-14 18:20:52 -08:00
Hakim El Hattab
a30cdaaffc rolled back to classList, promoting poyfill in readme 2012-01-14 17:56:11 -08:00
Hakim El Hattab
9736509bae broaden selector for img:hover (fixes #11) 2012-01-14 17:36:07 -08:00
Hakim El Hattab
510ac8e114 don't apply linkify effect to anchors containing images 2012-01-14 17:31:41 -08:00
Hakim El Hattab
c3bc0f70ef add new example 2012-01-14 17:19:12 -08:00
Naugtur
2ae803efb6 Added support for smart scrolling through slides. Scrolling events are throttled to prevent going too far 2012-01-15 00:34:51 +01:00
Hakim El Hattab
401c554c80 removed dependency on classList (#9) 2012-01-03 22:25:15 -08:00
Hakim El Hattab
4d3c3c8d3f Merge branch 'master' of github.com:hakimel/reveal.js 2012-01-03 08:29:50 -08:00
Hakim El Hattab
36950c8149 moved inline base64 images to aws 2012-01-03 00:24:09 -08:00
Hakim El Hattab
614b8cde66 scrolling fallback mode for IE < 9 2012-01-03 00:11:05 -08:00
Hakim El Hattab
4805234a41 slightly reduced size of progress bar 2012-01-02 23:57:53 -08:00
Hakim El Hattab
02f783b68d prevent default on space press 2012-01-02 23:48:09 -08:00
Hakim El Hattab
e8507de1e4 Added example 2012-01-02 02:18:08 -08:00
Hakim El Hattab
cbd59efef8 history on by default 2011-12-30 22:35:42 -08:00
Hakim El Hattab
9856f57db5 browser history updates can now be disabled via config 2011-12-30 22:33:19 -08:00
Hakim El Hattab
73eb66bf71 Merge branch 'master' of github.com:hakimel/reveal.js 2011-12-26 21:57:51 -08:00
Hakim El Hattab
3fa01ab107 updated copy in slides, added one that explains transitions 2011-12-26 21:57:37 -08:00
Hakim El Hattab
f7ac5fb159 updated readme 2011-12-26 21:34:53 -08:00
Hakim El Hattab
2c088681ec adjusted background color of page/box themes 2011-12-26 21:31:02 -08:00
Hakim El Hattab
daecc258d7 major, non backwards compatible, restructuring of DOM tree 2011-12-26 21:29:00 -08:00
Hakim El Hattab
5b2b3fa3df changed id of 'main' container to 'reveal' 2011-12-26 19:32:00 -08:00
Hakim El Hattab
bccb6e68c7 packed v1.1, upgraded to 1.2 2011-12-26 17:13:46 -08:00
Hakim El Hattab
2313dfef6d readme history update 2011-12-26 00:04:11 -08:00
Hakim El Hattab
c7c7735e7a added new transitions (box/page) and a ui theme (neon) 2011-12-26 00:00:38 -08:00
Hakim El Hattab
1ac6386eef fix padding and duplicate background on vertical slides in overview 2011-12-23 21:52:35 -08:00
Hakim El Hattab
b162a54c2d fix clicks on vertical slides in overview 2011-12-23 21:33:28 -08:00
Hakim El Hattab
91ff92e211 skip fragments when in overview 2011-12-23 21:22:13 -08:00
Hakim El Hattab
c6a75117f6 added experimental overview mode (press SPACE) 2011-12-23 02:47:38 -08:00
Hakim El Hattab
adc9ad19ce fallback on 2d transform transitions via feature detect 2011-12-23 00:36:37 -08:00
Hakim El Hattab
f6dc531298 slides three or more steps away from current are now hidden 2011-12-22 22:41:19 -08:00
Hakim El Hattab
01000e1478 only apply background gradient to <html> 2011-12-22 22:01:10 -08:00
Hakim El Hattab
0c231fec38 added '-ms' prefixed properties 2011-12-22 21:30:10 -08:00
Hakim El Hattab
9065114ef0 progress bar is now a div and uses the same transition + easing as slides (fixes #6) 2011-12-22 21:25:15 -08:00
Hakim El Hattab
91c3056a62 Added examples 2011-12-22 20:36:42 -08:00
Hakim El Hattab
abbd027124 updated readme 2011-12-22 00:11:57 -08:00
Hakim El Hattab
4a4ffd518e hide progress by default 2011-12-22 00:03:52 -08:00
Hakim El Hattab
bdff009c74 added optional presentation progress bar 2011-12-22 00:00:29 -08:00
Hakim El Hattab
2026c9645c replaced google logo with a unicorn 2011-12-21 23:03:30 -08:00
Hakim El Hattab
833e298617 comments & typo correction 2011-12-21 20:22:49 -08:00
Hakim El Hattab
11ee006f9d slide with code is now editable, escaped unicode arrows 2011-12-21 20:21:52 -08:00
Hakim El Hattab
60bf197890 Merge pull request #5 from matthewlein/master
contenteditable and arrow keys
2011-12-21 18:19:36 -08:00
Matthew Lein
853efe5043 for contenteditable elements, don't let arrow keys work 2011-12-21 15:11:10 -05:00
Hakim El Hattab
59c9b3c596 fragments now work in vertical slides (fixes #4) 2011-12-17 12:55:25 -08:00
Hakim El Hattab
e6f444a307 disabled overflow on body (fixes #2) 2011-12-05 01:00:52 -08:00
Hakim El Hattab
d2faad4730 fix broken link 2011-12-04 20:53:35 -08:00
Hakim El Hattab
f9527d31b4 fix vertical slide transition and hit areas of rolling links 2011-12-04 19:24:08 -08:00
Hakim El Hattab
233160ff23 cleanup & comments 2011-12-04 18:55:48 -08:00
Hakim El Hattab
b36e8d5c4e readme update 2011-12-04 18:51:09 -08:00
Hakim El Hattab
9edb5f6da0 Updated readme 2011-12-04 18:21:15 -08:00
Hakim El Hattab
a6453a0fb0 renamed to reveal.js, many new features, and upgraded to v1.0 2011-12-04 18:07:33 -08:00
9 changed files with 2059 additions and 514 deletions

106
README.md
View File

@@ -1,8 +1,108 @@
# CSS 3D Slideshow
# reveal.js
Requires a browser with support for CSS 3D transforms, such as Chrome or Safari.
A CSS 3D slideshow tool for quickly creating good looking HTML presentations. Doesn't _rely_ on any external libraries but [highlight.js](http://softwaremaniacs.org/soft/highlight/en/description/) is included by default for code highlighting.
Curious about how this looks in action? [Check out the demo page.](http://hakim.se/experiments/css/slideshow/).
Note that this requires a browser with support for CSS 3D transforms and ``classList``. If CSS 3D support is not detected, the presentation will degrade to less exciting 2D transitions. You could also use a polyfill for ``classList`` to make this work in < iOS 5 and < Safari 5.1, [here's one](https://github.com/remy/polyfills/blob/master/classList.js) from [@remy](https://github.com/remy).
Curious about how this looks in action? [Check out the demo page](http://lab.hakim.se/reveal-js/).
# Examples
* http://lab.hakim.se/reveal-js/ (original)
* http://www.ideapolisagency.com/ by [@achrafkassioui](http://twitter.com/achrafkassioui)
* http://lucienfrelin.com/ by [@lucienfrelin](http://twitter.com/lucienfrelin)
* http://creatorrr.github.com/ThePoet/
* http://moduscreate.com/ by [@ModusCreate](https://twitter.com/ModusCreate)
* [Webapp Development Stack & Tooling](http://dl.dropbox.com/u/39519/talks/jquk-tooling%2Bappstack/index.html) by [@paul_irish](https://twitter.com/paul_irish)
* http://idea.diwank.name/ by [Diwank Singh](http://diwank.name/)
* http://concurrencykit.org/presentations/lockfree_introduction/ by Samy Al Bahra
* http://www.thecssninja.com/talks/not_your_average_dnd/ by [@ryanseddon](http://twitter.com/ryanseddon)
* http://spinscale.github.com/elasticsearch/2012-03-jugm.html by [@spinscale](http://twitter.com/spinscale)
* [JavaScript Tooling](http://dl.dropbox.com/u/39519/talks/jsconf-tools/index.html) by [@paul_irish](https://twitter.com/paul_irish)
[Send me a link](http://hakim.se/about/contact) if you used reveal.js for a project or presentation.
# Usage
Markup heirarchy needs to be ``<div id="reveal"> <div class="slides"> <section>`` where the ``<section>`` represents one slide and can be repeated indefinitely. If you place multiple ``<section>``'s inside of another ``<section>`` they will be shown as vertical slides.
At the end of your page, after ``<script src="js/reveal.js"></script>``, you need to initialize reveal. Note that all config values are optional.
```
Reveal.initialize({
// Display controls in the bottom right corner
controls: true,
// Display a presentation progress bar
progress: true,
// If true; each slide will be pushed to the browser history
history: true,
// Flags if mouse wheel navigation should be enabled
mouseWheel: true,
// Apply a 3D roll to links on hover
rollingLinks: true,
// UI style
theme: 'default', // default/neon
// Transition style
transition: 'default' // default/cube/page/concave/linear(2d)
});
```
# History
#### 1.2 (master)
- Big changes to DOM structure:
- Previous #main wrapper is now called #reveal
- Slides were moved one level deeper, into #reveal .slides
- Controls and progress bar were moved into #reveal
- CSS is now much more explicit, rooted at #reveal, to prevent conflicts
- Config option for disabling updates to URL, defaults to true
- Anchors with image children no longer rotate in 3D on hover
- Support for mouse wheel navigation ([naugtur](https://github.com/naugtur))
- Delayed updates to URL hash to work around a bug in Chrome
- Included a classList polyfill for IE9
- Support for wireless presenter keys
- States can now be applied as classes on the document element by adding data-state on a slide
#### 1.1
- Added an optional presentation progress bar
- Images wrapped in anchors no longer unexpectedly flip in 3D
- Slides that contain other slides are given the 'stack' class
- Added 'transition' option for specifying transition styles
- Added 'theme' option for specifying UI styles
- New transitions: 'box' & 'page'
- New theme: 'neon'
#### 1.0
- New and improved style
- Added controls in bottom right which indicate where you can navigate
- Reveal views in iteratively by giving them the .fragment class
- Code sample syntax highlighting thanks to [highlight.js](http://softwaremaniacs.org/soft/highlight/en/description/)
- Initialization options (toggling controls, toggling rolling links, transition theme)
#### 0.3
- Added licensing terms
- Fixed broken links on touch devices
#### 0.2
- Refactored code and added inline documentation
- Slides now have unique URL's
- A basic API to invoke navigation was added
#### 0.1
- First release
- Transitions and a white theme
# License

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

750
js/reveal.js Normal file
View File

@@ -0,0 +1,750 @@
/**
* Copyright (C) 2011 Hakim El Hattab, http://hakim.se
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* #############################################################################
*
* Reveal.js is an easy to use HTML based slideshow enhanced by
* sexy CSS 3D transforms.
*
* Slides are given unique hash based URL's so that they can be
* opened directly.
*
* Public facing methods:
* - Reveal.initialize( { ... options ... } );
* - Reveal.navigateTo( indexh, indexv );
* - Reveal.navigateLeft();
* - Reveal.navigateRight();
* - Reveal.navigateUp();
* - Reveal.navigateDown();
*
* @author Hakim El Hattab | http://hakim.se
* @version 1.2
*/
var Reveal = (function(){
var HORIZONTAL_SLIDES_SELECTOR = '#reveal .slides>section',
VERTICAL_SLIDES_SELECTOR = '#reveal .slides>section.present>section',
// The horizontal and verical index of the currently active slide
indexh = 0,
indexv = 0,
// Configurations options, can be overridden at initialization time
config = {
controls: false,
progress: false,
history: false,
transition: 'default',
theme: 'default',
mouseWheel: true,
rollingLinks: true
},
// Slides may hold a data-state attribute which we pick up and apply
// as a class to the body. This list contains the combined state of
// all current slides.
state = [],
// Cached references to DOM elements
dom = {},
// Detect support for CSS 3D transforms
supports3DTransforms = document.body.style['perspectiveProperty'] !== undefined ||
document.body.style['WebkitPerspective'] !== undefined ||
document.body.style['MozPerspective'] !== undefined ||
document.body.style['msPerspective'] !== undefined,
supports2DTransforms = document.body.style['transformProperty'] !== undefined ||
document.body.style['WebkitTransform'] !== undefined ||
document.body.style['MozTransform'] !== undefined ||
document.body.style['msTransform'] !== undefined ||
document.body.style['OTransform'] !== undefined,
// Throttles mouse wheel navigation
mouseWheelTimeout = 0,
// Delays updates to the URL due to a Chrome thumbnailer bug
writeURLTimeout = 0;
/**
* Starts up the slideshow by applying configuration
* options and binding various events.
*/
function initialize( options ) {
if( !supports2DTransforms && !supports3DTransforms ) {
document.body.setAttribute( 'class', 'no-transforms' );
// If the browser doesn't support transforms we won't be
// using JavaScript to control the presentation
return;
}
// Cache references to DOM elements
dom.wrapper = document.querySelector( '#reveal' );
dom.progress = document.querySelector( '#reveal .progress' );
dom.progressbar = document.querySelector( '#reveal .progress span' );
dom.controls = document.querySelector( '#reveal .controls' );
dom.controlsLeft = document.querySelector( '#reveal .controls .left' );
dom.controlsRight = document.querySelector( '#reveal .controls .right' );
dom.controlsUp = document.querySelector( '#reveal .controls .up' );
dom.controlsDown = document.querySelector( '#reveal .controls .down' );
// Bind all view events
document.addEventListener('keydown', onDocumentKeyDown, false);
document.addEventListener('touchstart', onDocumentTouchStart, false);
window.addEventListener('hashchange', onWindowHashChange, false);
dom.controlsLeft.addEventListener('click', preventAndForward( navigateLeft ), false);
dom.controlsRight.addEventListener('click', preventAndForward( navigateRight ), false);
dom.controlsUp.addEventListener('click', preventAndForward( navigateUp ), false);
dom.controlsDown.addEventListener('click', preventAndForward( navigateDown ), false);
// Copy options over to our config object
extend( config, options );
// Fall back on the 2D transform theme 'linear'
if( supports3DTransforms === false ) {
config.transition = 'linear';
}
if( config.controls ) {
dom.controls.style.display = 'block';
}
if( config.progress ) {
dom.progress.style.display = 'block';
}
if( config.transition !== 'default' ) {
dom.wrapper.classList.add( config.transition );
}
if( config.theme !== 'default' ) {
dom.wrapper.classList.add( config.theme );
}
if( config.mouseWheel ) {
document.addEventListener('DOMMouseScroll', onDocumentMouseScroll, false); // FF
document.addEventListener('mousewheel', onDocumentMouseScroll, false);
}
if( config.rollingLinks ) {
// Add some 3D magic to our anchors
linkify();
}
// Read the initial hash
readURL();
}
/**
* Extend object a with the properties of object b.
* If there's a conflict, object b takes precedence.
*/
function extend( a, b ) {
for( var i in b ) {
a[ i ] = b[ i ];
}
}
/**
* Prevents an events defaults behavior calls the
* specified delegate.
*
* @param {Function} delegate The method to call
* after the wrapper has been executed
*/
function preventAndForward( delegate ) {
return function( event ) {
event.preventDefault();
delegate.call();
}
}
/**
* Handler for the document level 'keydown' event.
*
* @param {Object} event
*/
function onDocumentKeyDown( event ) {
// FFT: Use document.querySelector( ':focus' ) === null
// instead of checking contentEditable?
if( event.target.contentEditable === 'inherit' ) {
if( event.keyCode >= 33 && event.keyCode <= 40 ) {
switch( event.keyCode ) {
case 33: navigatePrev(); break; // prev for wireless presenter (PgUp)
case 34: navigateNext(); break; // next for wireless presenter (PgDn)
case 37: navigateLeft(); break; // left
case 39: navigateRight(); break; // right
case 38: navigateUp(); break; // up
case 40: navigateDown(); break; // down
}
event.preventDefault();
}
// Space bar
else if ( event.keyCode === 32 && supports3DTransforms ) {
if( overviewIsActive() ) {
deactivateOverview();
}
else {
activateOverview();
}
event.preventDefault();
}
}
}
/**
* Handler for the document level 'touchstart' event.
*
* This enables very basic tap interaction for touch
* devices. Added mainly for performance testing of 3D
* transforms on iOS but was so happily surprised with
* how smoothly it runs so I left it in here. Apple +1
*
* @param {Object} event
*/
function onDocumentTouchStart( event ) {
// We're only interested in one point taps
if (event.touches.length === 1) {
// Never prevent taps on anchors and images
if( event.target.tagName.toLowerCase() === 'a' || event.target.tagName.toLowerCase() === 'img' ) {
return;
}
event.preventDefault();
var point = {
x: event.touches[0].clientX,
y: event.touches[0].clientY
};
// Define the extent of the areas that may be tapped
// to navigate
var wt = window.innerWidth * 0.3;
var ht = window.innerHeight * 0.3;
if( point.x < wt ) {
navigateLeft();
}
else if( point.x > window.innerWidth - wt ) {
navigateRight();
}
else if( point.y < ht ) {
navigateUp();
}
else if( point.y > window.innerHeight - ht ) {
navigateDown();
}
slide();
}
}
/**
* Handles mouse wheel scrolling, throttled to avoid
* skipping multiple slides.
*/
function onDocumentMouseScroll( event ){
clearTimeout( mouseWheelTimeout );
mouseWheelTimeout = setTimeout( function() {
var delta = event.detail || -event.wheelDelta;
if( delta > 0 ) {
navigateNext();
}
else {
navigatePrev();
}
}, 100 );
}
/**
* Handler for the window level 'hashchange' event.
*
* @param {Object} event
*/
function onWindowHashChange( event ) {
readURL();
}
/**
* Wrap all links in 3D goodness.
*/
function linkify() {
if( supports3DTransforms ) {
var nodes = document.querySelectorAll( '#reveal .slides section a:not(.image)' );
for( var i = 0, len = nodes.length; i < len; i++ ) {
var node = nodes[i];
if( node.textContent && !node.querySelector( 'img' ) && ( !node.className || !node.classList.contains( node, 'roll' ) ) ) {
node.classList.add( 'roll' );
node.innerHTML = '<span data-title="'+ node.text +'">' + node.innerHTML + '</span>';
}
};
}
}
/**
* Displays the overview of slides (quick nav) by
* scaling down and arranging all slide elements.
*
* Experimental feature, might be dropped if perf
* can't be improved.
*/
function activateOverview() {
dom.wrapper.classList.add( 'overview' );
var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
var hslide = horizontalSlides[i],
htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * 105 ) + '%, 0%)';
hslide.setAttribute( 'data-index-h', i );
hslide.style.display = 'block';
hslide.style.WebkitTransform = htransform;
hslide.style.MozTransform = htransform;
hslide.style.msTransform = htransform;
hslide.style.OTransform = htransform;
hslide.style.transform = htransform;
if( !hslide.classList.contains( 'stack' ) ) {
// Navigate to this slide on click
hslide.addEventListener( 'click', onOverviewSlideClicked, true );
}
var verticalSlides = Array.prototype.slice.call( hslide.querySelectorAll( 'section' ) );
for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
var vslide = verticalSlides[j],
vtransform = 'translate(0%, ' + ( ( j - indexv ) * 105 ) + '%)';
vslide.setAttribute( 'data-index-h', i );
vslide.setAttribute( 'data-index-v', j );
vslide.style.display = 'block';
vslide.style.WebkitTransform = vtransform;
vslide.style.MozTransform = vtransform;
vslide.style.msTransform = vtransform;
vslide.style.OTransform = vtransform;
vslide.style.transform = vtransform;
// Navigate to this slide on click
vslide.addEventListener( 'click', onOverviewSlideClicked, true );
}
}
}
/**
* Exits the slide overview and enters the currently
* active slide.
*/
function deactivateOverview() {
dom.wrapper.classList.remove( 'overview' );
var slides = Array.prototype.slice.call( document.querySelectorAll( '#reveal .slides section' ) );
for( var i = 0, len = slides.length; i < len; i++ ) {
var element = slides[i];
// Resets all transforms to use the external styles
element.style.WebkitTransform = '';
element.style.MozTransform = '';
element.style.msTransform = '';
element.style.OTransform = '';
element.style.transform = '';
element.removeEventListener( 'click', onOverviewSlideClicked );
}
slide();
}
/**
* Checks if the overview is currently active.
*
* @return {Boolean} true if the overview is active,
* false otherwise
*/
function overviewIsActive() {
return dom.wrapper.classList.contains( 'overview' );
}
/**
* Invoked when a slide is and we're in the overview.
*/
function onOverviewSlideClicked( event ) {
// TODO There's a bug here where the event listeners are not
// removed after deactivating the overview.
if( overviewIsActive() ) {
event.preventDefault();
deactivateOverview();
indexh = this.getAttribute( 'data-index-h' );
indexv = this.getAttribute( 'data-index-v' );
slide();
}
}
/**
* Updates one dimension of slides by showing the slide
* with the specified index.
*
* @param {String} selector A CSS selector that will fetch
* the group of slides we are working with
* @param {Number} index The index of the slide that should be
* shown
*
* @return {Number} The index of the slide that is now shown,
* might differ from the passed in index if it was out of
* bounds.
*/
function updateSlides( selector, index ) {
// Select all slides and convert the NodeList result to
// an array
var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) );
if( slides.length ) {
// Enforce max and minimum index bounds
index = Math.max(Math.min(index, slides.length - 1), 0);
for( var i = 0; i < slides.length; i++ ) {
var slide = slides[i];
// Optimization; hide all slides that are three or more steps
// away from the present slide
if( overviewIsActive() === false ) {
slide.style.display = Math.abs( index - i ) > 3 ? 'none' : 'block';
}
slides[i].classList.remove( 'past' );
slides[i].classList.remove( 'present' );
slides[i].classList.remove( 'future' );
if( i < index ) {
// Any element previous to index is given the 'past' class
slides[i].classList.add( 'past' );
}
else if( i > index ) {
// Any element subsequent to index is given the 'future' class
slides[i].classList.add( 'future' );
}
// If this element contains vertical slides
if( slide.querySelector( 'section' ) ) {
slides[i].classList.add( 'stack' );
}
}
// Mark the current slide as present
slides[index].classList.add( 'present' );
// If this slide has a state associated with it, add it
// onto the current state of the deck
var slideState = slides[index].dataset.state;
if( slideState ) {
state = state.concat( slideState.split( ' ' ) );
}
}
else {
// Since there are no slides we can't be anywhere beyond the
// zeroth index
index = 0;
}
return index;
}
/**
* Updates the visual slides to represent the currently
* set indices.
*/
function slide() {
// Remember the state before this slide
var stateBefore = state.concat();
// Reset the state array
state.length = 0;
// Activate and transition to the new slide
indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, indexh );
indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, indexv );
// Apply the new state
stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
// Check if this state existed on the previous slide. If it
// did, we will avoid adding it repeatedly.
for( var j = 0; j < stateBefore.length; j++ ) {
if( stateBefore[j] === state[i] ) {
stateBefore.splice( j, 1 );
continue stateLoop;
}
}
document.documentElement.classList.add( state[i] );
// Dispatch custom event
var event = document.createEvent( "HTMLEvents" );
event.initEvent( state[i], true, true );
document.dispatchEvent( event );
}
// Clean up the remaints of the previous state
while( stateBefore.length ) {
document.documentElement.classList.remove( stateBefore.pop() );
}
// Update progress if enabled
if( config.progress ) {
dom.progressbar.style.width = ( indexh / ( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length - 1 ) ) * window.innerWidth + 'px';
}
// Close the overview if it's active
if( overviewIsActive() ) {
activateOverview();
}
updateControls();
clearTimeout( writeURLTimeout );
writeURLTimeout = setTimeout( writeURL, 1500 );
}
/**
* Updates the state and link pointers of the controls.
*/
function updateControls() {
var routes = availableRoutes();
// Remove the 'enabled' class from all directions
[ dom.controlsLeft, dom.controlsRight, dom.controlsUp, dom.controlsDown ].forEach( function( node ) {
node.classList.remove( 'enabled' );
} )
if( routes.left ) dom.controlsLeft.classList.add( 'enabled' );
if( routes.right ) dom.controlsRight.classList.add( 'enabled' );
if( routes.up ) dom.controlsUp.classList.add( 'enabled' );
if( routes.down ) dom.controlsDown.classList.add( 'enabled' );
}
/**
* Determine what available routes there are for navigation.
*
* @return {Object} containing four booleans: left/right/up/down
*/
function availableRoutes() {
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
var verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
return {
left: indexh > 0,
right: indexh < horizontalSlides.length - 1,
up: indexv > 0,
down: indexv < verticalSlides.length - 1
};
}
/**
* Reads the current URL (hash) and navigates accordingly.
*/
function readURL() {
// Break the hash down to separate components
var bits = window.location.hash.slice(2).split('/');
// Read the index components of the hash
indexh = parseInt( bits[0] ) || 0 ;
indexv = parseInt( bits[1] ) || 0 ;
navigateTo( indexh, indexv );
}
/**
* Updates the page URL (hash) to reflect the current
* state.
*/
function writeURL() {
if( config.history ) {
var url = '/';
// Only include the minimum possible number of components in
// the URL
if( indexh > 0 || indexv > 0 ) url += indexh;
if( indexv > 0 ) url += '/' + indexv;
window.location.hash = url;
}
}
/**
* Navigate to the next slide fragment.
*
* @return {Boolean} true if there was a next fragment,
* false otherwise
*/
function nextFragment() {
// Vertical slides:
if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
if( verticalFragments.length ) {
verticalFragments[0].classList.add( 'visible' );
return true;
}
}
// Horizontal slides:
else {
var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
if( horizontalFragments.length ) {
horizontalFragments[0].classList.add( 'visible' );
return true;
}
}
return false;
}
/**
* Navigate to the previous slide fragment.
*
* @return {Boolean} true if there was a previous fragment,
* false otherwise
*/
function previousFragment() {
// Vertical slides:
if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment.visible' );
if( verticalFragments.length ) {
verticalFragments[ verticalFragments.length - 1 ].classList.remove( 'visible' );
return true;
}
}
// Horizontal slides:
else {
var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment.visible' );
if( horizontalFragments.length ) {
horizontalFragments[ horizontalFragments.length - 1 ].classList.remove( 'visible' );
return true;
}
}
return false;
}
/**
* Triggers a navigation to the specified indices.
*
* @param {Number} h The horizontal index of the slide to show
* @param {Number} v The vertical index of the slide to show
*/
function navigateTo( h, v ) {
indexh = h === undefined ? indexh : h;
indexv = v === undefined ? indexv : v;
slide();
}
function navigateLeft() {
// Prioritize hiding fragments
if( overviewIsActive() || previousFragment() === false ) {
indexh --;
indexv = 0;
slide();
}
}
function navigateRight() {
// Prioritize revealing fragments
if( overviewIsActive() || nextFragment() === false ) {
indexh ++;
indexv = 0;
slide();
}
}
function navigateUp() {
// Prioritize hiding fragments
if( overviewIsActive() || previousFragment() === false ) {
indexv --;
slide();
}
}
function navigateDown() {
// Prioritize revealing fragments
if( overviewIsActive() || nextFragment() === false ) {
indexv ++;
slide();
}
}
/**
* Navigates backwards, prioritized in the following order:
* 1) Previous fragment
* 2) Previous vertical slide
* 3) Previous horizontal slide
*/
function navigatePrev() {
// Prioritize revealing fragments
if( previousFragment() === false ) {
if( availableRoutes().up ) {
navigateUp();
}
else {
// Fetch the previous horizontal slide, if there is one
var previousSlide = document.querySelector( '#reveal .slides>section.past:nth-child(' + indexh + ')' );
if( previousSlide ) {
indexv = ( previousSlide.querySelectorAll('section').length + 1 ) || 0;
indexh --;
slide();
}
}
}
}
/**
* Same as #navigatePrev() but navigates forwards.
*/
function navigateNext() {
// Prioritize revealing fragments
if( nextFragment() === false ) {
availableRoutes().down ? navigateDown() : navigateRight();
}
}
// Expose some methods publicly
return {
initialize: initialize,
navigateTo: navigateTo,
navigateLeft: navigateLeft,
navigateRight: navigateRight,
navigateUp: navigateUp,
navigateDown: navigateDown
};
})();

View File

@@ -1,289 +0,0 @@
/**
* Copyright (C) 2011 Hakim El Hattab, http://hakim.se
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* Handles the very minimal navigation logic involved in the
* slideshow. Including keyboard navigation, touch interaction
* and URL history behavior.
*
* Slides are given unique hash based URL's so that they can be
* opened directly. I didn't use the HTML5 History API for this
* as it would have required the addition of server side rewrite
* rules and hence require more effort for anyone to set up.
*
* This component can be called from other scripts via a tiny API:
* - Slideshow.navigateTo( indexh, indexv );
* - Slideshow.navigateLeft();
* - Slideshow.navigateRight();
* - Slideshow.navigateUp();
* - Slideshow.navigateDown();
*
*
* version 0.1:
* - First release
*
* version 0.2:
* - Refactored code and added inline documentation
* - Slides now have unique URL's
* - A basic API to invoke navigation was added
*
* version 0.3:
* - Added licensing terms
*
* version 0.4:
* - Fixed broken links on touch devices.
*
*
* @author Hakim El Hattab
* @version 0.4
*/
var Slideshow = (function(){
var indexh = 0,
indexv = 0;
/**
* Activates the main program logic.
*/
function initialize() {
document.addEventListener('keydown', onDocumentKeyDown, false);
document.addEventListener('touchstart', onDocumentTouchStart, false);
window.addEventListener('hashchange', onWindowHashChange, false);
// Read the initial state of the URL (hash)
readURL();
}
/**
* Handler for the document level 'keydown' event.
*
* @param {Object} event
*/
function onDocumentKeyDown( event ) {
if( event.keyCode >= 37 && event.keyCode <= 40 ) {
switch( event.keyCode ) {
case 37: navigateLeft(); break; // left
case 39: navigateRight(); break; // right
case 38: navigateUp(); break; // up
case 40: navigateDown(); break; // down
}
slide();
event.preventDefault();
}
}
/**
* Handler for the document level 'touchstart' event.
*
* This enables very basic tap interaction for touch
* devices. Added mainly for performance testing of 3D
* transforms on iOS but was so happily surprised with
* how smoothly it runs so I left it in here. Apple +1
*
* @param {Object} event
*/
function onDocumentTouchStart( event ) {
// We're only interested in one point taps
if (event.touches.length === 1) {
// Never prevent taps on anchors and images
if( event.target.tagName.toLowerCase() === 'a' || event.target.tagName.toLowerCase() === 'img' ) {
return;
}
event.preventDefault();
var point = {
x: event.touches[0].clientX,
y: event.touches[0].clientY
};
// Define the extent of the areas that may be tapped
// to navigate
var wt = window.innerWidth * 0.3;
var ht = window.innerHeight * 0.3;
if( point.x < wt ) {
navigateLeft();
}
else if( point.x > window.innerWidth - wt ) {
navigateRight();
}
else if( point.y < ht ) {
navigateUp();
}
else if( point.y > window.innerHeight - ht ) {
navigateDown();
}
slide();
}
}
/**
* Handler for the window level 'hashchange' event.
*
* @param {Object} event
*/
function onWindowHashChange( event ) {
readURL();
}
/**
* Updates one dimension of slides by showing the slide
* with the specified index.
*
* @param {String} selector A CSS selector that will fetch
* the group of slides we are working with
* @param {Number} index The index of the slide that should be
* shown
*
* @return {Number} The index of the slide that is now shown,
* might differ from the passed in index if it was out of
* bounds.
*/
function updateSlides( selector, index ) {
// Select all slides and convert the NodeList result to
// an array
var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) );
if( slides.length ) {
// Enforce max and minimum index bounds
index = Math.max(Math.min(index, slides.length - 1), 0);
slides[index].setAttribute('class', 'present');
// Any element previous to index is given the 'past' class
slides.slice(0, index).map(function(element){
element.setAttribute('class', 'past');
});
// Any element subsequent to index is given the 'future' class
slides.slice(index + 1).map(function(element){
element.setAttribute('class', 'future');
});
}
else {
// Since there are no slides we can't be anywhere beyond the
// zeroth index
index = 0;
}
return index;
}
/**
* Updates the visual slides to represent the currently
* set indices.
*/
function slide() {
indexh = updateSlides( '#main>section', indexh );
indexv = updateSlides( 'section.present>section', indexv );
writeURL();
}
/**
* Reads the current URL (hash) and navigates accordingly.
*/
function readURL() {
// Break the hash down to separate components
var bits = window.location.hash.slice(2).split('/');
// Read the index components of the hash
indexh = bits[0] ? parseInt( bits[0] ) : 0;
indexv = bits[1] ? parseInt( bits[1] ) : 0;
navigateTo( indexh, indexv );
}
/**
* Updates the page URL (hash) to reflect the current
* navigational state.
*/
function writeURL() {
var url = '/';
// Only include the minimum possible number of components in
// the URL
if( indexh > 0 || indexv > 0 ) url += indexh
if( indexv > 0 ) url += '/' + indexv
window.location.hash = url;
}
/**
* Triggers a navigation to the specified indices.
*
* @param {Number} h The horizontal index of the slide to show
* @param {Number} v The vertical index of the slide to show
*/
function navigateTo( h, v ) {
indexh = h === undefined ? indexh : h;
indexv = v === undefined ? indexv : v;
slide();
}
function navigateLeft() {
indexh --;
indexv = 0;
slide();
}
function navigateRight() {
indexh ++;
indexv = 0;
slide();
}
function navigateUp() {
indexv --;
slide();
}
function navigateDown() {
indexv ++;
slide();
}
// Initialize the program. Done right before returning to ensure
// that any inline variable definitions are available to all
// functions
initialize();
// Expose some methods publicly
return {
navigateTo: navigateTo,
navigateLeft: navigateLeft,
navigateRight: navigateRight,
navigateUp: navigateUp,
navigateDown: navigateDown
};
})();

3
lib/classList.js Normal file
View File

@@ -0,0 +1,3 @@
// classList polyfill from https://github.com/remy/polyfills/blob/master/classList.js
(function(){function c(a){this._element=a;if(a.className!=this.classCache){this._classCache=a.className;var a=this._classCache.split(" "),b;for(b=0;b<a.length;b++)e.call(this,a[b])}}if(!("undefined"===typeof Element||Element.prototype.hasOwnProperty("classList"))){var d=[].indexOf,f=[].slice,e=[].push,g=[].splice,h=[].join;c.prototype={add:function(a){e.call(this,a);this._element.className=f.call(this,0).join(" ")},contains:function(a){return-1!==d.call(this,a)},item:function(a){return this[a]||null},
remove:function(a){a=d.call(this,a);g.call(this,a,1);this._element.className=f.call(this,0).join(" ")},toString:function(){return h.call(this," ")},toggle:function(a){-1===d.call(this,a)?this.add(a):this.remove(a)}};window.DOMTokenList=c;Element.prototype.__defineGetter__("classList",function(){return new c(this)})}})();

5
lib/highlight.js Normal file

File diff suppressed because one or more lines are too long

115
lib/zenburn.css Normal file
View File

@@ -0,0 +1,115 @@
/*
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
based on dark.css by Ivan Sagalaev
*/
pre code {
display: block; padding: 0.5em;
background: #3F3F3F;
color: #DCDCDC;
}
pre .keyword,
pre .tag,
pre .django .tag,
pre .django .keyword,
pre .css .class,
pre .css .id,
pre .lisp .title {
color: #E3CEAB;
}
pre .django .template_tag,
pre .django .variable,
pre .django .filter .argument {
color: #DCDCDC;
}
pre .number,
pre .date {
color: #8CD0D3;
}
pre .dos .envvar,
pre .dos .stream,
pre .variable,
pre .apache .sqbracket {
color: #EFDCBC;
}
pre .dos .flow,
pre .diff .change,
pre .python .exception,
pre .python .built_in,
pre .literal,
pre .tex .special {
color: #EFEFAF;
}
pre .diff .chunk,
pre .ruby .subst {
color: #8F8F8F;
}
pre .dos .keyword,
pre .python .decorator,
pre .class .title,
pre .haskell .label,
pre .function .title,
pre .ini .title,
pre .diff .header,
pre .ruby .class .parent,
pre .apache .tag,
pre .nginx .built_in,
pre .tex .command,
pre .input_number {
color: #efef8f;
}
pre .dos .winutils,
pre .ruby .symbol,
pre .ruby .symbol .string,
pre .ruby .symbol .keyword,
pre .ruby .symbol .keymethods,
pre .ruby .string,
pre .ruby .instancevar {
color: #DCA3A3;
}
pre .diff .deletion,
pre .string,
pre .tag .value,
pre .preprocessor,
pre .built_in,
pre .sql .aggregate,
pre .javadoc,
pre .smalltalk .class,
pre .smalltalk .localvars,
pre .smalltalk .array,
pre .css .rules .value,
pre .attr_selector,
pre .pseudo,
pre .apache .cbracket,
pre .tex .formula {
color: #CC9393;
}
pre .shebang,
pre .diff .addition,
pre .comment,
pre .java .annotation,
pre .template_comment,
pre .pi,
pre .doctype {
color: #7F9F7F;
}
pre .xml .css,
pre .xml .javascript,
pre .xml .vbscript,
pre .tex .formula {
opacity: 0.5;
}