Toward Webmaker Custom Elements, Web Components

I've been thinking quite a bit lately about how Webmaker can take advantage of the work being done on Web Components and Custom Elements.  I tasked Pomax with doing some research and prototyping, and the results have been encouraging.  I wanted to say something about my current thinking and what we might do.

One of the successes we had with Popcorn.js was that it became really easy to create plugins that could take care of the complexities of working with third-party APIs and showing web content dynamically, and linearly in time based on media resources.  Consider the Google Map plugin, which allows one to specify a location, map type, etc. and have a map dynamically load within the provided container div:

var p = Popcorn( "#video" )  
       start: 5,  
       end: 15,  
       type: "ROADMAP",  
       target: "map",  
       lat: 43.665429,  
       lng: -79.403323  

We've seen people make all kinds of plugins to simplify the use of more complex APIs like this.  Often it means dynamically loading some script, setting up a div or iframe, adding an element with a particular class name or id, and applying some styles.

There are a few things I've always wanted to improve about it, though.  First, how to properly combine a bunch of styles with a plugin.  Currently a plugin like the googlemap one is just JavaScript.  In reality, you almost always want a mix of JS and CSS, and doing CSS in script is not ideal; nor is having to manage the loading of two files per plugin (*.js, *.css).  A second issue is that these plugins are tightly bound to Popcorn, which is fine if you're time-based experiences, but not so good for a normal web page.

With custom elements, we can solve a lot of these problems.  First, a custom element is a simple HTML file containing the definition of a new element, any associated styles, and scripts.  I use it in my page by loading it via a link:

<link rel="component" href="webmaker-components.html">

I love the simplicity of this method of packaging and loading new elements.  This file can include one ore more new elements, making it possible to do some server-side bundling for dynamic builds--imagine loading components a, b, c, and d via,b,c,d.

Now in your markup it's possible to take our Google map from above, and rewrite it like so:

<webmaker-map start="5" end="15" location="Maruyama Zoo">  

Here content attributes on the custom webmaker-map element provide a way to indicate start and end times, and a location to pass thorugh to Google's API.  However, while I can specify timing info, I can also leave it off, indicating that the map should always be visible:

<webmaker-map location="Maruyama Zoo"></webmaker-map>

By moving the functionality of the Google Map plugin to a custom element, we've made it possible for it to be used in any web context or tool.

You can see this in action in Pomax's demo page: first with timing info, second without as a static web page.  View the source of both pages.  First off, notice how little code there is, and more, how it's all markup vs. script.  You might be wondering why this works at all, since browser vendors are still defining and implementing the spec.  You'll see that this uses a polyfill to give us the ability to play with things now.

This model of providing functional-units to authors is also exciting in the way it lets us mix and match depending on the needs of the individual.  For example, lets say you want to add comments to your page.  One option would be to use Facebook's comments plugin, another would be to use Disqus's embed.  Both can be wrapped into custom elements, and users can choose.  I did just that for Facebook's comments: code (view source) and demo (scroll to the bottom).  Here I use


to add the functionality I want.  No scripting of any kind, which means that this becomes accessible to so many more web makers, for whom coding is beyond their reach.  Whenever we can reduce complexity like this, we should do it.

I think moving toward HTML-based custom elements vs. script-only plugins is going to make a huge difference.  It's going to mean that it's easy to integrate with existing tools and workflows, easy to find and use them (they are just web pages, after all), and most of all, easier for non-devs to use all these amazing APIs and services, which require coding.

Pomax and Matt have already started work to convert Popcorn Maker to use this, and are making good progress.  I'm looking forward to building more pieces of the Webmaker tools and gallery infrastructure using these same methods, and I'll write more about or progress later when I have something to show.