Popcorn Maker 0.1

bobby

4

After my recent stint in Europe for the Mozilla Festival and MozCamp I had the opportunity to reflect on the development environment of Popcorn Maker, courtesy of the 8 hour flight from Berlin to New York. The result is a version of Popcorn Maker which can be proudly labeled as 0.1, and very friendly to developers.

 

History Lesson: Butter

Butter Butter was an initial exploration of making a GUI for producers hoping to use popcorn.js for their projects. The app enjoyed some success, but it was eclipsed by the need to expand the app in different directions, which I have written about previously. Like most promising experiments, it needed to be rewritten to be the powerful app we hoped it would become.

Consequently, there was a lot of discussion about how to engineer the experience which was to become Popcorn Maker, which Brett and Ben detailed in their post, Designing the Popcorn Maker. In short, the current goal is to create a web app which encompasses the same ideas as Butter, but makes traditional content producers (usually of the film persuasion) comfortable by drawing memes from other popular pieces of software. However, a functioning web app is only a piece of the puzzle, since harnessing community involvement is a very powerful concept. Eventually, users will be able to use Popcorn Maker like they use WordPress – by downloading and installing the app on a machine of their choice – but with unique sharing capabilities and editing opportunities, like publishing your popcornizedtm template which might be a remix of something like a youtube video page.

Require Saves The Day

Butter - Popcorn Maker The subsequent struggle to design an acceptable user experience and its contention with pace of development and fluctuating feature requests hasn’t offered the opportunity for Popcorn Maker’s codebase to settle. As a result, Popcorn Maker’s developers have had to suffer through a poor debugging experience and a sub-optimal development environment.

Now, that has all changed. Some geniune thinking time and my recent exploits inside Paladin with James Burke, the creator of require.js, has changed Popcorn Maker for the better – for developer and users alike.

Using require.js, I was able to split up Butter’s core and constituent modules into several files respectively. require’s module system makes this process natural and provides a method for producing dependency chains. So, Butter’s core relies on the existence of several smaller modules like Media, Track, and TrackEvent, while Butter’s Timeline module depends on some of the same (plus some others). In other words, dependency chains let a module rely on other modules which may be already shared amongst others still. Of course, this is nothing new to traditional developers who get to use #import to solve a similar problem.

Now, developers are able to isolate and fix bugs without involving a compilation process every time they make a change (since Butter is best suited as a library inside of Popcorn Maker).

Onward: To 0.1

Popcorn Maker + Butter Setup Since Popcorn Maker is an app that wraps Butter, developers can contribute from several perspectives:

  • Popcorn Maker: developing the app itself (UI, storage, exporting, etc.)
  • Templates: building general-purpose Butter templates to let users jump into editing a powerful popcorn experience quickly
  • Editors: providing html-based editors for popcorn plugins which would benefit from specific UI (e.g. Google Maps)
  • Butter: enhancing the core of Butter to fix bugs or provide better functionality or compatibility (standards like to change)

The beauty of the approach we’ve taken in 0.1 is that these elements are as decoupled as possible because they are actually separate require projects. Then, it’s no problem at all to have them share components, and they can depend on each other to provide a nice unidirectional development flow.

Part of the magic is a pattern which James has worked on that circumvents the data-main attribute traditionally attached to a require.js script tag. Instead, a script like this is referenced (in this case, butter.previewer.js):

(function () {
    // Stub for has function.
    function has() {
        return true;
    }

    if ( has( 'source-config' ) ) {
        // Get the location of the butter source.
        // The last script tag should be the butter source
        // tag since in dev, it will be a blocking script tag,
        // so latest tag is the one for this script.
        var scripts = document.getElementsByTagName( 'script' ),
        path = scripts[scripts.length - 1].src;
        path = path.split( '/' );
        path.pop();
        path = path.join( '/' ) + '/';

        document.write( '<script src="' + 
          path + 
          '../../external/require/require.js"></' +
          'script>' );

        document.write('<script>' + 
          '(function(){' + 
          'var ctx = require.config({ ' + 
            'baseUrl: "' + path + '../",' +
            'context: "butter.previewer",' +
            'paths: {' +
              // Paths are relative to baseUrl; Notice the commas!
            '}' +
          '});' +
          'ctx(["previewer/previewer"])' + 
          '})()' +
        '</script>');
    }

    var ButterTemplate = function() {
      if ( !ButterTemplate.__waiting ) {
        ButterTemplate.__waiting = [];
      } //if
      ButterTemplate.__waiting.push( arguments );
    }; //ButterTemplate

    if ( !window.ButterTemplate ) {
      window.ButterTemplate = ButterTemplate;
    } //if

}());

