+
-
diff --git a/js/impress.js b/js/impress.js
index 46cd7d1..3528ef2 100644
--- a/js/impress.js
+++ b/js/impress.js
@@ -8,7 +8,7 @@
* in modern browsers and inspired by the idea behind prezi.com.
*
*
- * Copyright 2011-2012 Bartek Szopka (@bartaz), 2016-2023 Henrik Ingo (@henrikingo)
+ * Copyright 2011-2012 Bartek Szopka (@bartaz), 2016-2023 Henrik Ingo (@henrikingo)
* and 70+ other contributors
*
* Released under the MIT License.
@@ -4709,6 +4709,11 @@
currentSubstepOrder = el.dataset.substepOrder;
el.classList.add( "substep-visible" );
el.classList.add( "substep-active" );
+ if ( currentSubstepOrder === undefined ) {
+
+ // Stop after one substep as default order
+ break;
+ }
}
return el;
@@ -4741,6 +4746,7 @@
// Continue if there is another substep with the same substepOrder
if ( current > 0 &&
+ visible[ current ].dataset.substepOrder !== undefined &&
visible[ current - 1 ].dataset.substepOrder ===
visible[ current ].dataset.substepOrder ) {
visible.pop();
diff --git a/src/plugins/bookmark/README.md b/src/plugins/bookmark/README.md
new file mode 100644
index 0000000..116827b
--- /dev/null
+++ b/src/plugins/bookmark/README.md
@@ -0,0 +1,27 @@
+# Bookmark
+
+Nonlinear navigation similar to the Goto plugin.
+
+Goto supports nonlinear navigation by *locally* defining *out-links*, accessible via the arrow keys.
+
+Bookmark supports nonlinear navigation by *globally* defining *in-links*, accessible via normal keys like 1,2,3,A,B,C.
+
+Example:
+
+```html
+
+
+```
+
+An `id` is required on the `div`.
+
+If you assign the same key to multiple steps, that hotkey will cycle among them.
+
+WARNING: It's up to you to avoid reserved hotkeys H, B, P, ?, etc.
+
+Author
+------
+
+Copyright 2023 Wong Meng Weng (@mengwong)
+Released under the MIT license.
+
diff --git a/src/plugins/bookmark/bookmark.js b/src/plugins/bookmark/bookmark.js
new file mode 100644
index 0000000..387f964
--- /dev/null
+++ b/src/plugins/bookmark/bookmark.js
@@ -0,0 +1,72 @@
+/**
+ * Bookmark Plugin
+ *
+ * The bookmark plugin consists of
+ * a pre-init plugin,
+ * a keyup listener, and
+ * a pre-stepleave plugin.
+ *
+ * The pre-init plugin surveys all step divs to set up bookmark keybindings.
+ * The pre-stepleave plugin alters the destination when a bookmark hotkey is pressed.
+ *
+ * Example:
+ *
+ *
+ *
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values for a table
+ * of what strings to use for each key. Both .key and .code styles are recognized.
+ *
+ * It's up to the HTML author to avoid reserved hotkeys H, B, P, ? etc.
+ *
+ * Copyright 2016-2017 Henrik Ingo (@henrikingo)
+ * Released under the MIT license.
+ */
+/* global document, impress */
+
+( function( document ) {
+ "use strict";
+ var hotkeys = {};
+ function hotkeyDest( event ) {
+ return ( hotkeys.hasOwnProperty( event.key ) ? hotkeys[ event.key ] :
+ hotkeys.hasOwnProperty( event.code ) ? hotkeys[ event.code ] : null ); }
+
+ // In pre-init phase, build a map of bookmark hotkey to div id, by reviewing all steps
+ impress.addPreInitPlugin( function( root, api ) {
+ root.querySelectorAll( ".step" ).forEach( function( div ) {
+ if ( div.dataset.bookmarkKeyList !== undefined && div.id !== undefined ) {
+ div.dataset.bookmarkKeyList.split( " " ).forEach( ( k ) => {
+ if ( hotkeys.hasOwnProperty( k ) ) {
+ hotkeys[ k ].push( div.id );
+ } else { hotkeys[ k ] = [ div.id ]; } } ); } } );
+
+ api.lib.gc.addEventListener( document, "keyup", function( event ) {
+ if ( hotkeyDest( event ) !== null ) {
+ event.stopImmediatePropagation();
+ api.next( event );
+
+ // Event.preventDefault();
+ }
+ } );
+ } );
+
+ // In pre-stepleave phase, match a hotkey and reset destination accordingly.
+ impress.addPreStepLeavePlugin( function( event ) {
+
+ // Window.console.log(`bookmark: running as PreStepLeavePlugin; event=`);
+ // window.console.log(event)
+ if ( ( !event || !event.origEvent ) ) { return; }
+ var dest = hotkeyDest( event.origEvent );
+ if ( dest ) {
+
+ // Window.console.log(`bookmark: recognizing hotkey ${event.code} goes to ${dest}`)
+ var newTarget = document.getElementById( dest[ 0 ] ); // jshint ignore:line
+ if ( newTarget ) {
+ event.detail.next = newTarget;
+ dest.push( dest.shift() ); // Repeated hotkey presses cycle through each dest.
+ }
+ }
+ } );
+
+} )( document );
+
diff --git a/src/plugins/substep/substep.js b/src/plugins/substep/substep.js
index d79253e..b94f618 100644
--- a/src/plugins/substep/substep.js
+++ b/src/plugins/substep/substep.js
@@ -104,6 +104,11 @@
currentSubstepOrder = el.dataset.substepOrder;
el.classList.add( "substep-visible" );
el.classList.add( "substep-active" );
+ if ( currentSubstepOrder === undefined ) {
+
+ // Stop after one substep as default order
+ break;
+ }
}
return el;
@@ -136,6 +141,7 @@
// Continue if there is another substep with the same substepOrder
if ( current > 0 &&
+ visible[ current ].dataset.substepOrder !== undefined &&
visible[ current - 1 ].dataset.substepOrder ===
visible[ current ].dataset.substepOrder ) {
visible.pop();