mirror of
https://github.com/hakimel/reveal.js.git
synced 2025-09-15 00:52:11 +02:00
Compare commits
73 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f59e64a571 | ||
|
d3e2a95d77 | ||
|
0d9a6419bb | ||
|
8dc7ae85a1 | ||
|
2c78eea0ca | ||
|
831236890c | ||
|
0cd3b8d430 | ||
|
732ed921eb | ||
|
be76bf3d23 | ||
|
87529c4adc | ||
|
b72bee3219 | ||
|
cd66a6574d | ||
|
b6030d5c7a | ||
|
a77842521e | ||
|
81cda2145f | ||
|
7f3bf1409e | ||
|
67add62316 | ||
|
f27db1dc84 | ||
|
ba8fc0bc35 | ||
|
a53b315e24 | ||
|
38b229a22f | ||
|
17854e892b | ||
|
896e0b7010 | ||
|
284610dab0 | ||
|
a30cdaaffc | ||
|
9736509bae | ||
|
510ac8e114 | ||
|
c3bc0f70ef | ||
|
2ae803efb6 | ||
|
401c554c80 | ||
|
4d3c3c8d3f | ||
|
36950c8149 | ||
|
614b8cde66 | ||
|
4805234a41 | ||
|
02f783b68d | ||
|
e8507de1e4 | ||
|
cbd59efef8 | ||
|
9856f57db5 | ||
|
73eb66bf71 | ||
|
3fa01ab107 | ||
|
f7ac5fb159 | ||
|
2c088681ec | ||
|
daecc258d7 | ||
|
5b2b3fa3df | ||
|
bccb6e68c7 | ||
|
2313dfef6d | ||
|
c7c7735e7a | ||
|
1ac6386eef | ||
|
b162a54c2d | ||
|
91ff92e211 | ||
|
c6a75117f6 | ||
|
adc9ad19ce | ||
|
f6dc531298 | ||
|
01000e1478 | ||
|
0c231fec38 | ||
|
9065114ef0 | ||
|
91c3056a62 | ||
|
abbd027124 | ||
|
4a4ffd518e | ||
|
bdff009c74 | ||
|
2026c9645c | ||
|
833e298617 | ||
|
11ee006f9d | ||
|
60bf197890 | ||
|
853efe5043 | ||
|
59c9b3c596 | ||
|
e6f444a307 | ||
|
d2faad4730 | ||
|
f9527d31b4 | ||
|
233160ff23 | ||
|
b36e8d5c4e | ||
|
9edb5f6da0 | ||
|
a6453a0fb0 |
106
README.md
106
README.md
@@ -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 |
953
css/main.css
953
css/main.css
File diff suppressed because it is too large
Load Diff
352
index.html
352
index.html
File diff suppressed because one or more lines are too long
750
js/reveal.js
Normal file
750
js/reveal.js
Normal 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
|
||||
};
|
||||
|
||||
})();
|
||||
|
289
js/slideshow.js
289
js/slideshow.js
@@ -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
3
lib/classList.js
Normal 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
5
lib/highlight.js
Normal file
File diff suppressed because one or more lines are too long
115
lib/zenburn.css
Normal file
115
lib/zenburn.css
Normal 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user