Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Chris Lawrence 2013-09-15 20:19:47 -04:00
commit 55f220109c
15 changed files with 308 additions and 178 deletions

View file

@ -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: '.'
}
}

View file

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

View file

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

File diff suppressed because one or more lines are too long

View file

@ -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 &lt; len; i++ ) {
var node = nodes[i];
if( !node.className ) ) {
if( !node.className ) {
node.className += ' roll';
}
};
}
}
}
</code></pre>

View file

@ -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,7 +356,6 @@ var Reveal = (function(){
createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null );
// Cache references to elements
if ( config.controls ) {
dom.controls = document.querySelector( '.reveal .controls' );
// There can be multiple instances of controls throughout the page
@ -363,7 +365,6 @@ var Reveal = (function(){
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,7 +582,6 @@ 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 ); } );
@ -595,7 +590,6 @@ var Reveal = (function(){
dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } );
dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } );
} );
}
}
@ -624,7 +618,6 @@ 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 ); } );
@ -633,7 +626,6 @@ var Reveal = (function(){
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 );
@ -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,8 +1779,6 @@ var Reveal = (function(){
*/
function updateControls() {
if ( config.controls && dom.controls ) {
var routes = availableRoutes();
var fragments = availableFragments();
@ -1834,7 +1819,6 @@ var Reveal = (function(){
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

File diff suppressed because one or more lines are too long

View file

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

View file

@ -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"
},

View file

@ -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,6 +280,11 @@
var section = sections[i];
// Only parse the same slide once
if( !section.getAttribute( 'data-markdown-parsed' ) ) {
section.setAttribute( 'data-markdown-parsed', true )
var notes = section.querySelector( 'aside.notes' );
var markdown = getMarkdownFromSlide( section );
@ -265,7 +300,21 @@
}
loadExternalMarkdown();
convertMarkdownToHTML();
}
})();
// API
return {
initialize: function() {
processSlides();
convertSlides();
},
// TODO: Do these belong in the API?
processSlides: processSlides,
convertSlides: convertSlides,
slidify: slidify
};
}));

View file

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

View file

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

View file

@ -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
View 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
View 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();