This pattern, which writes its own require.js-specific script tag when necessary (when not compiled), takes advantage of require contexts (returned from a call to require.config()), and is easily generalized. In fact, it’s used to load event editors, and butter itself. In other words, Butter (and Popcorn Maker, by extension) contains several require projects, each of which can be compiled to provide a minified version. Butter is actually a collection of libraries which can be included independently to provide functionality specific to things like Templates or Event Editors.

So, to create a simple Butter Template, all you need is this:

<html>
  <head>
    <script src="../../lib/popcorn/popcorn.js"></script>
    <script src="../../lib/popcorn/popcorn.subtitle.js"></script>
    <script src="../../butter/src/previewer/butter.previewer.js"></script>
    <script>
      /* Uncomment to provide custom functionality
        ButterTemplate(function() {
          // namespace has loaded; create your custom template here
        });
      */
    </script>
  </head>
  <body>
    <div id="main" data-butter="media"></div>
    <div id="subtitle-container" data-butter="target"></div>
  </body>
</html>

Similarly, to create an Event Editor, you need this:

<html>
  <head>
    <script src="../../lib/popcorn/popcorn.js"></script>
    <script src="../../lib/popcorn/popcorn.subtitle.js"></script>
    <script src="../../butter/src/previewer/butter.previewer.js"></script>
    <script>
      /* Uncomment to provide custom functionality
        ButterTemplate(function() {
          // namespace has loaded; create your custom template here
        });
      */
    </script>
  </head>
  <body>
    <div id="main" data-butter="media"></div>
    <div id="subtitle-container" data-butter="target"></div>
  </body>
</html>

Finally, Butter can be imported in the same way (in Popcorn Maker, for example):

<html>
  <head>
    <title>Popcorn Maker</title>
    <script type="text/javascript" src="lib/require/require.js"></script>
    <script type="text/javascript" src="butter/src/butter.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
  </head>
</html>

Notice the extra require inclusion here, which is necessary only because Popcorn Maker is also a require.js project. This way butter.js does not depend on Popcorn Maker to include require.js, and every layer of the project can be nicely compiled.

To reiterate, the very best part is that there is no need to re-compile Butter if a change needs to be made. require.js will let us compile the project only when we want to distribute it.

Enjoy

So, have a look at the app at mozillapopcorn.org/maker(on Monday), or clone the source for yourself to see what you can do locally. As always, reporting bugs is paramount, and is worth almost as much as fixing them. Check out our 0.1 milestone on our lighthouse project, where you’ll almost certainly find a plethora of things to do.

4 responses

  1. Pingback from The Various Reasons for Migraine Head pain | How To Get Rid Of Eczema Fast on ::

    […] is certainly still a long way to go before this condition is understood and effectively treated.It can be a fair guess that every person has suffered the distress of a headache. Whenever it comes …ce a month. I am so thankful they stopped because they were exceptionally painful. There's much to […]

  2. Pingback from Shakespeare goes social: Mozilla Popcorn in the classroom | Mozilla Popcorn on ::

    […] Post navigation ← Previous […]

  3. dert wrote on ::

    SesliFul.Com,SesliFul, Seslichat,Seslisohbet,Kamerali Chat,Sesli …
    http://www.sesliful.com/SesliFul.Com,SesliFul, Seslichat,Seslisohbet,Kamerali Chat,Sesli chat, … RSS Feed Abone olun.. Sesli Sohbet Ve Sesli Chat Konularimiz …

  4. Jenny wrote on :

    I think guides like this are really handy – I pieced all of my knowledge together a bit at a time and think it would have been much easier if I’d just worked through it with a tutorials that taught everything. Bleacher Seats