Open quilicicf opened 4 years ago
This is a PR show-casing one solution to the problems above :point_up:
There is still the issue of the speaker notes to tackle but it's a good start IMO.
Work has started in PRs https://github.com/hakimel/reveal.js/pull/2627 and https://github.com/hakimel/reveal.js/pull/2633.
Stay tuned.
So, last part of the plan is about plugins.
To make reveal.js fully bundler-friendly we need all the core plugins to be injectable with the new system implemented in PR 2627.
For most plugins, this is going to be super easy bu the speaker notes plugin is gonna be harder so let's focus on this one.
The speaker notes need to be loaded from the main page (on the same URL as the main presentation) if we want to bundle the whole presentation in a single file.
This means that the URL needs to specify which reveal presentation to connect to and that the presentation should open in notes
mode. I'm thinking something like: http://localhost:8080/my_presentation.html?speaker-notes-for=${presentationId}
.
When the presentation is open in notes mode
, it should inject the relevant HTML/CSS and initiate the connection to the original presentation.
Another pro of this solution is that the slides are by default in the notes presentation, only some HTML injection and theming need to be done to show the speaker notes.
I think some other improvements could be gained with such a solution:
Reveal.initialize
I think these modifications might prove pretty tough though and I don't want to start implementing something that has no chance of getting merged so I need your opinion on this @hakimel.
WDYT?
I started working on plugin bundling a few days ago. The new recommended way to include plugins will be to use ESM, for example:
import Reveal from '/js/reveal.js';
import Zoom from '/plugin/zoom/zoom.js';
import Notes from '/plugin/notes/notes.js';
import Search from '/plugin/search/search.js';
import Markdown from '/plugin/markdown/markdown.js';
import Highlight from '/plugin/highlight/highlight.js';
let deck = new Reveal( document.querySelector( '.reveal' ), {
controls: true,
progress: true,
dependencies: [ Zoom, Notes, Search, Markdown, Highlight ]
});
deck.initialize();
I still want to support IE11 too, so I'm transpiling es5 versions of each plugin that can be included using the old dependencies
syntax if browser support is important:
dependencies: [
{ src: 'dist/plugin/markdown.js' },
{ src: 'dist/plugin/highlight.js' },
{ src: 'dist/plugin/notes.js' }
]
A lot of things are still changing but once this is done I'll take a closer look at your proposal for how we can best associate the notes window.
Awesome thanks! I'll let you take a look then. In the meantime I'd like to propose a new improvement which I can submit a PR for.
The main issue I'm facing with Reveal right now is that the UX for bootstrapping a new presentation is not exactly straight-forward. I always end up copy-pasting the last one and resetting it.
I'd like to propose a CLI tool for bootstrapping a new presentation that would allow the user to select the plugins/themes they want to install and generate the index.html
+ app.js
+ package.json
with all required dependencies.
I think the best place for such a tool is this repository because I'd be able to list the core plugins/themes from the source and it would be easier to keep the CLI compatible with potential changes in here.
WDYT?
Hi again!
I've played with the new imports and tried a lot of approaches to try and get a single, self-sufficient, HTML file at the end of my build and I struggle with the Notes plugin.
Trying to inject all the JS code of the presentation in a script
tag results in tripping the HTML parser when the Notes plugin is used.
Basically, the plugin does something like this:
speakerNotesWindow.document.write('<html>...<script>...</script>...</html>');
The problem is that the HTML parser doesn't understand that the closing script
tag here is in a JS string and it closes the parent script
tag which completely breaks the page :scream:
An illustration of the problem below. Note that the closing script
tag in the JS string is colored as valid HTML code because the HTML parser is tripped.
<html>
<script type="module">
document.write('<script>console.log("whatever");</script>');
</script>
</html>
A simple way to fix this would be to follow this piece of advice and split the tags like this:
document.write("<"+"script>...</"+"script>");
Which should be easy to add in the current scripts, a simple source.replaceAll('<script>', '<"+"script>').replaceAll('</script>', '</"+"script>')
would do.
This is a bit hacky but not terrible either and it solves the issue.
Note 1: I can open a PR to implement it or another solution if need be. Note 2: Found a duplicate issue, will comment there too.
What am I trying to do
I'm trying to use a bundler (parceljs in my case) to generate a self-sufficient HTML file containing a Reveal.js presentation.
This would have a lot of pros:
How is my presentation structured
Reveal.js is installed in my project via
npm
.I have an
index.html
file containing my slides that imports a JS file.The JS file imports the CSS, plugins etc... and initializes Reveal.js.
The issues I am facing
Reveal.js is not currently bundler-friendly for a couple of reasons described below.
Plugins
Reveal.js assumes the plugins are served over HTTP and it loads them from their source by injecting a
link
element withsrc='relativeUrlSubPathToPlugin'
.This can't work if my presentation is in a single HTML file.
In my case, given I use a bundler, I'd expect to retrieve the plugin (the object with function
init
) via an ESM import and directly provide it to Reveal.js.I have tried to hack around the injection process with no avail.
PDF printing
I would like to (ideally) embed both
paper.css
andpdf.css
in my presentation so that people can print it the way they want once bundled.They overlap if both included in the HTML file (and wreck the presentation).
This means that I have one of two solutions (at least that come to mind):
import pdfCss from 'reveal.js/print/pdf.css'
) and inject it (conditionally) myself in the HTML, depending on the query parameter?print-pdf
body
for example. Which would be done depending on the query parameterDoes that make sense?
I'd be happy to help with any implementation if you are convinced this would bring value to the project (and I hope it does).