Forward Thinking: Scriptable Webmaker Tools

Recently, Brett Gaylor wrote about the prospective future of Webmaker in 2013, discussing the topic of “Content Types”. Using a promotional video from the days of black-and-white GUIs, he drew an analogy between HyperCard and Webmaker ideology. The idea isn’t new — in fact, Ben Moskowitz had written previously about his own inspiration stemming from software like HyperCard and ResEdit. But Brett’s video really drove home the point for me.

While developing all-encompassing UI’s for tools is ideal, it’s also very hard. However, giving users the ability to script in the context of a tool alleviates much of the pain in designing the ultimate extensive UI. Moreover, it incrementally teaches the user the memes which stir around the tool and how to use them expressively to become super-users.

Naturally, I started hacking away at a prototype of this type of functionality in Popcorn Maker.

Originally, one of the goals of Popcorn Maker was to show the user the Popcorn code being built for them with the tool. At every turn, the user should be able to open the hood and look at how their project’s code changed to deliver what they see. Over the course of last year though, as Popcorn Maker really grew legs, that idea was supplanted by other inexorable demands more central to the comprehensive functionality of a web app — all the things usually neglected at the beginning of a fast-paced project born from a prototype, like dependency loaders, layout systems, build environments, sane architecture, bugs, bugs, and bugs.

Instead, Popcorn Maker boasts with a pretty versatile UI system. It’s not too hard on the eyes either. But, after a bit of regular usage, it’s easy to see where digging your hands into a script is sometimes preferable — especially for an experienced programmer.

image

For example, using the plugins that ship with Popcorn Maker, the timeline has exactly one control flow. In other words, there’s no way for decisions expressed by the user to affect the content of the presentation itself.

image

They can use the play/pause button, click on images and links, skip around the video, but the video still lacks the elegance of interactivity that can be attained with a bit of customization.

image

If I want to prepare a Popcorn Maker project that will show content contingent upon the number of prior visits by the user the project’s content needs to be somewhat intelligent. That sort of functionality could be built directly into the plugins, but it’s hard for plugin designers to define everything that should or should not be possible, and present some configuration options to help.

Still, using an expressive UI is favourable over writing everything out by hand, so meeting somewhere in the middle is best. And, of course, this idea has pervaded software even earlier than Hypercard. From Adobe’s creative product suite to modern game engines, there is a distinct and purposeful line between the parts of software architecture that are meant to be malleable, and the relatively steadfast parts that support them. Nobody wants to write NPC scripts in C++, nor is anybody looking to write pixel shaders with Haskell. Large projects provide several important vectors for contribution at different levels, and depending on the piece of the project or the type of work, a user or contributor must choose which is most appropriate (or is forced to through architectural decisions).

However, with the advent of intrinsically open, dynamic languages like JavaScript, there needn’t be such a stark divide between code that is meant to run the app itself and code that is meant to run inside of or with the app. Many other projects have similar thinking behind them, and while still being subject to a compilation process, even Processing.js sketches are almost JavaScript. A scripting interface for Popcorn Maker would be free of prior language restrictions though, so user-generated scripts that run inside of Popcorn Maker can simply be JavaScript! By extension, learning to script inside of Popcorn Maker will teach the user JavaScript. And scope restrictions are likely more helpful than not, giving the user a small box to think about, and forcing them to be creative when they want something more.

To test all of this thinking in a prototype, I created a branch of Popcorn Maker with a rudimentary scripting environment for the Text and Image plugins.

image

The Text and Image editors have a “Scripts” tab which exposes some opportunities for the user to add some extra customization or flexibility. For now, scripts are chained to specific events, like “onStart” and “onEnd” which are executed during the respective “start” function and the “end” functions of the plugins.

Now, if I want to add some programmatic difference to a specific track event without touching the plugin implementation, I can simply add some JavaScript to the provided CodeMirror textbox. Notice the mention of keywords like “event” and “popcorn”, which would not normally be accessible to globally-scoped scripts. These scripts are wrapped in a special scope providing convenient access to certain objects like Butter (butter), the current track event (event), and Popcorn (popcorn). Since this is just plain JavaScript that the browser is running, I can even use the DOM event system to attach an onclick listener to move the scrubber to 5 seconds when the user clicks on the track event’s target. (If you’re familiar with older versions of Macromedia Flash, this will seem natural.)

Scripting of this sort doesn’t only benefit Popcorn Maker’s users. Developers at all tiers often enjoy the opportunity to talk to the app at a higher level when implementing features. In the same branch, I made some potential improvements to the layout system by applying the idea of a mixin. In Popcorn Maker’s layout system mixins can be used to describe a piece of UI that the developer doesn’t need or want to know everything about. As an example, here’s the text editor rewritten with “buttermixin”s.

<buttermixin type=”editor” editor-classes=”default-editor”>
  <h1>Text Editor</h1>
  <buttermixin type=”editor-tabs”>
    <buttermixin type=”editor-tab-item” tab-classes=”basic-tab butter-active”>Basic</buttermixin>
    <buttermixin type=”editor-tab-item” tab-classes=”advanced-tab”>Advanced</buttermixin>
    <buttermixin type=”editor-tab-item” tab-classes=”scripts-tab”>Scripts</buttermixin>
  </buttermixin>
  <buttermixin type=”editor-body” body-classes=”butter-tabs-spacing”>
    <buttermixin type=”editor-body-content-container”></buttermixin>
    <buttermixin type=”editor-body-content-container” classes=”advanced-options display-off”></buttermixin>
    <buttermixin type=”editor-body-content-container” classes=”scripts display-off”></buttermixin>
  </buttermixin>
</buttermixin>

When Popcorn Maker starts, this code is exploded into another piece of HTML incorporating predefined UI widgets. Instead of needing to know how to structure the DOM for an entire editor, one <buttermixin type=”editor”></buttermixin> will create most of the important parts that Popcorn Maker expects in order to display an editor correctly within the app. With features like this one, prototyping is far simpler because the time to look up specific CSS properties and DOM structure is reduced, and mistakes are mitigated since forgetful boilerplate syntax is inserted automatically.

The app needs advancements like these to continue to grow while maintaining easy access points for developers and designers. Using a real templating system may still be a better approach, but this was an interesting experiment in continuing to use as much native HTML and JavaScript as possible in Popcorn Maker.

I love being able to exploit flexible systems like the ones available through browser technology to implement architectural features. The benefits are often felt throughout the code base and its developers. I’ve only begun to carve away at the landscape of high-level scripting techniques available to web apps like Popcorn Maker. When I’ve got a more punchy example (perhaps a screencast) of these features, I’ll certainly put it up.

  1. secretrobotron posted this

twitter.com/secretrobotron

view archive



Ask me something.

Submit something.