From 141d69469c5773b0f6850c40688fb91240751ea9 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 20 Aug 2012 22:13:00 -0400 Subject: [PATCH] support for named links (closes #55) --- README.md | 9 +++++++ js/reveal.js | 65 ++++++++++++++++++++++++++++++++++++++---------- js/reveal.min.js | 14 ++++++----- 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1db57be..7b0d859 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,15 @@ Reveal.addEventListener( 'fragmenthidden', function( event ) { } ); ``` +### Internal links + +It's easy to link between slides. The first example below targets the index of another slide whereas the second targets a slide with an ID attribute (```
```): + +```html +Link +Link +``` + ## PDF Export Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome). diff --git a/js/reveal.js b/js/reveal.js index 322d06e..9c26f29 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1,5 +1,5 @@ /*! - * reveal.js 2.0 r19 + * reveal.js 2.0 r20 * http://lab.hakim.se/reveal-js * MIT licensed * @@ -834,14 +834,35 @@ var Reveal = (function(){ * 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('/'); + var hash = window.location.hash; - // Read the index components of the hash - var h = parseInt( bits[0] ) || 0 ; - var v = parseInt( bits[1] ) || 0 ; + // Attempt to parse the hash as either an index or name + var bits = hash.slice( 2 ).split( '/' ), + name = hash.replace( /#|\//gi, '' ); - navigateTo( h, v ); + // If the first bit is invalid and there is a name we can + // assume that this is a named link + if( isNaN( parseInt( bits[0] ) ) && name.length ) { + // Find the slide with the specified name + var slide = document.querySelector( '#' + name ); + + if( slide ) { + // Find the position of the named slide and navigate to it + var indices = Reveal.getIndices( slide ); + navigateTo( indices.h, indices.v ); + } + // If the slide doesn't exist, navigate to the current slide + else { + navigateTo( indexh, indexv ); + } + } + else { + // Read the index components of the hash + var h = parseInt( bits[0] ) || 0, + v = parseInt( bits[1] ) || 0; + + navigateTo( h, v ); + } } /** @@ -1049,12 +1070,30 @@ var Reveal = (function(){ addEventListeners: addEventListeners, removeEventListeners: removeEventListeners, - // Returns the indices of the current slide - getIndices: function() { - return { - h: indexh, - v: indexv - }; + // Returns the indices of the current, or specified, slide + getIndices: function( slide ) { + // By default, return the current indices + var h = indexh, + v = indexv; + + // If a slide is specified, return the indices of that slide + if( slide ) { + var isVertical = !!slide.parentNode.nodeName.match( /section/gi ); + var slideh = isVertical ? slide.parentNode : slide; + + // Select all horizontal slides + var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + + // Now that we know which the horizontal slide is, get its index + h = Math.max( horizontalSlides.indexOf( slideh ), 0 ); + + // If this is a vertical slide, grab the vertical index + if( isVertical ) { + v = Math.max( Array.prototype.slice.call( slide.parentNode.children ).indexOf( slide ), 0 ); + } + } + + return { h: h, v: v }; }, // Returns the previous slide element, may be null diff --git a/js/reveal.min.js b/js/reveal.min.js index 50c95d9..4c2a4b8 100644 --- a/js/reveal.min.js +++ b/js/reveal.min.js @@ -1,5 +1,5 @@ /*! - * reveal.js 2.0 r19 + * reveal.js 2.0 r20 * http://lab.hakim.se/reveal-js * MIT licensed * @@ -51,7 +51,8 @@ c=ab(b,an===undefined?c:an);stateLoop:for(var ah=0,ak=ac.length;ah0,right:l0,down:c0||c>0){ad+=l;}if(c>0){ad+="/"+c;}window.location.hash=ad;}}function p(ae,ad){var af=document.createEvent("HTMLEvents",1,2);af.initEvent(ae,true,true); r(af,ad);d.wrapper.dispatchEvent(af);}function t(){if(document.querySelector(b+".present")){var ae=document.querySelectorAll(b+".present .fragment:not(.visible)"); if(ae.length){ae[0].classList.add("visible");p("fragmentshown",{fragment:ae[0]});return true;}}else{var ad=document.querySelectorAll(k+".present .fragment:not(.visible)"); @@ -61,8 +62,9 @@ if(ad.length){ad[ad.length-1].classList.remove("visible");p("fragmenthidden",{fr if(N.autoSlide){j=setTimeout(v,N.autoSlide);}}function L(ae,ad){a(ae,ad);}function z(){if(V()||M()===false){a(l-1,0);}}function i(){if(V()||t()===false){a(l+1,0); }}function s(){if(V()||M()===false){a(l,c-1);}}function D(){if(V()||t()===false){a(l,c+1);}}function U(){if(M()===false){if(f().up){s();}else{var ad=document.querySelector(".reveal .slides>section.past:nth-child("+l+")"); if(ad){c=(ad.querySelectorAll("section").length+1)||0;l--;a();}}}}function v(){if(t()===false){f().down?D():i();}K();}function T(){if(V()){Y();}else{G(); -}}return{initialize:h,navigateTo:L,navigateLeft:z,navigateRight:i,navigateUp:s,navigateDown:D,navigatePrev:U,navigateNext:v,toggleOverview:T,addEventListeners:C,removeEventListeners:Q,getIndices:function(){return{h:l,v:c}; -},getPreviousSlide:function(){return w;},getCurrentSlide:function(){return E;},getQueryHash:function(){var ad={};location.search.replace(/[A-Z0-9]+?=(\w*)/gi,function(ae){ad[ae.split("=").shift()]=ae.split("=").pop(); -});return ad;},addEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).addEventListener(ae,af,ad); -}},removeEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).removeEventListener(ae,af,ad); +}}return{initialize:h,navigateTo:L,navigateLeft:z,navigateRight:i,navigateUp:s,navigateDown:D,navigatePrev:U,navigateNext:v,toggleOverview:T,addEventListeners:C,removeEventListeners:Q,getIndices:function(ad){var ah=l,af=c; +if(ad){var ai=!!ad.parentNode.nodeName.match(/section/gi);var ag=ai?ad.parentNode:ad;var ae=Array.prototype.slice.call(document.querySelectorAll(k));ah=Math.max(ae.indexOf(ag),0); +if(ai){af=Math.max(Array.prototype.slice.call(ad.parentNode.children).indexOf(ad),0);}}return{h:ah,v:af};},getPreviousSlide:function(){return w;},getCurrentSlide:function(){return E; +},getQueryHash:function(){var ad={};location.search.replace(/[A-Z0-9]+?=(\w*)/gi,function(ae){ad[ae.split("=").shift()]=ae.split("=").pop();});return ad; +},addEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).addEventListener(ae,af,ad);}},removeEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).removeEventListener(ae,af,ad); }}};})(); \ No newline at end of file