10 Commits

Author SHA1 Message Date
x80486
c9f6c67457 Augment pipeline with workflow to run the test suite 2025-09-25 12:43:09 +03:00
x80486
48466a42ae Enable GitHub Actions and Setup Continuous Integration Pipeline 2025-09-19 21:48:45 +03:00
Jaime A. Rodriguez
c95b93a48b Fix typos and improve clarity in GettingStarted.md 2025-09-04 09:57:12 +03:00
Peter Briggs
5da68e0686 Fix typo in index.html
wont -> won't
2024-04-26 20:13:34 +03:00
Falco Nogatz
fd945d5574 Add missing < in opening <a> tag 2024-02-29 12:24:14 +02:00
Falco Nogatz
784b51663f Remove link since in its current form it's invalid HTML 2024-02-29 12:24:14 +02:00
dependabot[bot]
f7e19b459e Bump async from 2.6.3 to 2.6.4 (#859)
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-12 00:45:25 +02:00
emmanuel
eb3c330184 Update README.md (#868)
Typo is corrected
2024-02-07 13:39:11 +02:00
Thomas Reitmayr
b3a7a632c7 Fix default substep order when no explicit order given (#855) (#856)
This affects both going to the next and previous substep.
2023-12-05 06:25:20 +02:00
Meng Weng Wong
d0ba7ff884 New "bookmark" plugin allows hotkey fast-travel to specific steps (#852)
add plugin bookmark supporting direct access via hotkeys
similar to "click", we can now fast travel using hotkeys e.g. 1 2 3
2023-11-01 01:13:40 +02:00
12 changed files with 255 additions and 55 deletions

61
.github/workflows/pipeline.yaml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: Automates the Verification, Testing, and Building Process
env:
NPM_CONFIG_LOGLEVEL: "warn"
NPM_CONFIG_PREFER_OFFLINE: "true"
jobs:
verification:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
- name: Install dependencies
run: npm clean-install
- name: Lint code
run: npm run lint
testing:
needs: verification
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
- name: Install dependencies
run: npm clean-install
- name: Run test suite
run: npm run test
assembly:
needs: testing
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
- name: Install dependencies
run: npm clean-install
- name: Build artifact(s)
run: npm run build
on:
pull_request:
branches:
- master
push:
branches:
- master
permissions:
contents: read

View File

@@ -1,15 +1,15 @@
# Introduction
Welcome to impress.js! This presentation framework allows you to create stunning presentations with the power of CSS3 transformations.
**NOTE:** This Guide is not made for you, if you have never written HTML and/or CSS before. Knowing your way around in JavaScript certainly helps, but is not a necessity. You may still continue this tutorial and try to understand what we do as you go.
**NOTE:** This Guide is not made for you if you have never written HTML and/or CSS before. Knowing your way around in JavaScript certainly helps, but it is not a necessity. You may still continue this tutorial and try to understand what we do as you go.
For more advanced and complete documentation, you might prefer the [DOCUMENTATION](DOCUMENTATION.md).
# Getting started with impress.js
## Installation / acquiring the framework
First of all, you need to know, if you are going to have WiFi connection when you hold your presentation. If you are not sure, please use the method where you download the file instead of the cdn.
First of all, you need to know if you are going to have a WiFi connection when you hold your presentation. If you are not sure, please use the method where you download the file instead of the CDN.
### Including from cdn
Loading the script from the cdn is quite straight forward. If you copy the below example code, you need to do nothing else, impress will be loaded automatically.
### Including from CDN
Loading the script from the CDN is quite straightforward. If you copy the example code below, you need to do nothing else; impress.js will be loaded automatically.
**Direct links to different versions of the impress.js file**
- V2.0.0: https://cdn.jsdelivr.net/gh/impress/impress.js@2.0.0/js/impress.js
@@ -17,11 +17,11 @@ Loading the script from the cdn is quite straight forward. If you copy the below
- Source: https://cdn.jsdelivr.net/gh/impress/impress.js/js/impress.js
### Download the file to your PC
Head to the releases tab and download the source code as zip or as a tarball. Go ahead and unzip / untar it. You need to copy the folder */js/* into the folder you are working in. Optionally, if you want to make your life a bit easier, you can copy also copy the folder */css/* in there.
Head to the releases tab and download the source code as a zip or a tarball. Go ahead and unzip/untar it. You need to copy the folder */js/* into the folder you are working in. Optionally, to make your life a bit easier, you can also copy the */css/* folder into the same location.
## Setting up the project
Open up your favorite text-editor / IDE, for example Visual Studio Code, Atom, Notepad ++, ...
Open up your favorite text editor / IDE, for example, Visual Studio Code, Atom, Notepad++, ...
Now, create a new file called *index.html* and create the basic HTML structure:
```
@@ -50,19 +50,19 @@ Now, create a new file called *index.html* and create the basic HTML structure:
</html>
```
Now, head into a file-manager, navigate to the file you just created (*index.html*) and open it. You should end up in a browser where you should see "My first Slide" displayed. As this is not really exciting, we are not gonna change anything about that and are gonna look at what you just typed. What do these lines mean?
Now, head into a file manager, navigate to the file you just created (*index.html*), and open it. You should end up in a browser where you should see "My first Slide" displayed. Since this isn't exciting, we won't change anything and will review what you just typed. What do these lines mean?
Well, first things first, you should probably give your presentation a title. You may do this in normal HTML fashion by changing the *title* HTML tag.
So now, we reached the HTML body. You can see that it already belongs to a class. This class just tells impress.js that this is the body where the "fallback-message" should be displayed when it detects, that your browser does not support CSS3 and therefore impress.js won't work. You can easily omit that class though, including the "fallback-message" div with its content, if you only intend to use the presentation for yourself and you know about the fact that some browsers might not work.
So now, we have reached the HTML body. You can see that it already belongs to a class. This class just tells impress.js that this is the body where the "fallback-message" should be displayed when it detects, that your browser does not support CSS3 and therefore impress.js won't work. You can easily omit that class though, including the "fallback-message" div with its content, if you only intend to use the presentation for yourself and you know about the fact that some browsers might not work.
Now, probably the most important part of all is the *div* that belongs to the ```impress``` class. This *div* should contain all the HTML code you write, as everything outside that class will not be animated by impress.js.
Finally, we load the ```impress.js``` script from your local copy (if you have one) or from the cdn, if you do not have a local copy and execute
Finally, we load the ```impress.js``` script from your local copy (if you have one) or from the CDN, if you do not have a local copy, and execute
```
impress().init()
```
to initialize impress.js. Now, let's continue on to explore more and more features of this amazing tool!
to initialize impress.js. Now, let's continue to explore more features of this amazing tool!
## Creating slides
Creating slides is fairly easy. You create a *div* that belongs to the class ```step``` and you are off to the races! Let me give you an example:
@@ -74,7 +74,7 @@ Hello World
Now, if you reload the presentation, you start to see a \*slight\* problem. All your text is stacked... How do we work around that?
Obviously, impress.js has an answer to it. You can add the following additional attributes to your div, to make it work:
Obviously, impress.js has an answer to it. You can add the following additional attributes to your div to make it work:
Attribute | Explanation
----------------|------------
@@ -87,11 +87,11 @@ data-rotate-y | Rotate the element along the y-axis
data-rotate-z | Rotate the element along the z-axis
data-scale | Scale the element.
These are the basic positioning options in impress.js. All of the attributes take Strings as arguments, so be aware of the fact, that you need to put quotation marks around the numbers! The *data-rotate* attributes take an angle in form of a String as argument.
These are the basic positioning options in impress.js. All of the attributes take Strings as arguments, so be aware that you need to put quotation marks around the numbers! The *data-rotate* attributes take an angle in the form of a String as an argument.
Now, that you have created the slides, you might want to style them. This is where CSS comes into play. Add another file to your project called, e.g., ```style.css```.
Now that you have created the slides, you might want to style them. This is where CSS comes into play. Add another file to your project called, e.g., ```style.css```.
**NOTE:** Whatever you do, do not mess with positioning and rotation of the div that belongs to the class *step*, but add a div inside of it, if you really have to mess with these properties. See the example below. Always position *steps* with the *data-* attribute!
**NOTE:** Whatever you do, do not mess with the positioning and rotation of the div that belongs to the class *step*, but add a div inside of it, if you really have to mess with these properties. See the example below. Always position *steps* with the *data-* attribute!
```
<div class="step yourClassNameHere" data-x="1000" data-y="1000" data-z="-1000" data-scale="2" data-rotate-z="90">
@@ -115,19 +115,19 @@ data-min-scale | 0 | Minimum scale factor.
data-perspective | 1000 | Perspective for 3D rendering. See https://developer.mozilla.org/en/CSS/perspective
### **Renaming Steps**
You can give each step an ID. The name of the ID will be displayed in the browsers navigation bar instead of the default *step-x* whereas x is replaced by the current step number. This can be especially helpful, when trying to jump between steps and go back to a previous one. If you want to know how to move to a specific slide, you should take a look at the [README](./src/plugins/goto/README.md) of the "Goto" plugin.
You can give each step an ID. The name of the ID will be displayed in the browser's navigation bar instead of the default *step-x*, where x is replaced by the current step number. This can be especially helpful when trying to jump between steps and go back to a previous one. If you want to know how to move to a specific slide, you should take a look at the [README](./src/plugins/goto/README.md) of the "Goto" plugin.
# Using PLUGINS
Impress.js is limited to everything that we have discussed so far and some other details, we won't go over here. Check the [DOCUMENTATION](DOCUMENTATION.md) for that.
Impress.js is limited to everything we have discussed so far, along with some additional details; we won't cover them here. Check the [DOCUMENTATION](DOCUMENTATION.md) for that.
impress.js has accumulated a lot of very useful plugins. You may find all of them [here](./src/plugins/)!
Each Plugin has a README.md file which you may read to get an idea on how to use them. Some of the plugins run unnoticed in the background, like the *resize* plugin, which automatically resizes the presentation whenever the browser window changed in size. Here, I will give you an overview of some of the plugins that impress.js includes by default.
Each Plugin has a README.md file, which you may read to get an idea of how to use it. Some plugins run unnoticed in the background, such as the *resize* plugin, which automatically resizes the presentation whenever the browser window changes size. Here, I will give you an overview of some of the plugins that impress.js includes by default.
**NOTE:** As previously mentioned, if you'd like to get more info about how it works, take a look at the [DOCUMENTATION](DOCUMENTATION.md) or the README.md files of the plugins.
## [impressConsole](/src/plugins/impressConsole/README.md)
This plugin opens up and additional browser tab which contains a speaker console. There you can see the current slide, the past slide and your notes. You add notes to your presentation by adding a *div* that belongs to the class "notes" to your *div* that belongs to the class "step".
This plugin opens up an additional browser tab that contains a speaker console. There you can see the current slide, the past slide, and your notes. You add notes to your presentation by adding a *div* that belongs to the class "notes" to your *div* that belongs to the class "step".
### **adding notes to your presentation**
You may add notes to your presentation by adding a div of class *notes* into the div of class *step*, like so:
@@ -151,17 +151,17 @@ Now that you have added the notes to your HTML, it is time to hide them. You nee
To enter it, press P.
## [Goto](/src/plugins/goto/README.md)
This plugin allows you to directly go to a certain step, by either passing in a number or the id of the step you'd like to go to.
This plugin allows you to directly go to a certain step by either passing in a number or the ID of the step you'd like to go to.
## [Progress](/src/plugins/progress/README.md)
This plugin, as its name implies, displays the progress in your presentation.
## [Blackout](/src/plugins/blackout/blackout.js)
This plugin hides the screen, if you press B, which is handy in a lot of situations.
This plugin hides the screen when you press B, which is handy in many situations.
## Other plugins
You may find the other plugins [here](/src/plugins/). It certainly helps if you familiarise yourself with the plugins.
# Thank you for reading this
If you want to know more, you can always ready the [DOCUMENTATION](DOCUMENTATION.md) or, even better, read the Source Code and try to understand how it works!
If you want to know more, you can always read the [DOCUMENTATION](DOCUMENTATION.md) or, even better, read the Source Code and try to understand how it works!

View File

@@ -109,7 +109,7 @@ ABOUT THE NAME
impress.js name is [courtesy of @skuzniak](http://twitter.com/skuzniak/status/143627215165333504).
It's an (un)fortunate coincidence that a Open/LibreOffice presentation tool is called Impress ;)
It's an (un)fortunate coincidence that an Open/LibreOffice presentation tool is called Impress ;)
Reference API
--------------

View File

@@ -13,6 +13,7 @@ files.push('src/plugins/autoplay/autoplay.js',
'src/plugins/form/form.js',
'src/plugins/fullscreen/fullscreen.js',
'src/plugins/goto/goto.js',
'src/plugins/bookmark/bookmark.js',
'src/plugins/help/help.js',
'src/plugins/impressConsole/impressConsole.js',
'src/plugins/media/media.js',

View File

@@ -28,21 +28,42 @@
<ul>
<li>Impress.js allows you to layout your presentation in a 3D space</li>
<li>Now <a href="https://github.com/impress/impress.js/tree/master/src/plugins/goto">the
goto plugin</a> also allows you to specify
<li><a href="https://github.com/impress/impress.js/tree/master/src/plugins/goto">The
goto plugin</a> allows you to specify
non-linear navigation!</li>
<li>This demo can be navigated by
<ul>
<li>continuously pressing Space</li>
<li>continuously pressing Right Arrow</li>
<li>continuously pressing Down Arrow</li>
<li>(or freely, pressing Up, Down, Right, Left as you choose)</li>
</ul>
<li>It's up to you to decide which is the better structure</li>
</li>
</div>
<div id="bm0" class="step" data-scale="1" data-rel-x="1500" data-rel-y="0"
data-bookmark-key-list="0">
<h1>Using bookmark hotkeys</h1>
<ul>
<li><a href="https://github.com/impress/impress.js/tree/master/src/plugins/bookmark">The
bookmark plugin</a> also allows you to specify
non-linear navigation, in a different way.</li>
<li>This demo can <em>also</em> be navigated by
<ul>
<li>pressing 1 2 3 4 5 6 7 8 9 to fast travel directly</li>
<li>pressing J J J, K K K, L L L to cycle vertically</li>
<li>pressing U U U, I I I, O O O to cycle horizontally</li>
<li>pressing Z or [ to zoom out to the full view</li>
<li>pressing 0 to come back to this text</li>
</ul>
</li>
<li>It's up to you to decide which is the better structure</li>
</ul>
</div>
<div id="contents" class="step" data-rel-x="1500" data-rel-y="1500" data-scale="1">
<div id="contents" class="step" data-rel-x="0" data-rel-y="1500" data-scale="1"
data-bookmark-key-list="w" >
<h1>Choosing a treat</h1>
<ul>
@@ -60,7 +81,8 @@
<!-- Ice cream slides (3) -->
<div id="icecream" class="step" data-x="2000" data-y="2000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="contents icecream-pro contents crisps">
data-goto-next-list="contents icecream-pro contents crisps"
data-bookmark-key-list="7 u j" >
<h1>Ice cream</h1>
<ul>
@@ -73,7 +95,8 @@
<div id="icecream-pro" class="step" data-rel-x="0" data-rel-y="1000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="icecream icecream-con applepie crisps-pro">
data-goto-next-list="icecream icecream-con applepie crisps-pro"
data-bookmark-key-list="4 i j" >
<h1>Ice cream: Pro's</h1>
<ul>
@@ -85,7 +108,8 @@
<div id="icecream-con" class="step" data-rel-x="0" data-rel-y="1000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="icecream-pro crisps applepie-pro crisps-con">
data-goto-next-list="icecream-pro crisps applepie-pro crisps-con"
data-bookmark-key-list="1 o j" >
<h1>Ice cream: Con's</h1>
<ul>
@@ -99,7 +123,8 @@
<!-- Crisps slides (3) -->
<div id="crisps" class="step" data-x="3500" data-y="2000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="icecream-con crisps-pro icecream applepie">
data-goto-next-list="icecream-con crisps-pro icecream applepie"
data-bookmark-key-list="8 u k" >
<h1>Crisps</h1>
<ul>
@@ -112,7 +137,8 @@
<div id="crisps-pro" class="step" data-rel-x="0" data-rel-y="1000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="crisps crisps-con icecream-pro applepie-pro">
data-goto-next-list="crisps crisps-con icecream-pro applepie-pro"
data-bookmark-key-list="5 i k" >
<h1>Crisps: Pro's</h1>
<ul>
@@ -127,7 +153,8 @@
<div id="crisps-con" class="step" data-rel-x="0" data-rel-y="1000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="crisps-pro applepie icecream-con applepie-con">
data-goto-next-list="crisps-pro applepie icecream-con applepie-con"
data-bookmark-key-list="2 o k" >
<h1>Crisps: Con's</h1>
<ul>
@@ -140,7 +167,8 @@
<!-- Apple pie slides (3) -->
<div id="applepie" class="step" data-x="5000" data-y="2000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="crisps-con applepie-pro crisps icecream-pro">
data-goto-next-list="crisps-con applepie-pro crisps icecream-pro"
data-bookmark-key-list="9 u l" >
<h1>Apple pie</h1>
<ul>
@@ -152,7 +180,8 @@
<div id="applepie-pro" class="step" data-rel-x="0" data-rel-y="1000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="applepie applepie-con crisps-pro icecream-con">
data-goto-next-list="applepie applepie-con crisps-pro icecream-con"
data-bookmark-key-list="6 i l" >
<h1>Apple pie: Pro's</h1>
<ul>
@@ -165,7 +194,8 @@
<div id="applepie-con" class="step" data-rel-x="0" data-rel-y="1000"
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
data-goto-next-list="applepie-pro conclusion crisps-con conclusion">
data-goto-next-list="applepie-pro conclusion crisps-con conclusion"
data-bookmark-key-list="3 o l" >
<h1>Apple pie: Con's</h1>
<ul>
@@ -175,7 +205,8 @@
</div>
<div id="conclusion" class="step" data-rel-x="1000" data-rel-y="1000">
<div id="conclusion" class="step" data-rel-x="1000" data-rel-y="1000"
data-bookmark-key-list="q" >
<h1>Conclusion</h1>
<p>Can I choose all three ;-)</p>
@@ -186,7 +217,8 @@
<a href="https://www.flickr.com/photos/stevepj2009/6296334551">stevepj2009@Flickr</a> </p>
</div>
<div id="overview" class="step" data-x="3000" data-y="2000" data-scale="9" style="pointer-events: none;">
<div id="overview" class="step" data-x="3000" data-y="2000" data-scale="9" style="pointer-events: none;"
data-bookmark-key-list="z [" >
</div>
</div>

View File

@@ -325,7 +325,7 @@
A(Support for<br />diagrams)
B[Provided by<br />mermaid.js]
C{Already<br />know<br />mermaid?}
D(<a href=&quot;http://knsv.github.io/mermaid/index.html#usage&quot;>Tutorial</a>)
D(Tutorial)
E(Great, hope you enjoy!)
A-->B
B-->C
@@ -338,7 +338,7 @@
<h1><a href="http://docs.mathjax.org/en/latest/start.html">MathJax.js</a></h1>
<p>Use \(\LaTeX\), MathML or AsciiMath to properly show mathematical formula.</p>
<div class="notes">
Mermaid.js, likewise in a href="https://github.com/impress/impress.js/tree/master/extras">extras/</a>
Mermaid.js, likewise in <a href="https://github.com/impress/impress.js/tree/master/extras">extras/</a>
directory, draws SVG diagrams from a MarkDown-like syntax. To learn
more about it <a href="http://knsv.github.io/mermaid/index.html#usage">read the fine manual</a>.
</div>

View File

@@ -415,7 +415,7 @@ if ("ontouchstart" in document.documentElement) {
but it's optional - if not provided default transition duration for the presentation will be used.
You can also simply call `impress()` again to get the API, so `impress().next()` is also allowed.
Don't worry, it wont initialize the presentation again.
Don't worry, it won't initialize the presentation again.
For some example uses of this API check the last part of the source of impress.js where the API
is used in event handlers.

View File

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

25
package-lock.json generated
View File

@@ -262,9 +262,9 @@
}
},
"node_modules/async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
@@ -618,7 +618,6 @@
"dependencies": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -3125,9 +3124,6 @@
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"dependencies": {
"graceful-fs": "^4.1.6"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
@@ -4372,7 +4368,6 @@
"dependencies": {
"anymatch": "^1.3.0",
"async-each": "^1.0.0",
"fsevents": "^1.0.0",
"glob-parent": "^2.0.0",
"inherits": "^2.0.1",
"is-binary-path": "^1.0.0",
@@ -6177,7 +6172,7 @@
"node_modules/utile/node_modules/async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
"dev": true
},
"node_modules/utils-merge": {
@@ -6291,7 +6286,7 @@
"node_modules/winston/node_modules/async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
"dev": true
},
"node_modules/winston/node_modules/colors": {
@@ -6588,9 +6583,9 @@
"dev": true
},
"async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dev": true,
"requires": {
"lodash": "^4.17.14"
@@ -11506,7 +11501,7 @@
"async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
"dev": true
}
}
@@ -11600,7 +11595,7 @@
"async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
"dev": true
},
"colors": {

View File

@@ -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
<!-- data-bookmark-key-list allows an "inbound"-oriented style of non-linear navigation. -->
<div id="..." class="step" data-bookmark-key-list="Digit1 KeyA 1 2 3 a b c">
```
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.

View File

@@ -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:
*
* <!-- data-bookmark-key-list allows an "inbound" style of non-linear navigation. -->
* <div id="..." class="step" data-bookmark-key-list="Digit1 KeyA 1 2 3 a b c">
*
* 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 );

View File

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