fragments are now included in URL by default, even on named slides
This commit is contained in:
parent
d727509dbc
commit
9823be99f4
9 changed files with 123 additions and 30 deletions
|
@ -263,7 +263,7 @@ Reveal.initialize({
|
||||||
|
|
||||||
// Flags whether to include the current fragment in the URL,
|
// Flags whether to include the current fragment in the URL,
|
||||||
// so that reloading brings you to the same fragment position
|
// so that reloading brings you to the same fragment position
|
||||||
fragmentInURL: false,
|
fragmentInURL: true,
|
||||||
|
|
||||||
// Flags if the presentation is running in an embedded mode,
|
// Flags if the presentation is running in an embedded mode,
|
||||||
// i.e. contained within a limited portion of the screen
|
// i.e. contained within a limited portion of the screen
|
||||||
|
|
4
dist/reveal.es5.js
vendored
4
dist/reveal.es5.js
vendored
File diff suppressed because one or more lines are too long
2
dist/reveal.es5.js.map
vendored
2
dist/reveal.es5.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/reveal.js
vendored
4
dist/reveal.js
vendored
File diff suppressed because one or more lines are too long
2
dist/reveal.js.map
vendored
2
dist/reveal.js.map
vendored
File diff suppressed because one or more lines are too long
|
@ -124,7 +124,7 @@ export default {
|
||||||
|
|
||||||
// Flags whether to include the current fragment in the URL,
|
// Flags whether to include the current fragment in the URL,
|
||||||
// so that reloading brings you to the same fragment position
|
// so that reloading brings you to the same fragment position
|
||||||
fragmentInURL: false,
|
fragmentInURL: true,
|
||||||
|
|
||||||
// Flags if the presentation is running in an embedded mode,
|
// Flags if the presentation is running in an embedded mode,
|
||||||
// i.e. contained within a limited portion of the screen
|
// i.e. contained within a limited portion of the screen
|
||||||
|
|
|
@ -12,6 +12,20 @@ export default class Location {
|
||||||
// Delays updates to the URL due to a Chrome thumbnailer bug
|
// Delays updates to the URL due to a Chrome thumbnailer bug
|
||||||
this.writeURLTimeout = 0;
|
this.writeURLTimeout = 0;
|
||||||
|
|
||||||
|
this.onWindowHashChange = this.onWindowHashChange.bind( this );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bind() {
|
||||||
|
|
||||||
|
window.addEventListener( 'hashchange', this.onWindowHashChange, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unbind() {
|
||||||
|
|
||||||
|
window.removeEventListener( 'hashchange', this.onWindowHashChange, false );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,13 +41,22 @@ export default class Location {
|
||||||
|
|
||||||
// Attempt to parse the hash as either an index or name
|
// Attempt to parse the hash as either an index or name
|
||||||
let bits = hash.slice( 2 ).split( '/' ),
|
let bits = hash.slice( 2 ).split( '/' ),
|
||||||
name = hash.replace( /#|\//gi, '' );
|
name = hash.replace( /#\/?/gi, '' );
|
||||||
|
|
||||||
// If the first bit is not fully numeric and there is a name we
|
// If the first bit is not fully numeric and there is a name we
|
||||||
// can assume that this is a named link
|
// can assume that this is a named link
|
||||||
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
||||||
let element;
|
let element;
|
||||||
|
|
||||||
|
let f;
|
||||||
|
|
||||||
|
// Parse named links with fragments (#/named-link/2)
|
||||||
|
if( /\/[-\d]+$/g.test( name ) ) {
|
||||||
|
f = parseInt( name.split( '/' ).pop(), 10 );
|
||||||
|
f = isNaN(f) ? undefined : f;
|
||||||
|
name = name.split( '/' ).shift();
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the named link is a valid HTML ID attribute
|
// Ensure the named link is a valid HTML ID attribute
|
||||||
try {
|
try {
|
||||||
element = document.getElementById( decodeURIComponent( name ) );
|
element = document.getElementById( decodeURIComponent( name ) );
|
||||||
|
@ -45,10 +68,10 @@ export default class Location {
|
||||||
|
|
||||||
if( element ) {
|
if( element ) {
|
||||||
// If the slide exists and is not the current slide...
|
// If the slide exists and is not the current slide...
|
||||||
if ( !isSameNameAsCurrentSlide ) {
|
if ( !isSameNameAsCurrentSlide || typeof f !== 'undefined' ) {
|
||||||
// ...find the position of the named slide and navigate to it
|
// ...find the position of the named slide and navigate to it
|
||||||
let elementIndex = this.Reveal.getIndices(element);
|
let slideIndices = this.Reveal.getIndices( element );
|
||||||
this.Reveal.slide(elementIndex.h, elementIndex.v);
|
this.Reveal.slide( slideIndices.h, slideIndices.v, f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the slide doesn't exist, navigate to the current slide
|
// If the slide doesn't exist, navigate to the current slide
|
||||||
|
@ -141,19 +164,34 @@ export default class Location {
|
||||||
|
|
||||||
// If the current slide has an ID, use that as a named link,
|
// If the current slide has an ID, use that as a named link,
|
||||||
// but we don't support named links with a fragment index
|
// but we don't support named links with a fragment index
|
||||||
if( typeof id === 'string' && id.length && index.f === undefined ) {
|
if( typeof id === 'string' && id.length ) {
|
||||||
url = '/' + id;
|
url = '/' + id;
|
||||||
|
|
||||||
|
// If there is also a fragment, append that at the end
|
||||||
|
// of the named link, like: #/named-link/2
|
||||||
|
if( index.f >= 0 ) url += '/' + index.f;
|
||||||
}
|
}
|
||||||
// Otherwise use the /h/v index
|
// Otherwise use the /h/v index
|
||||||
else {
|
else {
|
||||||
let hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;
|
let hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;
|
||||||
if( index.h > 0 || index.v > 0 || index.f !== undefined ) url += index.h + hashIndexBase;
|
if( index.h > 0 || index.v > 0 || index.f >= 0 ) url += index.h + hashIndexBase;
|
||||||
if( index.v > 0 || index.f !== undefined ) url += '/' + (index.v + hashIndexBase );
|
if( index.v > 0 || index.f >= 0 ) url += '/' + (index.v + hashIndexBase );
|
||||||
if( index.f !== undefined ) url += '/' + index.f;
|
if( index.f >= 0 ) url += '/' + index.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the window level 'hashchange' event.
|
||||||
|
*
|
||||||
|
* @param {object} [event]
|
||||||
|
*/
|
||||||
|
onWindowHashChange( event ) {
|
||||||
|
|
||||||
|
this.readURL();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
15
js/reveal.js
15
js/reveal.js
|
@ -490,13 +490,13 @@ export default function( revealElement, options ) {
|
||||||
|
|
||||||
eventsAreBound = true;
|
eventsAreBound = true;
|
||||||
|
|
||||||
window.addEventListener( 'hashchange', onWindowHashChange, false );
|
|
||||||
window.addEventListener( 'resize', onWindowResize, false );
|
window.addEventListener( 'resize', onWindowResize, false );
|
||||||
|
|
||||||
if( config.touch ) touch.bind();
|
if( config.touch ) touch.bind();
|
||||||
if( config.keyboard ) keyboard.bind();
|
if( config.keyboard ) keyboard.bind();
|
||||||
if( config.progress ) progress.bind();
|
if( config.progress ) progress.bind();
|
||||||
controls.bind();
|
controls.bind();
|
||||||
|
location.bind();
|
||||||
|
|
||||||
dom.slides.addEventListener( 'transitionend', onTransitionEnd, false );
|
dom.slides.addEventListener( 'transitionend', onTransitionEnd, false );
|
||||||
dom.pauseOverlay.addEventListener( 'click', resume, false );
|
dom.pauseOverlay.addEventListener( 'click', resume, false );
|
||||||
|
@ -518,8 +518,8 @@ export default function( revealElement, options ) {
|
||||||
keyboard.unbind();
|
keyboard.unbind();
|
||||||
controls.unbind();
|
controls.unbind();
|
||||||
progress.unbind();
|
progress.unbind();
|
||||||
|
location.unbind();
|
||||||
|
|
||||||
window.removeEventListener( 'hashchange', onWindowHashChange, false );
|
|
||||||
window.removeEventListener( 'resize', onWindowResize, false );
|
window.removeEventListener( 'resize', onWindowResize, false );
|
||||||
|
|
||||||
dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );
|
dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );
|
||||||
|
@ -2288,17 +2288,6 @@ export default function( revealElement, options ) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for the window level 'hashchange' event.
|
|
||||||
*
|
|
||||||
* @param {object} [event]
|
|
||||||
*/
|
|
||||||
function onWindowHashChange( event ) {
|
|
||||||
|
|
||||||
location.readURL();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the window level 'resize' event.
|
* Handler for the window level 'resize' event.
|
||||||
*
|
*
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<iframe data-src="http://example.com"></iframe>
|
<iframe data-src="http://example.com"></iframe>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section id="fragments3">
|
||||||
<h1>3.3</h1>
|
<h1>3.3</h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="fragment" data-fragment-index="1">3.3.1</li>
|
<li class="fragment" data-fragment-index="1">3.3.1</li>
|
||||||
|
@ -79,6 +79,8 @@
|
||||||
|
|
||||||
<script src="../dist/reveal.es5.js"></script>
|
<script src="../dist/reveal.es5.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
window.location.hash = '';
|
||||||
|
|
||||||
// These tests expect the DOM to contain a presentation
|
// These tests expect the DOM to contain a presentation
|
||||||
// with the following slide structure:
|
// with the following slide structure:
|
||||||
//
|
//
|
||||||
|
@ -311,6 +313,70 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// URL TESTS
|
||||||
|
|
||||||
|
QUnit.module( 'URL' );
|
||||||
|
|
||||||
|
QUnit.test( 'Write (fragmentInURL: false)', function( assert ) {
|
||||||
|
Reveal.configure({ hash: true, fragmentInURL: false });
|
||||||
|
|
||||||
|
Reveal.slide( 2, 0 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/2' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/2/1' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 0, 1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/2' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 2, 0 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/fragments3' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 2, 1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/fragments3' );
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test( 'Write (fragmentInURL: true)', function( assert ) {
|
||||||
|
Reveal.configure({ hash: true, fragmentInURL: true });
|
||||||
|
|
||||||
|
Reveal.slide( 2, 0, -1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/2' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 1, -1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/2/1' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 0, 1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/2/0/1' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 2, -1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/fragments3' );
|
||||||
|
|
||||||
|
Reveal.slide( 2, 2, 1 );
|
||||||
|
assert.strictEqual( window.location.hash, '#/fragments3/1' );
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test( 'Read', async function( assert ) {
|
||||||
|
Reveal.configure({ hash: true, fragmentInURL: true });
|
||||||
|
|
||||||
|
let test = function( hash, indices ) {
|
||||||
|
return new Promise( resolve => {
|
||||||
|
window.onhashchange = () => {
|
||||||
|
assert.deepEqual( Reveal.getIndices(), indices );
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
window.location.hash = hash;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
await test( '#/0', { h: 0, v: 0, f: undefined } ); // horizontal
|
||||||
|
await test( '#/1/1', { h: 1, v: 1, f: undefined } ); // vertical
|
||||||
|
await test( '#/0/', { h: 0, v: 0, f: undefined } ); // trailing /
|
||||||
|
await test( '#/1/1/', { h: 1, v: 1, f: undefined } ); // trailing /
|
||||||
|
await test( '#/2/0/1', { h: 2, v: 0, f: 1 } ); // fragment
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// FRAGMENT TESTS
|
// FRAGMENT TESTS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue