Vendor reveal.js 5.2.1 (from 5.1.0)
Contains the upstream 5.2.x feature set, most notably the lightbox
(data-preview-image/data-preview-video opens media full-size in an
overlay), controls: "speaker-only", search API extensions and
speaker-view fixes. The package's local additions are carried over
unchanged: IDS theme (ids.css/ids.scss), extra theme fonts,
chalkboard/customcontrols/menu plugins, and the 1280x720 default
slide size (patched in js/config.js and the dist bundles).
Also fixes a pre-existing fork bug (unrelated to the upgrade): the
slidechanged Highcharts resize hook in default.html now checks that
Highcharts exists, no longer throwing in decks without highcharter.
Docs: README (Rmd + rendered md) gained a short Lightbox section,
NEWS.md notes the library bump.
Verified: examples/ids.html and examples/simple.html re-render and run
error-free through all 13/5 slides (Reveal.VERSION = 5.2.1); lightbox
opens on click and closes with Esc in a dedicated test deck.
Change-Id: I0751129dfb0c9d20b56241377905876314a26011
diff --git a/inst/reveal.js-5.2.1/js/controllers/jumptoslide.js b/inst/reveal.js-5.2.1/js/controllers/jumptoslide.js
new file mode 100644
index 0000000..0aaa2b1
--- /dev/null
+++ b/inst/reveal.js-5.2.1/js/controllers/jumptoslide.js
@@ -0,0 +1,197 @@
+import {
+ SLIDE_NUMBER_FORMAT_CURRENT,
+ SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL
+} from "../utils/constants";
+
+/**
+ * Makes it possible to jump to a slide by entering its
+ * slide number or id.
+ */
+export default class JumpToSlide {
+
+ constructor( Reveal ) {
+
+ this.Reveal = Reveal;
+
+ this.onInput = this.onInput.bind( this );
+ this.onBlur = this.onBlur.bind( this );
+ this.onKeyDown = this.onKeyDown.bind( this );
+
+ }
+
+ render() {
+
+ this.element = document.createElement( 'div' );
+ this.element.className = 'jump-to-slide';
+
+ this.jumpInput = document.createElement( 'input' );
+ this.jumpInput.type = 'text';
+ this.jumpInput.className = 'jump-to-slide-input';
+ this.jumpInput.placeholder = 'Jump to slide';
+ this.jumpInput.addEventListener( 'input', this.onInput );
+ this.jumpInput.addEventListener( 'keydown', this.onKeyDown );
+ this.jumpInput.addEventListener( 'blur', this.onBlur );
+
+ this.element.appendChild( this.jumpInput );
+
+ }
+
+ show() {
+
+ this.indicesOnShow = this.Reveal.getIndices();
+
+ this.Reveal.getRevealElement().appendChild( this.element );
+ this.jumpInput.focus();
+
+ }
+
+ hide() {
+
+ if( this.isVisible() ) {
+ this.element.remove();
+ this.jumpInput.value = '';
+
+ clearTimeout( this.jumpTimeout );
+ delete this.jumpTimeout;
+ }
+
+ }
+
+ isVisible() {
+
+ return !!this.element.parentNode;
+
+ }
+
+ /**
+ * Parses the current input and jumps to the given slide.
+ */
+ jump() {
+
+ clearTimeout( this.jumpTimeout );
+ delete this.jumpTimeout;
+
+ let query = this.jumpInput.value.trim( '' );
+ let indices;
+
+ // When slide numbers are formatted to be a single linear number
+ // (instead of showing a separate horizontal/vertical index) we
+ // use the same format for slide jumps
+ if( /^\d+$/.test( query ) ) {
+ const slideNumberFormat = this.Reveal.getConfig().slideNumber;
+ if( slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT || slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL ) {
+ const slide = this.Reveal.getSlides()[ parseInt( query, 10 ) - 1 ];
+ if( slide ) {
+ indices = this.Reveal.getIndices( slide );
+ }
+ }
+ }
+
+ if( !indices ) {
+ // If the query uses "horizontal.vertical" format, convert to
+ // "horizontal/vertical" so that our URL parser can understand
+ if( /^\d+\.\d+$/.test( query ) ) {
+ query = query.replace( '.', '/' );
+ }
+
+ indices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );
+ }
+
+ // Still no valid index? Fall back on a text search
+ if( !indices && /\S+/i.test( query ) && query.length > 1 ) {
+ indices = this.search( query );
+ }
+
+ if( indices && query !== '' ) {
+ this.Reveal.slide( indices.h, indices.v, indices.f );
+ return true;
+ }
+ else {
+ this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
+ return false;
+ }
+
+ }
+
+ jumpAfter( delay ) {
+
+ clearTimeout( this.jumpTimeout );
+ this.jumpTimeout = setTimeout( () => this.jump(), delay );
+
+ }
+
+ /**
+ * A lofi search that looks for the given query in all
+ * of our slides and returns the first match.
+ */
+ search( query ) {
+
+ const regex = new RegExp( '\\b' + query.trim() + '\\b', 'i' );
+
+ const slide = this.Reveal.getSlides().find( ( slide ) => {
+ return regex.test( slide.innerText );
+ } );
+
+ if( slide ) {
+ return this.Reveal.getIndices( slide );
+ }
+ else {
+ return null;
+ }
+
+ }
+
+ /**
+ * Reverts back to the slide we were on when jump to slide was
+ * invoked.
+ */
+ cancel() {
+
+ this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
+ this.hide();
+
+ }
+
+ confirm() {
+
+ this.jump();
+ this.hide();
+
+ }
+
+ destroy() {
+
+ this.jumpInput.removeEventListener( 'input', this.onInput );
+ this.jumpInput.removeEventListener( 'keydown', this.onKeyDown );
+ this.jumpInput.removeEventListener( 'blur', this.onBlur );
+
+ this.element.remove();
+
+ }
+
+ onKeyDown( event ) {
+
+ if( event.keyCode === 13 ) {
+ this.confirm();
+ }
+ else if( event.keyCode === 27 ) {
+ this.cancel();
+
+ event.stopImmediatePropagation();
+ }
+
+ }
+
+ onInput( event ) {
+
+ this.jumpAfter( 200 );
+
+ }
+
+ onBlur() {
+
+ setTimeout( () => this.hide(), 1 );
+
+ }
+
+}
\ No newline at end of file