regebro / impress-console

Speaker notes for impress.js
MIT License
133 stars 32 forks source link

Plugin API for impress.js #19

Open henrikingo opened 8 years ago

henrikingo commented 8 years ago

Hi @regebro

First of all, let me thank you for creating impressConsole. I use it a lot and like it!

If you've followed impress.js itself, you might have noticed that there's some activity to rejuvenate the project. In particular, we've been working on adding unit testing as well as a plugin api to allow for adding new cool features in a modular way.

I have created a proposal for a plugin api at https://github.com/henrikingo/impress.js/blob/myfork/src/plugins/README.md

I should note that this is just in my fork yet, and not in official impress.js yet. Otoh I'm not aware of any alternative proposals either, nor anyone working on one. Also, for the parts that I will discuss here, related to impress-console, it's worth pointing out that these features actually do exist in upstream impress.js since years ago. That is to say, it is feasible for you to implement these changes if you think what I'm proposing makes sense.

In my fork you can see some plugins under src/plugins/. I've also created a folder extras/ for some additional plugins, that aren't part of the set enabled by default, but that can be used by adding them with their own <script src="extras/3rd-party-plugin.js"> tag. I've already added impress-console there as a git module. In your case the main reason I've added impress-console as an extra plugin instead of being enabled by default, is that impress-console doesn't conform to all the requirements of the api - which of course is reasonable as the api didn't exist until 2 weeks ago.

The README above describes the plugin API. Impress-console would be categorized as a GUI plugin.

As I would like impress-console to be moved into the "official" set of plugins under src/plugins/, and there it would be enabled by default, I will list here the changes that would be needed to get there. I'm happy to create a pull request for these changes, if you're interested in implementing these changes. Like I've said, integrating with impress.js with this method is possible also with the old/upstream impress.js codebase, so you could safely add this to the main impress-console repo.

Proposed changes

initialization

The main requirement in the new api, is that plugins should not themselves expose any global variables. In the case of impress-console, this means that the current way of initializing with impressConsole().init() is not "allowed".

The proposed way for most plugins in the new api is to catch the impress:init event triggered by impress.js after its own initialization is complete:

document.addEventListener("impress:init", function (event) {
    impressConsole().init()

With doing this, impressConsole would automatically be initialized together with impress().init().

Of course, for backwards compatibility, you could still continue to expose the old API, which could print a deprecation warning:

init = function() {
    console.log( "impressConsole().init() is deprecated: impressConsole is now integrated with impress.js plugin api, and is automatically initialized together with impress.js." );

impressConsole().open(), etc

If you think you need to continue to expose the full impressConsole() api, that could similarly be allowed as an exception for backward compatibility.

However, I propose that similar mechanisms, such as using events and event listeners are introduced alongside them as well. For example, if I need to programmatically open impress-console, maybe I could trigger the event impress:console:do-open, which impressConsole is listening on. Note that the prefix impress:console: adheres to a namespace rule defined in the plugin api README.

CSS

One requirement for the default plugin set is that they must be self contained, and not depend on any external js, css, html or image files. (For one thing, when the plugin is compiled into the big js/impress.js file, it must not assume any relative paths to other files.)

In impressConsole.js that is already true for the HTML, which is a string inside the javascript. However, that HTML then links to a CSS file.

My proposal here would be to take the default CSS and integrate into a <style> tag inlined in the HTML.

Note that it is still possible to allow the user to specify his own CSS file. It's just that by default you cannot depend on, nor assume that you know the location of, some external CSS file. Of course, since impress().init() is no longer called by the user, that would have to be some other method than the current one.

For example, it is allowed for plugins to take input via their own html attributes, properly namespaced:

<div id="impress" data-impress-console-css="...">

auto-play

I don't think this is officially part of impressConsole.js itself, but I've seen some presentations that integrate impress-console use the following html attribute to automatically open the presenter console:

<div id="impress" auto-launch="true">

Again, using such attributes is allowed, but to follow a standard namespace API, should be changed to

<div id="impress" data-impress-console-autolaunch="true">
or
<div id="impress" data-impress-console="auto">

Let me know if you're interested in a pull request that would implement the above changes. (To be clear, I'll repeat that it would also preserve backwards compatibility.)

regebro commented 7 years ago

Hi, sorry for the delay in me looking at this. The last year has been insane.

I don't know much about Javascript, really, and if the best way to deal with plugins is to "compile" a js file containing impress.js + plugins, then so be it. But I don't like it, that feels iffy. If your proposal gets accepted and impressConsole becomes a default plugin, then that becomes less of a problem for me as I don't have to deal with it. :-)

Otherwise it looks good. If your proposal gets accepted we should of course update impressConsole to listen to the init event instead.

henrikingo commented 7 years ago

Hi @regebro

Thanks for commenting. It is good to have your view.

I was wondering about the "compile" as well (because I'm really a database consultant) but the desire was to have multiple small files for developers (and in particular, ability to add or remove files if you want / don't want some feature) while of course having only a single file to load in the browser. This seems to be the common way to do it (as evidenced by there existing a node module to do exactly this as well).

Unfortunately upstream impress.js has remained pretty stagnant (now 7 months later compared to above). @bartaz (the creator of impress.js) looked a little at my work in private - I don't know how superficially - and kind of ok'd it, but there hasn't been any meaningful public discussion from him or anyone else. There's also no alternative activity to build a plugin api, or any code activity at all for that matter. So I just kept on adding plugins, both for my own needs and most of the open tickets in the upstream impress.js backlog. (Btw, I'm also making progress on a GUI editor at https://github.com/henrikingo/impressionist, but it's still about 3 commits away from being able to actually open, edit and save a working impress.js presentation.)

If it is possible to implement above changes in a way that would be backward compatible with current impressConsole, I will send you a pull request soon. Since that would be completely backwards compatible, there shouldn't be a risk in you including it - well, at least I think it is worthwhile for you to look at such a PR and see what you think.

regebro commented 7 years ago

Yeah, I have been wondering if I should switch to jmpress.js instead, but last time I tried it it was very unstable. At least some things are happening with impress.js now, there\s been a new release.

henrikingo commented 7 years ago

...at least it seems to have issues updating the #step-id in the url. Thanks for the link though, I wasn't aware of it. Always nice to know what's going on, even if my idea is not to rewrite impress.js, simply continue to work on the vision stated by its creator.

henrikingo commented 7 years ago

There's now a pull request. Have fun!