Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
55f220109c
@ -1,6 +1,6 @@
|
||||
/* global module:false */
|
||||
module.exports = function(grunt) {
|
||||
|
||||
var port = grunt.option('port') || 8000;
|
||||
// Project configuration
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
@ -78,7 +78,7 @@ module.exports = function(grunt) {
|
||||
connect: {
|
||||
server: {
|
||||
options: {
|
||||
port: 8000,
|
||||
port: port,
|
||||
base: '.'
|
||||
}
|
||||
}
|
||||
|
19
README.md
19
README.md
@ -778,6 +778,8 @@ $ grunt serve
|
||||
|
||||
8. Open <http://localhost:8000> to view your presentation
|
||||
|
||||
You can change the port by using `grunt serve --port 8001`.
|
||||
|
||||
|
||||
### Folder Structure
|
||||
- **css/** Core styles without which the project does not function
|
||||
@ -786,6 +788,23 @@ $ grunt serve
|
||||
- **lib/** All other third party assets (JavaScript, CSS, fonts)
|
||||
|
||||
|
||||
### Contributing
|
||||
|
||||
Please keep the [issue tracker](github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. If you are reporting a bug make sure to include information about which browser and operating system you are using as well as the necessary steps to reproduce the issue.
|
||||
|
||||
If you have personal support questions use [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
|
||||
|
||||
|
||||
#### Pull requests
|
||||
|
||||
- Should follow the coding style
|
||||
- Tabs to indent
|
||||
- Single-quoted strings
|
||||
- No space between function name and opening argument parenthesis
|
||||
- One space after opening and before closing parenthesis
|
||||
- Should be made towards the **dev branch**
|
||||
- Should be submitted from a feature/topic branch (not your master)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
|
@ -517,6 +517,10 @@ body {
|
||||
perspective-origin: 0px -100px;
|
||||
}
|
||||
|
||||
.reveal .slides>section {
|
||||
-ms-perspective: 600px;
|
||||
}
|
||||
|
||||
.reveal .slides>section,
|
||||
.reveal .slides>section>section {
|
||||
display: none;
|
||||
@ -1050,8 +1054,8 @@ body {
|
||||
|
||||
.reveal.fade.overview .slides section,
|
||||
.reveal.fade.overview .slides>section>section,
|
||||
.reveal.fade.exit-overview .slides section,
|
||||
.reveal.fade.exit-overview .slides>section>section {
|
||||
.reveal.fade.overview-deactivating .slides section,
|
||||
.reveal.fade.overview-deactivating .slides>section>section {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-ms-transition: none;
|
||||
|
2
css/reveal.min.css
vendored
2
css/reveal.min.css
vendored
File diff suppressed because one or more lines are too long
11
index.html
11
index.html
@ -167,12 +167,15 @@
|
||||
<h2>Themes</h2>
|
||||
<p>
|
||||
Reveal.js comes with a few themes built in: <br>
|
||||
<a href="?#/themes">Default</a> -
|
||||
<a href="?theme=sky#/themes">Sky</a> -
|
||||
<a href="?theme=beige#/themes">Beige</a> -
|
||||
<a href="?theme=simple#/themes">Simple</a> -
|
||||
<a href="?theme=serif#/themes">Serif</a> -
|
||||
<a href="?theme=night#/themes">Night</a> -
|
||||
<a href="?#/themes">Default</a>
|
||||
<a href="?theme=night#/themes">Night</a> <br>
|
||||
<a href="?theme=moon.css#/themes">Moon</a> -
|
||||
<a href="?theme=simple.css#/themes">Simple</a> -
|
||||
<a href="?theme=solarized.css#/themes">Solarized</a>
|
||||
</p>
|
||||
<p>
|
||||
<small>
|
||||
@ -259,10 +262,10 @@ function linkify( selector ) {
|
||||
for( var i = 0, len = nodes.length; i < len; i++ ) {
|
||||
var node = nodes[i];
|
||||
|
||||
if( !node.className ) ) {
|
||||
if( !node.className ) {
|
||||
node.className += ' roll';
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
164
js/reveal.js
164
js/reveal.js
@ -74,6 +74,9 @@ var Reveal = (function(){
|
||||
// Apply a 3D roll to links on hover
|
||||
rollingLinks: false,
|
||||
|
||||
// Hides the address bar on mobile devices
|
||||
hideAddressBar: true,
|
||||
|
||||
// Opens links in an iframe preview overlay
|
||||
previewLinks: false,
|
||||
|
||||
@ -353,17 +356,15 @@ var Reveal = (function(){
|
||||
createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null );
|
||||
|
||||
// Cache references to elements
|
||||
if ( config.controls ) {
|
||||
dom.controls = document.querySelector( '.reveal .controls' );
|
||||
dom.controls = document.querySelector( '.reveal .controls' );
|
||||
|
||||
// There can be multiple instances of controls throughout the page
|
||||
dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
|
||||
dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) );
|
||||
dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) );
|
||||
dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) );
|
||||
dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
|
||||
dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
|
||||
}
|
||||
// There can be multiple instances of controls throughout the page
|
||||
dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
|
||||
dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) );
|
||||
dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) );
|
||||
dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) );
|
||||
dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
|
||||
dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
|
||||
|
||||
}
|
||||
|
||||
@ -491,13 +492,8 @@ var Reveal = (function(){
|
||||
dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );
|
||||
dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
|
||||
|
||||
if( dom.controls ) {
|
||||
dom.controls.style.display = ( config.controls && dom.controls ) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
if( dom.progress ) {
|
||||
dom.progress.style.display = ( config.progress && dom.progress ) ? 'block' : 'none';
|
||||
}
|
||||
dom.controls.style.display = config.controls ? 'block' : 'none';
|
||||
dom.progress.style.display = config.progress ? 'block' : 'none';
|
||||
|
||||
if( config.rtl ) {
|
||||
dom.wrapper.classList.add( 'rtl' );
|
||||
@ -586,16 +582,14 @@ var Reveal = (function(){
|
||||
dom.progress.addEventListener( 'click', onProgressClicked, false );
|
||||
}
|
||||
|
||||
if ( config.controls && dom.controls ) {
|
||||
[ 'touchstart', 'click' ].forEach( function( eventName ) {
|
||||
dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
|
||||
dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
|
||||
dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } );
|
||||
dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } );
|
||||
dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } );
|
||||
dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } );
|
||||
} );
|
||||
}
|
||||
[ 'touchstart', 'click' ].forEach( function( eventName ) {
|
||||
dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
|
||||
dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
|
||||
dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } );
|
||||
dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } );
|
||||
dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } );
|
||||
dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
@ -624,16 +618,14 @@ var Reveal = (function(){
|
||||
dom.progress.removeEventListener( 'click', onProgressClicked, false );
|
||||
}
|
||||
|
||||
if ( config.controls && dom.controls ) {
|
||||
[ 'touchstart', 'click' ].forEach( function( eventName ) {
|
||||
dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } );
|
||||
dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } );
|
||||
dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } );
|
||||
dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } );
|
||||
dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } );
|
||||
dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } );
|
||||
} );
|
||||
}
|
||||
[ 'touchstart', 'click' ].forEach( function( eventName ) {
|
||||
dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } );
|
||||
dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } );
|
||||
dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } );
|
||||
dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } );
|
||||
dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } );
|
||||
dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
@ -778,7 +770,7 @@ var Reveal = (function(){
|
||||
*/
|
||||
function hideAddressBar() {
|
||||
|
||||
if( /iphone|ipod|android/gi.test( navigator.userAgent ) && !/crios/gi.test( navigator.userAgent ) ) {
|
||||
if( config.hideAddressBar && isMobileDevice ) {
|
||||
// Events that should trigger the address bar to hide
|
||||
window.addEventListener( 'load', removeAddressBar, false );
|
||||
window.addEventListener( 'orientationchange', removeAddressBar, false );
|
||||
@ -792,7 +784,8 @@ var Reveal = (function(){
|
||||
*/
|
||||
function removeAddressBar() {
|
||||
|
||||
if( window.orientation === 0 ) {
|
||||
// Portrait and not Chrome for iOS
|
||||
if( window.orientation === 0 && !/crios/gi.test( navigator.userAgent ) ) {
|
||||
document.documentElement.style.overflow = 'scroll';
|
||||
document.body.style.height = '120%';
|
||||
}
|
||||
@ -1156,7 +1149,7 @@ var Reveal = (function(){
|
||||
var depth = window.innerWidth < 400 ? 1000 : 2500;
|
||||
|
||||
dom.wrapper.classList.add( 'overview' );
|
||||
dom.wrapper.classList.remove( 'exit-overview' );
|
||||
dom.wrapper.classList.remove( 'overview-deactivating' );
|
||||
|
||||
clearTimeout( activateOverviewTimeout );
|
||||
clearTimeout( deactivateOverviewTimeout );
|
||||
@ -1164,7 +1157,7 @@ var Reveal = (function(){
|
||||
// Not the pretties solution, but need to let the overview
|
||||
// class apply first so that slides are measured accurately
|
||||
// before we can position them
|
||||
activateOverviewTimeout = setTimeout( function(){
|
||||
activateOverviewTimeout = setTimeout( function() {
|
||||
|
||||
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
||||
|
||||
@ -1241,25 +1234,19 @@ var Reveal = (function(){
|
||||
// Temporarily add a class so that transitions can do different things
|
||||
// depending on whether they are exiting/entering overview, or just
|
||||
// moving from slide to slide
|
||||
dom.wrapper.classList.add( 'exit-overview' );
|
||||
dom.wrapper.classList.add( 'overview-deactivating' );
|
||||
|
||||
deactivateOverviewTimeout = setTimeout( function () {
|
||||
dom.wrapper.classList.remove( 'exit-overview' );
|
||||
}, 10);
|
||||
dom.wrapper.classList.remove( 'overview-deactivating' );
|
||||
}, 1 );
|
||||
|
||||
// Select all slides
|
||||
var slides = toArray( document.querySelectorAll( SLIDES_SELECTOR ) );
|
||||
|
||||
for( var i = 0, len = slides.length; i < len; i++ ) {
|
||||
var element = slides[i];
|
||||
|
||||
element.style.display = '';
|
||||
|
||||
toArray( document.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) {
|
||||
// Resets all transforms to use the external styles
|
||||
transformElement( element, '' );
|
||||
transformElement( slide, '' );
|
||||
|
||||
element.removeEventListener( 'click', onOverviewSlideClicked, true );
|
||||
}
|
||||
slide.removeEventListener( 'click', onOverviewSlideClicked, true );
|
||||
} );
|
||||
|
||||
slide( indexh, indexv );
|
||||
|
||||
@ -1792,48 +1779,45 @@ var Reveal = (function(){
|
||||
*/
|
||||
function updateControls() {
|
||||
|
||||
if ( config.controls && dom.controls ) {
|
||||
var routes = availableRoutes();
|
||||
var fragments = availableFragments();
|
||||
|
||||
var routes = availableRoutes();
|
||||
var fragments = availableFragments();
|
||||
// Remove the 'enabled' class from all directions
|
||||
dom.controlsLeft.concat( dom.controlsRight )
|
||||
.concat( dom.controlsUp )
|
||||
.concat( dom.controlsDown )
|
||||
.concat( dom.controlsPrev )
|
||||
.concat( dom.controlsNext ).forEach( function( node ) {
|
||||
node.classList.remove( 'enabled' );
|
||||
node.classList.remove( 'fragmented' );
|
||||
} );
|
||||
|
||||
// Remove the 'enabled' class from all directions
|
||||
dom.controlsLeft.concat( dom.controlsRight )
|
||||
.concat( dom.controlsUp )
|
||||
.concat( dom.controlsDown )
|
||||
.concat( dom.controlsPrev )
|
||||
.concat( dom.controlsNext ).forEach( function( node ) {
|
||||
node.classList.remove( 'enabled' );
|
||||
node.classList.remove( 'fragmented' );
|
||||
} );
|
||||
// Add the 'enabled' class to the available routes
|
||||
if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
|
||||
// Add the 'enabled' class to the available routes
|
||||
if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
// Prev/next buttons
|
||||
if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
|
||||
// Prev/next buttons
|
||||
if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
||||
// Highlight fragment directions
|
||||
if( currentSlide ) {
|
||||
|
||||
// Highlight fragment directions
|
||||
if( currentSlide ) {
|
||||
// Always apply fragment decorator to prev/next buttons
|
||||
if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
|
||||
// Always apply fragment decorator to prev/next buttons
|
||||
if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
|
||||
// Apply fragment decorators to directional buttons based on
|
||||
// what slide axis they are in
|
||||
if( isVerticalSlide( currentSlide ) ) {
|
||||
if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
}
|
||||
else {
|
||||
if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
}
|
||||
// Apply fragment decorators to directional buttons based on
|
||||
// what slide axis they are in
|
||||
if( isVerticalSlide( currentSlide ) ) {
|
||||
if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
}
|
||||
else {
|
||||
if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
||||
}
|
||||
|
||||
}
|
||||
|
4
js/reveal.min.js
vendored
4
js/reveal.min.js
vendored
File diff suppressed because one or more lines are too long
@ -13,11 +13,13 @@ pre code {
|
||||
|
||||
pre .keyword,
|
||||
pre .tag,
|
||||
pre .django .tag,
|
||||
pre .django .keyword,
|
||||
pre .css .class,
|
||||
pre .css .id,
|
||||
pre .lisp .title {
|
||||
pre .lisp .title,
|
||||
pre .nginx .title,
|
||||
pre .request,
|
||||
pre .status,
|
||||
pre .clojure .attribute {
|
||||
color: #E3CEAB;
|
||||
}
|
||||
|
||||
@ -49,32 +51,27 @@ pre .tex .special {
|
||||
}
|
||||
|
||||
pre .diff .chunk,
|
||||
pre .ruby .subst {
|
||||
pre .subst {
|
||||
color: #8F8F8F;
|
||||
}
|
||||
|
||||
pre .dos .keyword,
|
||||
pre .python .decorator,
|
||||
pre .class .title,
|
||||
pre .haskell .label,
|
||||
pre .function .title,
|
||||
pre .ini .title,
|
||||
pre .title,
|
||||
pre .haskell .type,
|
||||
pre .diff .header,
|
||||
pre .ruby .class .parent,
|
||||
pre .apache .tag,
|
||||
pre .nginx .built_in,
|
||||
pre .tex .command,
|
||||
pre .input_number {
|
||||
pre .prompt {
|
||||
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 {
|
||||
pre .ruby .string {
|
||||
color: #DCA3A3;
|
||||
}
|
||||
|
||||
@ -106,10 +103,12 @@ pre .doctype {
|
||||
color: #7F9F7F;
|
||||
}
|
||||
|
||||
pre .xml .css,
|
||||
pre .coffeescript .javascript,
|
||||
pre .javascript .xml,
|
||||
pre .tex .formula,
|
||||
pre .xml .javascript,
|
||||
pre .xml .vbscript,
|
||||
pre .tex .formula {
|
||||
pre .xml .css,
|
||||
pre .xml .cdata {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
}
|
14
package.json
14
package.json
@ -21,19 +21,19 @@
|
||||
"node": "~0.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"underscore": "~1.3.3",
|
||||
"underscore": "~1.5.1",
|
||||
"express": "~2.5.9",
|
||||
"mustache": "~0.4.0",
|
||||
"mustache": "~0.7.2",
|
||||
"socket.io": "~0.9.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt-contrib-qunit": "~0.2.2",
|
||||
"grunt-contrib-jshint": "~0.2.0",
|
||||
"grunt-contrib-jshint": "~0.6.4",
|
||||
"grunt-contrib-cssmin": "~0.4.1",
|
||||
"grunt-contrib-uglify": "~0.1.1",
|
||||
"grunt-contrib-watch": "~0.2.0",
|
||||
"grunt-contrib-sass": "~0.2.2",
|
||||
"grunt-contrib-connect": "~0.2.0",
|
||||
"grunt-contrib-uglify": "~0.2.4",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-contrib-sass": "~0.5.0",
|
||||
"grunt-contrib-connect": "~0.4.1",
|
||||
"grunt-zip": "~0.7.0",
|
||||
"grunt": "~0.4.0"
|
||||
},
|
||||
|
@ -3,7 +3,16 @@
|
||||
* markdown inside of presentations as well as loading
|
||||
* of external markdown documents.
|
||||
*/
|
||||
(function(){
|
||||
(function( root, factory ) {
|
||||
if( typeof exports === 'object' ) {
|
||||
module.exports = factory( require( './marked' ) );
|
||||
}
|
||||
else {
|
||||
// Browser globals (root is window)
|
||||
root.RevealMarkdown = factory( root.marked );
|
||||
root.RevealMarkdown.initialize();
|
||||
}
|
||||
}( this, function( marked ) {
|
||||
|
||||
if( typeof marked === 'undefined' ) {
|
||||
throw 'The reveal.js Markdown plugin requires marked to be loaded';
|
||||
@ -17,6 +26,10 @@
|
||||
});
|
||||
}
|
||||
|
||||
var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
|
||||
DEFAULT_NOTES_SEPARATOR = 'note:';
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the markdown contents of a slide section
|
||||
* element. Normalizes leading tabs/whitespace.
|
||||
@ -72,15 +85,32 @@
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the given options and fills out default
|
||||
* values for what's not defined.
|
||||
*/
|
||||
function getSlidifyOptions( options ) {
|
||||
|
||||
options = options || {};
|
||||
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
|
||||
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
||||
options.attributes = options.attributes || '';
|
||||
|
||||
return options;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for constructing a markdown slide.
|
||||
*/
|
||||
function createMarkdownSlide( data ) {
|
||||
function createMarkdownSlide( content, options ) {
|
||||
|
||||
var content = data.content || data;
|
||||
options = getSlidifyOptions( options );
|
||||
|
||||
if( data.notes ) {
|
||||
content += '<aside class="notes" data-markdown>' + data.notes + '</aside>';
|
||||
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
||||
|
||||
if( notesMatch.length === 2 ) {
|
||||
content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
|
||||
}
|
||||
|
||||
return '<script type="text/template">' + content + '</script>';
|
||||
@ -91,25 +121,18 @@
|
||||
* Parses a data string into multiple slides based
|
||||
* on the passed in separator arguments.
|
||||
*/
|
||||
function slidifyMarkdown( markdown, options ) {
|
||||
function slidify( markdown, options ) {
|
||||
|
||||
options = options || {};
|
||||
options.separator = options.separator || '^\n---\n$';
|
||||
options.notesSeparator = options.notesSeparator || 'note:';
|
||||
options.attributes = options.attributes || '';
|
||||
options = getSlidifyOptions( options );
|
||||
|
||||
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
||||
horizontalSeparatorRegex = new RegExp( options.separator ),
|
||||
notesSeparatorRegex = new RegExp( options.notesSeparator, 'mgi' );
|
||||
horizontalSeparatorRegex = new RegExp( options.separator );
|
||||
|
||||
var matches,
|
||||
noteMatch,
|
||||
lastIndex = 0,
|
||||
isHorizontal,
|
||||
wasHorizontal = true,
|
||||
content,
|
||||
notes,
|
||||
slide,
|
||||
sectionStack = [];
|
||||
|
||||
// iterate until all blocks between separators are stacked up
|
||||
@ -126,25 +149,14 @@
|
||||
|
||||
// pluck slide content from markdown input
|
||||
content = markdown.substring( lastIndex, matches.index );
|
||||
noteMatch = content.split( notesSeparatorRegex );
|
||||
|
||||
if( noteMatch.length === 2 ) {
|
||||
content = noteMatch[0];
|
||||
notes = noteMatch[1].trim();
|
||||
}
|
||||
|
||||
slide = {
|
||||
content: content,
|
||||
notes: notes || ''
|
||||
};
|
||||
|
||||
if( isHorizontal && wasHorizontal ) {
|
||||
// add to horizontal stack
|
||||
sectionStack.push( slide );
|
||||
sectionStack.push( content );
|
||||
}
|
||||
else {
|
||||
// add to vertical stack
|
||||
sectionStack[sectionStack.length-1].push( slide );
|
||||
sectionStack[sectionStack.length-1].push( content );
|
||||
}
|
||||
|
||||
lastIndex = separatorRegex.lastIndex;
|
||||
@ -160,12 +172,16 @@
|
||||
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
|
||||
// vertical
|
||||
if( sectionStack[i].propertyIsEnumerable( length ) && typeof sectionStack[i].splice === 'function' ) {
|
||||
markdownSections += '<section '+ options.attributes +'>' +
|
||||
'<section data-markdown>' + sectionStack[i].map( createMarkdownSlide ).join( '</section><section data-markdown>' ) + '</section>' +
|
||||
'</section>';
|
||||
markdownSections += '<section '+ options.attributes +'>';
|
||||
|
||||
sectionStack[i].forEach( function( child ) {
|
||||
markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
|
||||
} );
|
||||
|
||||
markdownSections += '</section>';
|
||||
}
|
||||
else {
|
||||
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i] ) + '</section>';
|
||||
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +189,12 @@
|
||||
|
||||
}
|
||||
|
||||
function loadExternalMarkdown() {
|
||||
/**
|
||||
* Parses any current data-markdown slides, splits
|
||||
* multi-slide markdown into separate sections and
|
||||
* handles loading of external markdown.
|
||||
*/
|
||||
function processSlides() {
|
||||
|
||||
var sections = document.querySelectorAll( '[data-markdown]'),
|
||||
section;
|
||||
@ -198,7 +219,7 @@
|
||||
if( xhr.readyState === 4 ) {
|
||||
if ( xhr.status >= 200 && xhr.status < 300 ) {
|
||||
|
||||
section.outerHTML = slidifyMarkdown( xhr.responseText, {
|
||||
section.outerHTML = slidify( xhr.responseText, {
|
||||
separator: section.getAttribute( 'data-separator' ),
|
||||
verticalSeparator: section.getAttribute( 'data-vertical' ),
|
||||
notesSeparator: section.getAttribute( 'data-notes' ),
|
||||
@ -228,9 +249,9 @@
|
||||
}
|
||||
|
||||
}
|
||||
else if( section.getAttribute( 'data-separator' ) ) {
|
||||
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
|
||||
|
||||
section.outerHTML = slidifyMarkdown( getMarkdownFromSlide( section ), {
|
||||
section.outerHTML = slidify( getMarkdownFromSlide( section ), {
|
||||
separator: section.getAttribute( 'data-separator' ),
|
||||
verticalSeparator: section.getAttribute( 'data-vertical' ),
|
||||
notesSeparator: section.getAttribute( 'data-notes' ),
|
||||
@ -238,11 +259,20 @@
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function convertMarkdownToHTML() {
|
||||
/**
|
||||
* Converts any current data-markdown slides in the
|
||||
* DOM to HTML.
|
||||
*/
|
||||
function convertSlides() {
|
||||
|
||||
var sections = document.querySelectorAll( '[data-markdown]');
|
||||
|
||||
@ -250,22 +280,41 @@
|
||||
|
||||
var section = sections[i];
|
||||
|
||||
var notes = section.querySelector( 'aside.notes' );
|
||||
var markdown = getMarkdownFromSlide( section );
|
||||
// Only parse the same slide once
|
||||
if( !section.getAttribute( 'data-markdown-parsed' ) ) {
|
||||
|
||||
section.innerHTML = marked( markdown );
|
||||
section.setAttribute( 'data-markdown-parsed', true )
|
||||
|
||||
var notes = section.querySelector( 'aside.notes' );
|
||||
var markdown = getMarkdownFromSlide( section );
|
||||
|
||||
section.innerHTML = marked( markdown );
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadExternalMarkdown();
|
||||
convertMarkdownToHTML();
|
||||
// API
|
||||
return {
|
||||
|
||||
})();
|
||||
initialize: function() {
|
||||
processSlides();
|
||||
convertSlides();
|
||||
},
|
||||
|
||||
// TODO: Do these belong in the API?
|
||||
processSlides: processSlides,
|
||||
convertSlides: convertSlides,
|
||||
slidify: slidify
|
||||
|
||||
};
|
||||
|
||||
}));
|
||||
|
@ -1,6 +1,7 @@
|
||||
(function() {
|
||||
// don't emit events from inside the previews themselves
|
||||
// Don't emit events from inside of notes windows
|
||||
if ( window.location.search.match( /receiver/gi ) ) { return; }
|
||||
|
||||
var multiplex = Reveal.getConfig().multiplex;
|
||||
|
||||
var socket = io.connect(multiplex.url);
|
||||
|
@ -139,11 +139,11 @@
|
||||
<body>
|
||||
|
||||
<div id="wrap-current-slide" class="slides">
|
||||
<script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ window.opener.location.href +'"></iframe>' );</script>
|
||||
<script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ window.opener.location.href +'?receiver"></iframe>' );</script>
|
||||
</div>
|
||||
|
||||
<div id="wrap-next-slide" class="slides">
|
||||
<script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ window.opener.location.href +'"></iframe>' );</script>
|
||||
<script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ window.opener.location.href +'?receiver"></iframe>' );</script>
|
||||
<span>UPCOMING:</span>
|
||||
</div>
|
||||
|
||||
@ -239,6 +239,10 @@
|
||||
currentSlide.contentWindow.Reveal.addEventListener( 'fragmentshown', synchronizeMainWindow );
|
||||
currentSlide.contentWindow.Reveal.addEventListener( 'fragmenthidden', synchronizeMainWindow );
|
||||
|
||||
// Reconfigure the notes window to remove needless UI
|
||||
currentSlide.contentWindow.Reveal.configure({ controls: false, progress: false, overview: false });
|
||||
nextSlide.contentWindow.Reveal.configure({ controls: false, progress: false, overview: false });
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
* Detects if notes are enable and the current page is opened inside an /iframe
|
||||
* this prevents loading Remotes.io several times
|
||||
*/
|
||||
var remotesAndIsNotes = (function(){
|
||||
return !(window.RevealNotes && self == top);
|
||||
var isNotesAndIframe = (function(){
|
||||
return window.RevealNotes && !(self == top);
|
||||
})();
|
||||
|
||||
if(!hasTouch && !remotesAndIsNotes){
|
||||
if(!hasTouch && !isNotesAndIframe){
|
||||
head.ready( 'remotes.ne.min.js', function() {
|
||||
new Remotes("preview")
|
||||
.on("swipe-left", function(e){ Reveal.right(); })
|
||||
|
52
test/test-markdown.html
Normal file
52
test/test-markdown.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - Test Markdown</title>
|
||||
|
||||
<link rel="stylesheet" href="../css/reveal.min.css">
|
||||
<link rel="stylesheet" href="qunit-1.12.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 data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
|
||||
|
||||
<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
|
||||
<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
|
||||
<script type="text/template">
|
||||
## Slide 1.1
|
||||
|
||||
--
|
||||
|
||||
## Slide 1.2
|
||||
|
||||
---
|
||||
|
||||
## Slide 2
|
||||
</script>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="../lib/js/head.min.js"></script>
|
||||
<script src="../js/reveal.min.js"></script>
|
||||
<script src="../plugin/markdown/marked.js"></script>
|
||||
<script src="../plugin/markdown/markdown.js"></script>
|
||||
<script src="qunit-1.12.0.js"></script>
|
||||
|
||||
<script src="test-markdown.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
15
test/test-markdown.js
Normal file
15
test/test-markdown.js
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
|
||||
Reveal.addEventListener( 'ready', function() {
|
||||
|
||||
QUnit.module( 'Markdown' );
|
||||
|
||||
test( 'Vertical separator', function() {
|
||||
strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
|
||||
});
|
||||
|
||||
|
||||
} );
|
||||
|
||||
Reveal.initialize();
|
||||
|
Loading…
Reference in New Issue
Block a user