mozilla-b2g/gaia — pull request #18909 by jrburke (2014-05-03 06:37:33+00:00)
Title: Bug 1005446 - [email] try custom elements for cards

This is a speculative experiment about using custom elements for the email app's cards.

## Goals:

* Try out custom elements now that they are available in the platform (at least for certified apps for now).
* Use a custom element approach that uses mixins that help with auto-wiring DOM elements in the template to the custom element and for binding events to those sub-elements. So now the cards should not need to do domNode.getElementsByClassName or addEventListener for the simple cases.
* Take the opportunity to remove the "mode" and "tray" concepts from the Cards implementation to simplify it.
* Try out native Promises inside alameda.
* Make sure `evt` async notifies listeners on an emit. I do not expect any drastic breakage, but given that it does change the execution model a bit, good to do early as part of a bigger experiment like this.

## Notable bugs

Since I removed the tray and mode parts from the Cards implementation, I put in a hack to get from the folder_list back to the message_list: you need to click **only** on the hamburger menu icon.

I am counting on the email drawers to land for that to work out. However, worse case I can add a little bit back to get this to work, likely doing the same trick as in the drawer case: the folder_picker would have a transparent background and clicks off to that side would just trigger a navigation back.

## Implementation

The custom element mixin approach uses the one from [jrburke/element](https://github.com/jrburke/element): an `element` and `template` loader plugin that handle mixing in objects and a template to form the final prototype that is given to document.registerElement. See that other repo for more information.

Also, I removed prim from alameda and use the native Promise directly. With that, I convered `evt`'s emit() to use Promise.resolve() to dispatch the emit, so that we get a proper async notification to listeners.

With these changes I broke up mail_common into specific modules for each piece. So, no more mail_common.

I converted all the cards over to this approach, and it appears to be working well. I put up an app zip here if you want to try it out without fetching the branch:

http://jrburke.com/work/gaia/email-wc-1.zip

## Still left to do

* hook up the cookie cache. In some ways this should be "easier" as the platform should auto-upgrade any injected custom element once its definition is registered, but need to try it out to be sure.
* We could look at removing the 'tmpl!' dependencies, or convert them to 'template!' ones, but not sure it is worth the payoff yet for such tiny pieces of typically view-only HTML.
* I would like change the module IDs to better match the custom element tag names. Right now 'cards/message_list' module ID ends up as 'cards-message-list' custom element. I would rather we refer to the module ID of 'elements/message-list', and then have a prefix configured with the `element` loader to know about the `elements` part, and register the element as 'message-list. Maybe `element` should take a map or something else, so that if there are building blocks that are custom elements, we could load those correctly from a different module ID prefix.
* Speaking of building blocks custom elements: the `template` loader plugin already knows how to parse out other custom elements referenced in a template and load them as dependencies, so my hope is that we can support building blocks without needing to use HTML Imports because HTML Imports are a bit wonky when you do have a module system, and HTML Imports is currently incomplete anyway.

## Next steps

Get feedback from the team. As this was a bit of an unplanned experiment, I do not want to derail people too much, so will not be formally flipping the feedback flags yet.

However, I believe I converted all the code over, and I think we could land this pretty easily. We would definitely want some more QA time on it in case a binding port was missed in some way, but given that this is the start of a feature cycle, it would be a great time to do it.

I would want to land the email drawers though before calling this work complete, as I cheated a bit assuming it was there, so that I could remove more of the Cards stuff.

I think this is also a nice way to step into custom elements without rethinking the entire email front end. Most of the internal logic in the cards and the Cards module are the same, just the wiring is done differently, and some boilerplate in the constructors has been removed in favor of data- attributes.