More jsdom

More jsdom

# Sandboxes

This module provides a method for creating sandboxed DOMs (using
[jsdom](https://github.com/tmpvar/jsdom)). It augments the DOM with a
functional [WebSocket](http://en.wikipedia.org/wiki/WebSocket) using
[ws](https://github.com/einaros/ws/), and generally makes spinning up arbitrary
DOM contexts a pleasant breeze.

    config = require 'config'
    Promise = require 'bluebird'
    WebSocket = require 'ws/lib/WebSocket'

    errors = require 'errors'
    logging = require 'logging'

    {jsdom} = require 'jsdom'

Hax: Fix document.domain since jsdom has a stub here.

    {HTMLDocument} = require 'jsdom/lib/jsdom/living'
    Object.defineProperties(
      HTMLDocument.prototype
      domain: get: -> 'localhost'
    )

This class is responsible for creating and cleaning up DOMs, and provides
some methods to inspect the state of the document.

    exports.Sandbox = class Sandbox

## *constructor*

*Spin up a DOM.*

      constructor: ->

        @_cleanupFunctions = []
        @_window = null

## Sandbox#close

*Close a DOM.*

      close: ->

If the window is already gone, nope out.

        return Promise.resolve() unless @_window?

Run all the registered cleanup functions.

        Promise.all(
          fn() for fn in @_cleanupFunctions

Suppress cleanup errors.

        ).catch(->

Actually close the window and null it out.

        ).finally =>

          @_window.close()
          @_window = null

## Sandbox#createDocument

* (string) `html` - The HTML document.
* (object) `options` - An options object which may contain the following
  values:
    * (string) `cookie` - Cookie string.
    * (string) `cookieDomain` - The domain the cookie applies to.
    * (string) `url` - The canonical URL of the HTML document.

*Create a DOM from an HTML document.*

      createDocument: (html, options = {}) ->

Set up a DOM, forwarding our cookie.

        document = jsdom(
          html

          cookie: options.cookie
          cookieDomain: options.cookieDomain ? 'localhost'

          url: options.url ? "http://localhost:#{config.get 'packageSettings:shrub-http:port'}/"
        )
        @_window = window = document.defaultView

Capture "client" console logs.

        for level in ['info', 'log', 'debug', 'warn', 'error']
          do (level) -> window.console[level] = (args...) ->

Make errors as detailed as possible.

            for arg, i in args
              if arg instanceof Error
                args[i] = errors.stack arg
              else
                arg

            console[level] args...

Hack in WebSocket.

        window.WebSocket = WebSocket

        sandbox = this
        new Promise (resolve, reject) ->

When the window is loaded, we'll reject with any error, or resolve.

          window.onload = ->

            for documentError in window.document.errors ? []
              if documentError.data?.error?
                error = new Error "#{documentError.message}\n#{errors.stack documentError.data.error}"

            if error?
              reject error
            else
              resolve sandbox

## Sandbox#emitHtml

*Emit the document as HTML.*

      emitHtml: -> """
    <!doctype html>
    #{@_window.document.innerHTML}
    """

## Sandbox#registerCleanupFunction

* (function) `fn` - The function to run when the sandbox is closing.

*Register a function to run when the sandbox is closing.*

      registerCleanupFunction: (fn) -> @_cleanupFunctions.push fn

## Sandbox#url

*The current URL the sandbox is at.*

      url: -> @_window.location.href

# Sandboxes

This module provides a method for creating sandboxed DOMs (using
[jsdom](https://github.com/tmpvar/jsdom)). It augments the DOM with a
functional [WebSocket](http://en.wikipedia.org/wiki/WebSocket) using
[ws](https://github.com/einaros/ws/), and generally makes spinning up arbitrary
DOM contexts a pleasant breeze.

    config = require 'config'
    Promise = require 'bluebird'
    WebSocket = require 'ws/lib/WebSocket'

    errors = require 'errors'
    logging = require 'logging'

    {jsdom} = require 'jsdom'

Hax: Fix document.domain since jsdom has a stub here.

    {HTMLDocument} = require 'jsdom/lib/jsdom/living'
    Object.defineProperties(
      HTMLDocument.prototype
      domain: get: -> 'localhost'
    )

This class is responsible for creating and cleaning up DOMs, and provides
some methods to inspect the state of the document.

    exports.Sandbox = class Sandbox

## *constructor*

*Spin up a DOM.*

      constructor: ->

        @_cleanupFunctions = []
        @_window = null

## Sandbox#close

*Close a DOM.*

      close: ->

If the window is already gone, nope out.

        return Promise.resolve() unless @_window?

Run all the registered cleanup functions.

        Promise.all(
          fn() for fn in @_cleanupFunctions

Suppress cleanup errors.

        ).catch(->

Actually close the window and null it out.

        ).finally =>

          @_window.close()
          @_window = null

## Sandbox#createDocument

* (string) `html` - The HTML document.
* (object) `options` - An options object which may contain the following
  values:
    * (string) `cookie` - Cookie string.
    * (string) `cookieDomain` - The domain the cookie applies to.
    * (string) `url` - The canonical URL of the HTML document.

*Create a DOM from an HTML document.*

      createDocument: (html, options = {}) ->

Set up a DOM, forwarding our cookie.

        document = jsdom(
          html, jsdom.defaultLevel

          cookie: options.cookie
          cookieDomain: options.cookieDomain ? 'localhost'

          url: options.url ? "http://localhost:#{config.get 'packageSettings:shrub-http:port'}/"
        )
        @_window = window = document.defaultView

Capture "client" console logs.

        for level in ['info', 'log', 'debug', 'warn', 'error']
          do (level) -> window.console[level] = (args...) ->

Make errors as detailed as possible.

            for arg, i in args
              if arg instanceof Error
                args[i] = errors.stack arg
              else
                arg

            console[level] args...

Hack in WebSocket.

        window.WebSocket = WebSocket

        sandbox = this
        new Promise (resolve, reject) ->

When the window is loaded, we'll reject with any error, or resolve.

          window.onload = ->

            for documentError in window.document.errors ? []
              if documentError.data?.error?
                error = new Error "#{
                  documentError.message
                }\n#{
                  errors.stack documentError.data.error
                }"

            if error?
              reject error
            else
              resolve sandbox

## Sandbox#emitHtml

*Emit the document as HTML.*

      emitHtml: -> """
    <!doctype html>
    #{@_window.document.innerHTML}
    """

## Sandbox#registerCleanupFunction

* (function) `fn` - The function to run when the sandbox is closing.

*Register a function to run when the sandbox is closing.*

      registerCleanupFunction: (fn) -> @_cleanupFunctions.push fn

## Sandbox#url

*The current URL the sandbox is at.*

      url: -> @_window.location.href


structre webpack.config

structre webpack.config

# Webpack Configuration

[Webpack](https://github.com/webpack/webpack) handles asset compilation (Sass, CoffeeScript, etc).
It also manages loading via JavaScript `require`, Sass `@import`, and CSS `url()`.

First, require the dependencies:

    path    = require('path')
    webpack = require('webpack')
    _       = require('lodash')

Define an empty configuration

    module.exports = {}

List bundle entry points, i.e. packages to compile in the distribution. See [docs](http://webpack.github.io/docs/configuration.html#entry).

    module.exports.entry =
      main             : "./src/scripts/main.litcoffee"
      "styles"         : "./src/styles/styles.scss"
      "vendor/es5-shim": "./bower_components/es5-shim/es5-shim.js"
      "vendor/es5-sham": "./bower_components/es5-shim/es5-sham.js"

Then, define how files should be loaded (required) based on the extension:

### Scripts

Process CoffeeScript and JSX in CoffeeScript and JavaScript.

    scriptModLoaders = [
      { test: /\.coffee$/, loader: "jsx!coffee" }
      { test: /\.litcoffee$/, loader: "jsx!coffee?literate"}
      { test: /\.js$/, loader: "jsx" }
    ]

### Styles

Process with Sass and Autoprefixer.

    cssLoaders = ['style', 'css', 'autoprefixer-loader?last 2 versions']
    styleModLoaders = [
      { test: /\.scss$/, loaders: cssLoaders.concat(["sass?precision=10&outputStyle=expanded&includePaths[]=" + path.resolve(__dirname, './bower_components')]) }
      { test: /\.css$/, loaders: cssLoaders }
    ]

### Static assets

Embed data-URLs into CSS and JS for small images and `.woff` fonts:

    staticModLoaders = [
      { test: /\.gif$/, loader: "url?limit=10000&mimetype=image/gif" }
      { test: /\.jpg$/, loader: "url?limit=10000&mimetype=image/jpg" }
      { test: /\.png$/, loader: "url?limit=10000&mimetype=image/png" }
      { test: /\.woff$/, loader: "url?limit=10000&mimetype=application/font-woff" }
      { test: /\.ttf$/, loader: "file?mimetype=application/vnd.ms-fontobject" }
      { test: /\.eot$/, loader: "file?mimetype=application/x-font-ttf" }
      { test: /\.svg$/, loader: "file?mimetype=image/svg+xml" }
    ]

### Output CSS to `.css` files

`ExtractTextPlugin` is an experimental plugin to output CSS in `.css` and not as `.js` files with embedded CSS strings.

Require the plugin:

    ExtractTextPlugin = require("extract-text-webpack-plugin")

Set `styleModLoaders` to use the plugin:

    styleModLoaders = styleModLoaders.map (e) ->
      { test: e.test, loader: ExtractTextPlugin.extract(e.loaders.slice(1).join('!')) }

Create an instance of the extractTextPlugin:

    extractTextPlugin = new ExtractTextPlugin("[name].css", allChunks: true)

### Define macro variables

`DefinePlugin` defines variables to be substituted in the assets (a la macro).

Define `__PRODUCTION__: false` variable (set to true on `useProductionSettings()`):

    definePlugin = new webpack.DefinePlugin(
      __PRODUCTION__: JSON.stringify(false)
    )

### Other options

    _.merge module.exports,

Set compilation target to "web". See [docs](http://webpack.github.io/docs/configuration.html#target).

      target: "web"

Set development options by default:

      debug: true
      # We are watching in Gulp, so tell webpack not to watch
      watch: false
      # watchDelay: 300

Output options:

      output:
        path         : path.join(__dirname, "dist", "assets")
        publicPath   : "/assets/"
        filename     : "[name].js"
        chunkFilename: "[name].[id].[chunkhash].js"

Look for required files in bower and node

      resolve:
        modulesDirectories: ['bower_components', 'node_modules']

Define how modules should be loaded based on path extension:

      module:
        loaders: styleModLoaders.concat(scriptModLoaders).concat(staticModLoaders)
        noParse: /\.min\.js$/

Define the plugins:

      plugins: [

`definePlugin` defines variables to be substituted in the assets (a la macro):

        definePlugin

`extractTextPlugin` (defined above) will compile CSS to a .css file, as opposed to inlining it as a string in a .js file.

        extractTextPlugin
      ]

## Production overrides

Export a method that applies production settings (used in gulpfile):

      useProductionSettings: ->

Production plugins:

        plugins = @plugins.concat [

Minify JavaScript with UglifyJS:

          new webpack.optimize.UglifyJsPlugin()
        ]

Set `__PRODUCTION__` to true in the `DefinePlugin` instance:

        definePlugin.definitions.__PRODUCTION__ = JSON.stringify(true)

Tell `ExtractTextPlugin` to append hashes (BROKEN, see [plugin issue #9](https://github.com/webpack/extract-text-webpack-plugin/issues/9)):

        extractTextPlugin.filename = '[name]-[hash].css'

Merge in production config (deep merge):

        _.merge @,

Disable development settings:

          debug: false
          watch: false
          devtool: null

Add content hashes to the output filenames:

          output:
            filename: "[name]-[hash].js"

Production-only plugins:

          plugins: plugins

# Webpack Configuration

[Webpack](https://github.com/webpack/webpack) handles asset compilation (Sass, CoffeeScript, etc).
It also manages loading via JavaScript `require`, Sass `@import`, and CSS `url()`.

First, require the dependencies:

    path    = require('path')
    webpack = require('webpack')
    _       = require('lodash')

## Prepare CSS configuration

List of loader names for CSS files:

    cssLoaders = ['style', 'css', 'autoprefixer-loader?last 2 versions']

Style module loaders (used later):

    styleLoaders = [
      { test: /\.scss$/, loaders: cssLoaders.concat(["sass?precision=10&outputStyle=expanded&includePaths[]=" + path.resolve(__dirname, './bower_components')]) }
      { test: /\.css$/, loaders: cssLoaders }
    ]

`ExtractTextPlugin` is an experimental plugin to output CSS in `.css` and not `.js` files. Create plugin instance (used later):

    ExtractTextPlugin = require("extract-text-webpack-plugin")
    extractTextPlugin = new ExtractTextPlugin("[name].css", allChunks: true)

Override style loaders to use `ExtractTextPlugin`:

    styleLoaders = styleLoaders.map (e) ->
      test: e.test
      loader: ExtractTextPlugin.extract(e.loaders.slice(1).join('!'))

## Export configuration

    module.exports =

List of bundle entry points, i.e. packages to compile in the distribution. See [docs](http://webpack.github.io/docs/configuration.html#entry).

      entry:
        main             : "./src/scripts/main.litcoffee"
        "styles"         : "./src/styles/styles.scss"
        "vendor/es5-shim": "./bower_components/es5-shim/es5-shim.js"
        "vendor/es5-sham": "./bower_components/es5-shim/es5-sham.js"

Set compilation target to "web". See [docs](http://webpack.github.io/docs/configuration.html#target).

      target: "web"

Set development options by default:

      debug: true
      # We are watching in Gulp, so tell webpack not to watch
      watch: false
      # watchDelay: 300

Output options:

      output:
        path         : path.join(__dirname, "dist", "assets")
        publicPath   : "/assets/"
        filename     : "[name].js"
        chunkFilename: "[name].[id].[chunkhash].js"

Look for required files in bower and node

      resolve:
        modulesDirectories: ['bower_components', 'node_modules']

Define how modules should be loaded based on path extension:

      module:
        loaders: styleLoaders.concat [
          { test: /\.gif$/, loader: "url?limit=10000&minetype=image/gif" }
          { test: /\.jpg$/, loader: "url?limit=10000&minetype=image/jpg" }
          { test: /\.png$/, loader: "url?limit=10000&minetype=image/png" }
          { test: /\.js$/, loader: "jsx" }
          { test: /\.coffee$/, loader: "jsx!coffee" }
          { test: /\.litcoffee$/, loader: "jsx!coffee?literate"}
          # url-loader embeds DataUrls.
          { test: /\.woff$/, loader: "url?limit=10000&minetype=application/font-woff" }
          # file-loader emits files.
          { test: /\.ttf$/, loader: "file?mimetype=application/vnd.ms-fontobject" }
          { test: /\.eot$/, loader: "file?mimetype=application/x-font-ttf" }
          { test: /\.svg$/, loader: "file?mimetype=image/svg+xml" }
        ]
        noParse: /\.min\.js$/

Define the plugins:

      plugins: [

`DefinePlugin` defines a variable that will be substituted in the assets (a la macro):

        new webpack.DefinePlugin(__PRODUCTION__: JSON.stringify(false))

`extractTextPlugin` (defined above) will compile CSS to a .css file, as opposed to inlining it as a string in a .js file.

        extractTextPlugin
      ]

## Production overrides

Export a method that applies production settings (used in gulpfile):

      useProductionSettings: ->

Production plugins:

        plugins = @plugins.concat [

Minify JavaScript with UglifyJS:

          new webpack.optimize.UglifyJsPlugin()
        ]

Set `__PRODUCTION__` to true in the `DefinePlugin` instance:

        for plugin in plugins when plugin.definitions?.__PRODUCTION__
          plugin.definitions.__PRODUCTION__ = JSON.stringify(true)

Tell `ExtractTextPlugin` to append hashes (BROKEN, see [plugin issue #9](https://github.com/webpack/extract-text-webpack-plugin/issues/9)):

        for plugin in plugins when plugin.filename == '[name].css'
          plugin.filename = '[name]-[hash].css'

Merge in production config (deep merge):

        _.merge @,

Disable development settings:

          debug: false
          watch: false
          devtool: null

Add content hashes to the output filenames:

          output:
            filename: "[name]-[hash].js"

Production-only plugins:

          plugins: plugins


Add some docs for data-yield and data-contentfor

# Batman.View Bindings

Batman's view bindings are how data gets shown and collected from the user. They center on the notion of "bindings": that the view representation and the JavaScript land value are always guaranteed to be in sync, such that when one changes, the other will reflect it.

## How to use bindings

Bindings are declared as attributes on nodes under the `data` namespace. In practice, it looks like this:

```html
<div data-bind="name"></div>
```

This instantiates a binding on the `div` node which will update the node's `innerHTML` with the value found at the `name` keypath in the current context. Whenever the `name` key changes, the div's `innerHTML` will update to the new value.

Nodes can have multiple bindings:

```html
<p data-bind="body" data-showif="isPublished"></p>
```

or attribute bindings:

```html
<p data-bind-id="currentID"></p>
```

and bindings can be on inputs which the user can change:

```html
<input type="text" data-bind="title"></input>
```

When the `title` property changes on the JavaScript object this `input` is bound to, the `input`'s value will be updated. When the user types into the `input` (and `change` or `keyup` events are triggered), the `title` property in JavaScript land will be updated.

## Binding Keypaths

A `keypath` is the value of the HTML attribute a binding references. Importantly, keypaths can have multiple segments:

```html
<p data-bind="order.customer.name"></p>
```

The keypath in the above HTML is `order.customer.name`. When you create a binding to a keypath like this (with dots separating segments), the binding will update the HTML value when _any_ of those segments change. In the above example, this means the `p` tag's `innerHTML` will be updated when:

 1. the order changes,
 2. the order's customer changes,
 3. or the order's customer's name changes.

This is important because it means you can rely on a binding to "just work" when anything it depends on changes. If say you had a `<select>` on the page which changed the `order`'s `customer` property, bindings which bind to `order.customer.name` will update each time you change that select to reflect the new customer's name.

## Binding Contexts

All bindings render in a context. Binding contexts, known internally to Batman as `RenderContext`s, are objects which emulate the notion of variable scope in JavaScript code. When a controller action renders, it passes a context to the view consisting of itself, the `App`, and an object with a `window` key pointing to the host `window` object.

## Keypath Filters

Bindings can bind to filtered keypaths:

```html
<p data-bind="post.body | truncate 100"></p>
```

The above `<p>` will have 100 characters worth of the post's body. Whenever the post's body changes, it will be retruncated and the `<p>`'s `innerHTML` will be updated.

Filter chains can be arbitrarily long:

```html
<span data-bind="knight.title | prepend 'Sir' | append ', the honourable'."></span>
```

and filter chains can use other keypaths as arguments to the filters:

```html
<span data-bind="person.name | prepend ' ' | prepend person.title"></span>
```

The above `<span>`'s `innerHTML` will be updated whenever the person's name or title changes.

#### Two Way Bindings and Filters

Note that filtered keypaths cannot propagate DOM land changes because values can't always be "unfiltered". For example, if we bind an input to the truncated version of a string:

```html
<input data-bind="post.body | truncate 100"></input>
```

The `<input>`'s value can be updated when the `post.body` property changes but if a user types into this input field, they will edit the truncated body. If Batman updated the `post.body` property with the contents of the input, all characters which had been truncated will be lost to the nether. To avoid this loss of information and inconsistency, bindings to filtered keypaths will _only update from JavaScript land to HTML_, and never vice versa.

## Keypath Literals

Keypaths also support a select few literals within them. Numbers, strings, and booleans can be passed as arguments to filters or used as the actual value of the keypath.

The following are all valid, albeit contrived, bindings:

```html
<!-- String literal used as an argument -->
<p data-bind="body | append ' ... '"></p>

<!-- Boolean literal used as an argument -->
<p data-showif="shouldShow | default true"></p>

<!-- Number literal used as an argument -->
<p data-bind="body | truncate 100"></p>

<!-- String literal used as the value -->
<p data-bind="'Hardcoded'"></p>

<!-- Boolean literal used as the value -->
<p data-showif="true"></p>
```

## data-bind

`data-bind` creates a two way binding between a property on a `Batman.Object` and an HTML element. Bindings created via `data-bind` will update the HTML element with the value of the JS land property as soon as they are created and each time the property changes after, and if the HTML element can be observed for changes, it will update the JS land property with the value from the HTML.

`data-bind` will change its behaviour depending on what kind of tag it is attached to:

 + `<input type="checkbox">`: the binding will edit the `checked` property of the checkbox and populate the keypath with a boolean.
 + `<input type="text">` and similar, `<textarea`>: the binding will edit the `value` property of the input and populate the keypath with the string found at `value`.
 + `<input type="file">`: the binding will _not_ edit the `value` property of the input, but it will update the keypath with a host `File` object or objects if the node has the `multiple` attribute.
 + `<select>`: the binding will edit the `selected` property of each `<option>` tag within the `<select>` matching the property at the keypath. If the `<select>` has the multiple attribute, the value at the keypath can be an array of selected `<option>` values. You can also use `data-bind-selected` bindings on the individual options to toggle option selectedness.
 + All other tags: the binding will edit the `innerHTML` property of the tag and will not populate the keypath.

`data-bind` can also be used to bind an attribute of a node to a JavaScript property. Since attributes can't be observed for changes, this is a one way binding which will never update the JavaScript land property. Specify which attribute to bind using the "double dash" syntax like so: `data-bind-attribute="some.keypath"`. For example, to bind the `placeholder` attribute of an input, use `data-bind-placeholder`.

```html
<input type="text" data-bind-placeholder="'Specify a subtitle for product ' | append product.name">
```

_Note_: `data-bind` will not update a JavaScript property if filters are used in the keypath.

## data-source

`data-source` creates a one way binding which propagates only changes from JavaScript land to the DOM, and never vice versa. `data-source` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will only ever update the DOM and never the JavaScript land property.

For example, the HTML below will never update the `title` property on the product, even if the user changes it. Each time the `title` attribute changes from a `set` in JavaScript land, the value of the input will be updated to the new value of `title`, erasing any potential changes that have been made to the value of the input by the user.

```html
<input type="text" data-source="product.title">
```

_Note_: `data-source-attribute` is equivalent to `data-bind-attribute`, since the former is defined as never making JS land changes, and the latter is unable to.

## data-target

`data-target` creates a one way binding which propagates only changes from the DOM to JavaScript land, and never vice versa. `data-target` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will never update the DOM even if the JavaScript land value changes.

_Note_: `data-target-attribute` is unavailable, because DOM changes to node attributes can't be monitored.

## data-showif / data-hideif

`data-showif` and `data-hideif` bind to keypaths and show or hide the node they appear on based on the truthiness of the result. `data-showif` will show a node if the given keypath evaluates to something truthy, and `data-hideif` will leave a node visible until its given keypath becomes truthy, at which point the node will be hidden. `data-showif` and `data-hideif` show and hide nodes by adding `display: none !important;` to the node's `style` attribute.

For example, if the HTML below is rendered where the keypath `product.published` evaluated to true, the `<button>` will be visible.

```html
<button data-showif="product.published">Unpublish Product</button>
```

This is the Batman equivalent of a templating language's `if` construct, where else branches are implemented using the opposite binding.

```html
<button data-showif="product.published">Unpublish Product</button>
<button data-hideif="product.published">Publish Product</button>
```

## data-addclass / data-removeclass

`data-addclass` and `data-removeclass` bindings can be used to conditionally add or remove a class from a node based on a boolean keypath. Specify the class to add using the "double dash" syntax; for example,`data-addclass-big="some.keypath"` on a node will add the "big" class to that node's classes if `some.keypath` is truthy. `data-removeclass` will remove a class (usually one which is present in the HTML) if the keypath passed to it is truthy.

The outer span in the HTML below will have an "error" class when the `product.errors.length` keypath evaluates to anything other than 0, since 0 is falsy and other numbers are truthy.

```html
<span data-addclass-error="product.errors.length">This product has <span data-bind="product.errors.length"></span> errors.</button>
```

## data-foreach

`data-foreach` is used to loop over an iterable object in Batman views. `data-foreach` duplicates the node it occurs on for each item in the collection found at the keypath given to it, and renders each duplicated node with that node's object from the collection by putting it in the context under a name passed to it using the "double dash" syntax.

The `<option>` node below will be duplicated for each item in the `Set` at the `products` keypath.

```html
<select>
  <option data-foreach-product="products" data-bind="product.name"></option>
</select>
```

Batman will execute the `data-foreach` binding before the `data-bind` on the `<option>` node, which means that the `data-bind` will be processed for each duplicated node with each separate Product in the `products` Set in scope for each separate node. If there were say 3 Products in the `products` set, the HTML would look similar to this once rendered:

```html
<select>
  <option data-bind="product.name">Product A</option>
  <option data-bind="product.name">Product B</option>
  <option data-bind="product.name">Product C</option>
  <!-- end products -->
</select>
```

`data-foreach` can be used to iterate over `Batman.Set`s, and most often should be, because it observes any Sets and will update the DOM with new nodes if items are added to the set, or remove nodes from the DOM if their corresponding nodes are removed from the set. `data-foreach`, like every other binding, is keypath aware, such that if the `Set` instance at the keypath changes, or any previous segment of the keypath changes, `data-foreach` will remove all the nodes currently in the DOM, and add new nodes for each new item in the incoming `Set`.

Sometimes you'll need to add some custom logic to the iteration nodes. For example, a custom `viewDidAppear` handler so you can know whenever a new iteration node appears in the DOM. You can do this by specifying a custom subclass of `Batman.IterationView`.

```html
<ul>
  <li data-foreach-product="products" data-view="ProductIterationView">
    <span data-bind="product.name"></span>
  </li>
</ul>
```

```coffeescript
class MyApp.ProductIterationView extends Batman.IterationView
  viewDidAppear: ->
    $(@get('node')).draggable()
```

_Note_: `data-foreach` expects to find an iterable object at the keypath given to it, and will emit a warning if it finds `undefined`.

_Note_: `data-foreach` expects the passed enumerable to be unique. It creates a map of nodes to items, so every node needs to be able to reference exactly one object. If you simply have a set of values that you're iterating over, you should wrap your values in objects, e.g. `[{value: true}, {value: true}]`.

## data-formfor

`data-formfor` creates a special addition to the context stack to represent an object under edit within a form. Usually this object is a model. Using the double dash syntax, the name for the model to reside under can be specified.

==== Automatic Validation Display

`data-formfor` also has some handy functionality for displaying the result of validating the object under edit in the form. This will only be enabled if the object has an `errors` Set, like `Batman.Models` do.

If a tag matching the relative selector `.errors` is found, it will populate this element with a list of the errors found during validation on the object. The selector for the errors container can be changed by adding a `data-errors-list` attribute with the value of the selector to the form with the `data-formfor` binding on it, or editing `Batman.DOM.FormBinding::defaultErrorsListSelector`.

If value bindings are made using `data-bind` to attributes on the model within the form, automatic `data-addclass-error` bindings will be added to the elements on which the `data-bind` occurs to add the "error" class when the model has errors on the attribute which `data-bind` binds to.

In the HTML below, an automatic `data-addclass-error` will be added to the `<input>` which activates when the `product` model has validation errors on the `name` attribute.

```html
<form data-formfor-product="currentProduct">
  <input type="text" data-bind="product.name"></input>
</form>
```

The class which gets automatically added to inputs binding to invalid attributes can be customized by editing `Batman.DOM.FormBinding::errorClass`.

## data-context

`data-context` bindings add the object found at the key to the context stack, optionally under a key using the double dash syntax.

For example, if a `product` object exists in the current context, the `data-context` binding below will expose its attributes at the root level of the context:

```html
<div data-context="product">
  <span data-bind="name"></span>
  <span data-bind="cost"></span>
</div>
```

Contexts added to the stack can also be scoped under a key using `data-context-`:

```html
<div data-context-currentProduct="product">
  <span data-bind="currentProduct"></span>
  <span data-bind="currentProduct"></span>
</div>
```

This is a useful mechanism for passing local variables to partial views.

## data-event

`data-event` bindings add DOM event listeners to the nodes they exist on which call the function found at the passed keypath. `data-event` bindings use the double dash syntax to specify the name of the event to listen for.

In the HTML below, if the keypath `controller.nextAction` resolves to a function, that function will be executed each time the `<button>` element is clicked.

```html
<button data-event-click="controller.nextAction"></button>
```

Functions which `data-event` calls will be passed the node and the `DOMEvent` object: `(node, event) ->`.

`data-event` supports the following types of events formally and should "do the right thing" when attached to elements which fire these events:

 + click
 + doubleclick
 + change
 + submit

If the event name used doesn't match the above events, the event name used will just fall through and be passed to `window.addEventListener`.

## data-route

`data-route` bindings are used to dispatch a new controller action upon the clicking of the node they bind to. `data-route` expects to find either a string or a `NamedRouteQuery` at the keypath passed to it. With this route, it will add an event handler to the `click` action of the element which dispatches the route and prevents the default action of the DOMEvent. `data-route` will also populate the `href` attribute if it occurs on an `<a>` tag so that other functons like "Copy Link Address" and Alt+Click continue to work on the link.

The first way to use `data-route` is by passing it a string, which can be built using filters or an accessor, but the preferred way is to use the `NamedRouteQuery`. These objects are generated for you by starting keypaths at the `App.routes` property. All `Batman.App`s have a `routes` property which holds a nested list of all the routes, which you descend into by passing various key segments and objects. Since the `App` object is present in the default context stack, `data-route` keypaths can just start with `routes`.

For example, assume the following routes definition in the current `Batman.App`:

```coffeescript
class Alfred extends Batman.App
  @resources 'todos'
```

This means that routes like `/todos` and `/todos/:id` exist. To route to the collection action, use the plural name of the resource:

```html
<a data-route="routes.todos"></a>
```

To route to an individual todo things get a bit more complicated. If we have a Todo model with ID# `42` in the context as `todo`, use the `get` filter shorthand on the `NamedRouteQuery` returned by `routes.todos` to generate a member route:

```html
<a data-route="routes.todos[todo]"></a>
```

Underneath, this is calling `Alfred.get('routes.todos').get(todo)`; the todo object is being passed as a key to the `NamedRouteQuery`, which knows how to generate a member route when given a record. The above HTML when rendered will look like this:

```html
<a data-route="routes.todos[todo]" href="/todos/42"></a>
```

This syntax can be extended to nested routes. If we have nested routes, we can use chained gets to generated nested routes

```coffeescript
class Tracker extends Batman.App
  @resources 'villains', ->
    @resources 'crimes'
```

Routes for collection and member crimes should look like `/villains/:villain_id/crimes` and `/villains/:villain_id/crimes/:id` respectively. Assuming the presence of a `villain` and a `crime` in the context, chained `get`s on `NamedRouteQuery`s achieve this:

```html
<!-- Collection of crimes for a particular villain -->
<a data-route="routes.villains[villain].crimes"></a>
<!-- One crime of a particular villain -->
<a data-route="routes.villains[villain].crimes[crime]"></a>
```

_Note_: `data-route` bindings route only to internal dispatch, and not external links. Use a regular `<a>` tag to link away from the application.

## data-view

`data-view` bindings attach custom `Batman.View` instances or instantiate custom `View` subclasses to / on a node. `data-view` expects either a `Batman.View` instance or subclass at the keypath passed to it. If an instance is passed, it will `set` the `node` property of the view to the node the `data-view` occurs on. If a class is passed, that class will be instantiated with the context the `data-view` binding executed in and with the node it occurred upon. See `Batman.View` for more information on custom Views and their uses.

_Note_: `data-view` bindings will bind to the passed keypath until it exists, that is to say until the value of it is not `undefined`. After the `View` has been set up, the `data-view` binding will remove itself and stop observing the keypath.

## data-partial

`data-partial` pulls in a partial template and renders it in the current context of the node the `data-partial` occurs in. `data-partial` expects the name of the view to render in the value of the HTML attribute. __Warning__: This value is not a keypath. The HTML attribute's value is interpreted as a string, and the template which resides at that view path will be rendered.

If we have this HTML at `views/villains/_stub.html` in our app:

```html
<span data-bind="villain.name"></span>
```

and in `views/villains/show.html` we have this HTML:

```html
<h1>A villain!</h1>
<div data-partial="villains/_stub"></div>
```

the contents of the `stub` partial will be inserted and rendered in the `<div>` above.

## data-mixin

## data-defineview

## data-renderif

`data-renderif` defers parsing of a nodes child bindings until its keypath updates to true. `data-renderif` should generally be combined with a `data-showif` or `data-insertif` to prevent it being visible until ready.

## data-yield

`data-yield` is used for binging HTML from views into the document. By default `data-yield="main"` will bind view HTML based on the current controller and action. You can also define HTML templates using `data-contentfor`.

```html
<div data-yield="main"></div>
```

## data-contentfor

`data-contentfor` provides the keypath for which child nodes are bound to for use in a `data-yield`.

```html
<div data-contentfor="header"><h1 data-bind="title"></h1></div>
<div data-yield="header"></div>
```

# Batman.View Filters

## raw(value) : string

The `raw` filter renders the unescaped value.

```html
<span data-bind="someHTMLyString | raw"></span>
```

## get(value, key) : value

## value[key] : value

Shorthand for the `get` filter.

## equals(left, right) : boolean

## not(value) : boolean

## matches(value, string) : boolean

## truncate(value, length, end = '...') : string

## default(value, defaultValue) : value

## prepend(value, string) : string

## append(value, string) : string

## replace(value, searchString, replaceString[, flags]) : string

## downcase(value) : string

## upcase(value) : string

## pluralize(value, count) : string

## humanize(string) : string

## join(value, separator = '') : string

## sort(value) : value

## map(iterable) : value

## has(iterable, item) : boolean

## first(iterable) : value

## meta(value, keypath) : value

## interpolate(string, valuesObject) : string

## withArguments(function, curriedArguments...) : function

## routeToAction(model, action) : string

## escape(value) : string

# Batman.View Bindings

Batman's view bindings are how data gets shown and collected from the user. They center on the notion of "bindings": that the view representation and the JavaScript land value are always guaranteed to be in sync, such that when one changes, the other will reflect it.

## How to use bindings

Bindings are declared as attributes on nodes under the `data` namespace. In practice, it looks like this:

```html
<div data-bind="name"></div>
```

This instantiates a binding on the `div` node which will update the node's `innerHTML` with the value found at the `name` keypath in the current context. Whenever the `name` key changes, the div's `innerHTML` will update to the new value.

Nodes can have multiple bindings:

```html
<p data-bind="body" data-showif="isPublished"></p>
```

or attribute bindings:

```html
<p data-bind-id="currentID"></p>
```

and bindings can be on inputs which the user can change:

```html
<input type="text" data-bind="title"></input>
```

When the `title` property changes on the JavaScript object this `input` is bound to, the `input`'s value will be updated. When the user types into the `input` (and `change` or `keyup` events are triggered), the `title` property in JavaScript land will be updated.

## Binding Keypaths

A `keypath` is the value of the HTML attribute a binding references. Importantly, keypaths can have multiple segments:

```html
<p data-bind="order.customer.name"></p>
```

The keypath in the above HTML is `order.customer.name`. When you create a binding to a keypath like this (with dots separating segments), the binding will update the HTML value when _any_ of those segments change. In the above example, this means the `p` tag's `innerHTML` will be updated when:

 1. the order changes,
 2. the order's customer changes,
 3. or the order's customer's name changes.

This is important because it means you can rely on a binding to "just work" when anything it depends on changes. If say you had a `<select>` on the page which changed the `order`'s `customer` property, bindings which bind to `order.customer.name` will update each time you change that select to reflect the new customer's name.

## Binding Contexts

All bindings render in a context. Binding contexts, known internally to Batman as `RenderContext`s, are objects which emulate the notion of variable scope in JavaScript code. When a controller action renders, it passes a context to the view consisting of itself, the `App`, and an object with a `window` key pointing to the host `window` object.

## Keypath Filters

Bindings can bind to filtered keypaths:

```html
<p data-bind="post.body | truncate 100"></p>
```

The above `<p>` will have 100 characters worth of the post's body. Whenever the post's body changes, it will be retruncated and the `<p>`'s `innerHTML` will be updated.

Filter chains can be arbitrarily long:

```html
<span data-bind="knight.title | prepend 'Sir' | append ', the honourable'."></span>
```

and filter chains can use other keypaths as arguments to the filters:

```html
<span data-bind="person.name | prepend ' ' | prepend person.title"></span>
```

The above `<span>`'s `innerHTML` will be updated whenever the person's name or title changes.

#### Two Way Bindings and Filters

Note that filtered keypaths cannot propagate DOM land changes because values can't always be "unfiltered". For example, if we bind an input to the truncated version of a string:

```html
<input data-bind="post.body | truncate 100"></input>
```

The `<input>`'s value can be updated when the `post.body` property changes but if a user types into this input field, they will edit the truncated body. If Batman updated the `post.body` property with the contents of the input, all characters which had been truncated will be lost to the nether. To avoid this loss of information and inconsistency, bindings to filtered keypaths will _only update from JavaScript land to HTML_, and never vice versa.

## Keypath Literals

Keypaths also support a select few literals within them. Numbers, strings, and booleans can be passed as arguments to filters or used as the actual value of the keypath.

The following are all valid, albeit contrived, bindings:

```html
<!-- String literal used as an argument -->
<p data-bind="body | append ' ... '"></p>

<!-- Boolean literal used as an argument -->
<p data-showif="shouldShow | default true"></p>

<!-- Number literal used as an argument -->
<p data-bind="body | truncate 100"></p>

<!-- String literal used as the value -->
<p data-bind="'Hardcoded'"></p>

<!-- Boolean literal used as the value -->
<p data-showif="true"></p>
```

## data-bind

`data-bind` creates a two way binding between a property on a `Batman.Object` and an HTML element. Bindings created via `data-bind` will update the HTML element with the value of the JS land property as soon as they are created and each time the property changes after, and if the HTML element can be observed for changes, it will update the JS land property with the value from the HTML.

`data-bind` will change its behaviour depending on what kind of tag it is attached to:

 + `<input type="checkbox">`: the binding will edit the `checked` property of the checkbox and populate the keypath with a boolean.
 + `<input type="text">` and similar, `<textarea`>: the binding will edit the `value` property of the input and populate the keypath with the string found at `value`.
 + `<input type="file">`: the binding will _not_ edit the `value` property of the input, but it will update the keypath with a host `File` object or objects if the node has the `multiple` attribute.
 + `<select>`: the binding will edit the `selected` property of each `<option>` tag within the `<select>` matching the property at the keypath. If the `<select>` has the multiple attribute, the value at the keypath can be an array of selected `<option>` values. You can also use `data-bind-selected` bindings on the individual options to toggle option selectedness.
 + All other tags: the binding will edit the `innerHTML` property of the tag and will not populate the keypath.

`data-bind` can also be used to bind an attribute of a node to a JavaScript property. Since attributes can't be observed for changes, this is a one way binding which will never update the JavaScript land property. Specify which attribute to bind using the "double dash" syntax like so: `data-bind-attribute="some.keypath"`. For example, to bind the `placeholder` attribute of an input, use `data-bind-placeholder`.

```html
<input type="text" data-bind-placeholder="'Specify a subtitle for product ' | append product.name">
```

_Note_: `data-bind` will not update a JavaScript property if filters are used in the keypath.

## data-source

`data-source` creates a one way binding which propagates only changes from JavaScript land to the DOM, and never vice versa. `data-source` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will only ever update the DOM and never the JavaScript land property.

For example, the HTML below will never update the `title` property on the product, even if the user changes it. Each time the `title` attribute changes from a `set` in JavaScript land, the value of the input will be updated to the new value of `title`, erasing any potential changes that have been made to the value of the input by the user.

```html
<input type="text" data-source="product.title">
```

_Note_: `data-source-attribute` is equivalent to `data-bind-attribute`, since the former is defined as never making JS land changes, and the latter is unable to.

## data-target

`data-target` creates a one way binding which propagates only changes from the DOM to JavaScript land, and never vice versa. `data-target` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will never update the DOM even if the JavaScript land value changes.

_Note_: `data-target-attribute` is unavailable, because DOM changes to node attributes can't be monitored.

## data-showif / data-hideif

`data-showif` and `data-hideif` bind to keypaths and show or hide the node they appear on based on the truthiness of the result. `data-showif` will show a node if the given keypath evaluates to something truthy, and `data-hideif` will leave a node visible until its given keypath becomes truthy, at which point the node will be hidden. `data-showif` and `data-hideif` show and hide nodes by adding `display: none !important;` to the node's `style` attribute.

For example, if the HTML below is rendered where the keypath `product.published` evaluated to true, the `<button>` will be visible.

```html
<button data-showif="product.published">Unpublish Product</button>
```

This is the Batman equivalent of a templating language's `if` construct, where else branches are implemented using the opposite binding.

```html
<button data-showif="product.published">Unpublish Product</button>
<button data-hideif="product.published">Publish Product</button>
```

## data-addclass / data-removeclass

`data-addclass` and `data-removeclass` bindings can be used to conditionally add or remove a class from a node based on a boolean keypath. Specify the class to add using the "double dash" syntax; for example,`data-addclass-big="some.keypath"` on a node will add the "big" class to that node's classes if `some.keypath` is truthy. `data-removeclass` will remove a class (usually one which is present in the HTML) if the keypath passed to it is truthy.

The outer span in the HTML below will have an "error" class when the `product.errors.length` keypath evaluates to anything other than 0, since 0 is falsy and other numbers are truthy.

```html
<span data-addclass-error="product.errors.length">This product has <span data-bind="product.errors.length"></span> errors.</button>
```

## data-foreach

`data-foreach` is used to loop over an iterable object in Batman views. `data-foreach` duplicates the node it occurs on for each item in the collection found at the keypath given to it, and renders each duplicated node with that node's object from the collection by putting it in the context under a name passed to it using the "double dash" syntax.

The `<option>` node below will be duplicated for each item in the `Set` at the `products` keypath.

```html
<select>
  <option data-foreach-product="products" data-bind="product.name"></option>
</select>
```

Batman will execute the `data-foreach` binding before the `data-bind` on the `<option>` node, which means that the `data-bind` will be processed for each duplicated node with each separate Product in the `products` Set in scope for each separate node. If there were say 3 Products in the `products` set, the HTML would look similar to this once rendered:

```html
<select>
  <option data-bind="product.name">Product A</option>
  <option data-bind="product.name">Product B</option>
  <option data-bind="product.name">Product C</option>
  <!-- end products -->
</select>
```

`data-foreach` can be used to iterate over `Batman.Set`s, and most often should be, because it observes any Sets and will update the DOM with new nodes if items are added to the set, or remove nodes from the DOM if their corresponding nodes are removed from the set. `data-foreach`, like every other binding, is keypath aware, such that if the `Set` instance at the keypath changes, or any previous segment of the keypath changes, `data-foreach` will remove all the nodes currently in the DOM, and add new nodes for each new item in the incoming `Set`.

Sometimes you'll need to add some custom logic to the iteration nodes. For example, a custom `viewDidAppear` handler so you can know whenever a new iteration node appears in the DOM. You can do this by specifying a custom subclass of `Batman.IterationView`.

```html
<ul>
  <li data-foreach-product="products" data-view="ProductIterationView">
    <span data-bind="product.name"></span>
  </li>
</ul>
```

```coffeescript
class MyApp.ProductIterationView extends Batman.IterationView
  viewDidAppear: ->
    $(@get('node')).draggable()
```

_Note_: `data-foreach` expects to find an iterable object at the keypath given to it, and will emit a warning if it finds `undefined`.

_Note_: `data-foreach` expects the passed enumerable to be unique. It creates a map of nodes to items, so every node needs to be able to reference exactly one object. If you simply have a set of values that you're iterating over, you should wrap your values in objects, e.g. `[{value: true}, {value: true}]`.

## data-formfor

`data-formfor` creates a special addition to the context stack to represent an object under edit within a form. Usually this object is a model. Using the double dash syntax, the name for the model to reside under can be specified.

==== Automatic Validation Display

`data-formfor` also has some handy functionality for displaying the result of validating the object under edit in the form. This will only be enabled if the object has an `errors` Set, like `Batman.Models` do.

If a tag matching the relative selector `.errors` is found, it will populate this element with a list of the errors found during validation on the object. The selector for the errors container can be changed by adding a `data-errors-list` attribute with the value of the selector to the form with the `data-formfor` binding on it, or editing `Batman.DOM.FormBinding::defaultErrorsListSelector`.

If value bindings are made using `data-bind` to attributes on the model within the form, automatic `data-addclass-error` bindings will be added to the elements on which the `data-bind` occurs to add the "error" class when the model has errors on the attribute which `data-bind` binds to.

In the HTML below, an automatic `data-addclass-error` will be added to the `<input>` which activates when the `product` model has validation errors on the `name` attribute.

```html
<form data-formfor-product="currentProduct">
  <input type="text" data-bind="product.name"></input>
</form>
```

The class which gets automatically added to inputs binding to invalid attributes can be customized by editing `Batman.DOM.FormBinding::errorClass`.

## data-context

`data-context` bindings add the object found at the key to the context stack, optionally under a key using the double dash syntax.

For example, if a `product` object exists in the current context, the `data-context` binding below will expose its attributes at the root level of the context:

```html
<div data-context="product">
  <span data-bind="name"></span>
  <span data-bind="cost"></span>
</div>
```

Contexts added to the stack can also be scoped under a key using `data-context-`:

```html
<div data-context-currentProduct="product">
  <span data-bind="currentProduct"></span>
  <span data-bind="currentProduct"></span>
</div>
```

This is a useful mechanism for passing local variables to partial views.

## data-event

`data-event` bindings add DOM event listeners to the nodes they exist on which call the function found at the passed keypath. `data-event` bindings use the double dash syntax to specify the name of the event to listen for.

In the HTML below, if the keypath `controller.nextAction` resolves to a function, that function will be executed each time the `<button>` element is clicked.

```html
<button data-event-click="controller.nextAction"></button>
```

Functions which `data-event` calls will be passed the node and the `DOMEvent` object: `(node, event) ->`.

`data-event` supports the following types of events formally and should "do the right thing" when attached to elements which fire these events:

 + click
 + doubleclick
 + change
 + submit

If the event name used doesn't match the above events, the event name used will just fall through and be passed to `window.addEventListener`.

## data-route

`data-route` bindings are used to dispatch a new controller action upon the clicking of the node they bind to. `data-route` expects to find either a string or a `NamedRouteQuery` at the keypath passed to it. With this route, it will add an event handler to the `click` action of the element which dispatches the route and prevents the default action of the DOMEvent. `data-route` will also populate the `href` attribute if it occurs on an `<a>` tag so that other functons like "Copy Link Address" and Alt+Click continue to work on the link.

The first way to use `data-route` is by passing it a string, which can be built using filters or an accessor, but the preferred way is to use the `NamedRouteQuery`. These objects are generated for you by starting keypaths at the `App.routes` property. All `Batman.App`s have a `routes` property which holds a nested list of all the routes, which you descend into by passing various key segments and objects. Since the `App` object is present in the default context stack, `data-route` keypaths can just start with `routes`.

For example, assume the following routes definition in the current `Batman.App`:

```coffeescript
class Alfred extends Batman.App
  @resources 'todos'
```

This means that routes like `/todos` and `/todos/:id` exist. To route to the collection action, use the plural name of the resource:

```html
<a data-route="routes.todos"></a>
```

To route to an individual todo things get a bit more complicated. If we have a Todo model with ID# `42` in the context as `todo`, use the `get` filter shorthand on the `NamedRouteQuery` returned by `routes.todos` to generate a member route:

```html
<a data-route="routes.todos[todo]"></a>
```

Underneath, this is calling `Alfred.get('routes.todos').get(todo)`; the todo object is being passed as a key to the `NamedRouteQuery`, which knows how to generate a member route when given a record. The above HTML when rendered will look like this:

```html
<a data-route="routes.todos[todo]" href="/todos/42"></a>
```

This syntax can be extended to nested routes. If we have nested routes, we can use chained gets to generated nested routes

```coffeescript
class Tracker extends Batman.App
  @resources 'villains', ->
    @resources 'crimes'
```

Routes for collection and member crimes should look like `/villains/:villain_id/crimes` and `/villains/:villain_id/crimes/:id` respectively. Assuming the presence of a `villain` and a `crime` in the context, chained `get`s on `NamedRouteQuery`s achieve this:

```html
<!-- Collection of crimes for a particular villain -->
<a data-route="routes.villains[villain].crimes"></a>
<!-- One crime of a particular villain -->
<a data-route="routes.villains[villain].crimes[crime]"></a>
```

_Note_: `data-route` bindings route only to internal dispatch, and not external links. Use a regular `<a>` tag to link away from the application.

## data-view

`data-view` bindings attach custom `Batman.View` instances or instantiate custom `View` subclasses to / on a node. `data-view` expects either a `Batman.View` instance or subclass at the keypath passed to it. If an instance is passed, it will `set` the `node` property of the view to the node the `data-view` occurs on. If a class is passed, that class will be instantiated with the context the `data-view` binding executed in and with the node it occurred upon. See `Batman.View` for more information on custom Views and their uses.

_Note_: `data-view` bindings will bind to the passed keypath until it exists, that is to say until the value of it is not `undefined`. After the `View` has been set up, the `data-view` binding will remove itself and stop observing the keypath.

## data-partial

`data-partial` pulls in a partial template and renders it in the current context of the node the `data-partial` occurs in. `data-partial` expects the name of the view to render in the value of the HTML attribute. __Warning__: This value is not a keypath. The HTML attribute's value is interpreted as a string, and the template which resides at that view path will be rendered.

If we have this HTML at `views/villains/_stub.html` in our app:

```html
<span data-bind="villain.name"></span>
```

and in `views/villains/show.html` we have this HTML:

```html
<h1>A villain!</h1>
<div data-partial="villains/_stub"></div>
```

the contents of the `stub` partial will be inserted and rendered in the `<div>` above.

## data-mixin

## data-defineview

## data-renderif

`data-renderif` defers parsing of a nodes child bindings until its keypath updates to true. `data-renderif` should generally be combined with a `data-showif` or `data-insertif` to prevent it being visible until ready.

## data-yield

## data-contentfor

# Batman.View Filters

## raw(value) : string

The `raw` filter renders the unescaped value.

```html
<span data-bind="someHTMLyString | raw"></span>
```

## get(value, key) : value

## value[key] : value

Shorthand for the `get` filter.

## equals(left, right) : boolean

## not(value) : boolean

## matches(value, string) : boolean

## truncate(value, length, end = '...') : string

## default(value, defaultValue) : value

## prepend(value, string) : string

## append(value, string) : string

## replace(value, searchString, replaceString[, flags]) : string

## downcase(value) : string

## upcase(value) : string

## pluralize(value, count) : string

## humanize(string) : string

## join(value, separator = '') : string

## sort(value) : value

## map(iterable) : value

## has(iterable, item) : boolean

## first(iterable) : value

## meta(value, keypath) : value

## interpolate(string, valuesObject) : string

## withArguments(function, curriedArguments...) : function

## routeToAction(model, action) : string

## escape(value) : string


Add tests for set operations

Add tests for set operations

# /api/Data Structures/Batman.BinarySetOperation

`Batman.BinarySetOperation` extends `Batman.Set` and tracks _two_ `Batman.Set`s and updates its contents whenever an item is added to or removed from either set. `Batman.BinarySetOperation` is an abstract class. It is extended by `Batman.SetUnion`, `Batman.SetIntersection`, and `Batman.SetComplement`.

## ::constructor(left: Set, right: Set) : BinarySetOperation

Returns a new `BinarySetOperation` between `left` and `right`.

## ::merge(others... : Set) : Set

Returns a new `Batman.Set` with the contents of the `BinarySetOperation` plus the contents of `others`.

## ::filter(func: Function) : Set

Executes `func(item)` for each item in the `BinarySetOperation` and returns a new `Batman.Set` with items where `func(item)` returned a truthy value.

## ::.left : Set

Returns the first `Batman.Set` passed to the constructor.

## ::.right : Set

Returns the second `Batman.Set` passed to the constructor.

# /api/Data Structures/Batman.BinarySetOperation/Batman.SetUnion

`Batman.SetUnion` extends `Batman.BinarySetOperation`. It implements a [union operation](http://en.wikipedia.org/wiki/Union_%28set_theory%29): the `SetUnion` contains members found in _either set_ passed to the constructor, without duplicates.

Since `Batman.SetUnion` is a subclass of `Batman.Set`, you can use it just like a `Batman.Set`.

    test 'SetUnion contains the union of two sets', ->
      left = new Batman.Set(1, 2, 3)
      right = new Batman.Set(3, 4, 5)
      operation = new Batman.SetUnion(left, right)
      ok operation.has(1), 'has items from the left set'
      ok operation.has(4), 'has items from the right set'
      ok operation.has(3), 'has items from both sets'

# /api/Data Structures/Batman.BinarySetOperation/Batman.SetIntersection

`Batman.SetIntersection` extends `Batman.BinarySetOperation`. It implements an [intersection operation](http://en.wikipedia.org/wiki/Intersection_%28set_theory%29): it contains members of _both sets_ passed to its constructor without duplicates.

Since `Batman.SetIntersection` is a subclass of `Batman.Set`, you can use it just like a `Batman.Set`.

    test 'SetIntersection contains the intersection of two sets', ->
      left = new Batman.Set(1, 2, 3)
      right = new Batman.Set(3, 4, 5)
      operation = new Batman.SetIntersection(left, right)
      ok !operation.has(1), 'doesnt have items from the left set only'
      ok !operation.has(4), 'doesnt have items from the right set only'
      ok operation.has(3), 'has items from both sets'

# /api/Data Structures/Batman.BinarySetOperation/Batman.SetComplement

`Batman.SetComplement` extends `Batman.BinarySetOperation`. It implements a [complement operation](http://en.wikipedia.org/wiki/Complement_%28set_theory%29): it contains the members of _`left`_ which aren't in _`right`_.

Since `Batman.SetComplement` is a subclass of `Batman.Set`, you can use it just like a `Batman.Set`.

    test 'SetComplement contains the complement of two sets', ->
      left = new Batman.Set(1, 2, 3)
      right = new Batman.Set(3, 4, 5)
      operation = new Batman.SetComplement(left, right)
      ok operation.has(1), 'has items from the left set only'
      ok !operation.has(4), 'doesnt have items from the right set only'
      ok !operation.has(3), 'doesnt have items from both sets'

# /api/Data Structures/Batman.BinarySetOperation

`Batman.BinarySetOperation` extends `Batman.Set` and tracks _two_ `Batman.Set`s and updates its contents whenever an item is added to or removed from either set. `Batman.BinarySetOperation` is an abstract class. It is extended by `Batman.SetUnion`, `Batman.SetIntersection`, and `Batman.SetComplement`.

## ::constructor(left: Set, right: Set) : BinarySetOperation

Returns a new `BinarySetOperation` between `left` and `right`.

## ::merge(others... : Set) : Set

Returns a new `Batman.Set` with the contents of the `BinarySetOperation` plus the contents of `others`.

## ::filter(func: Function) : Set

Executes `func(item)` for each item in the `BinarySetOperation` and returns a new `Batman.Set` with items where `func(item)` returned a truthy value.

## ::.left : Set

Returns the first `Batman.Set` passed to the constructor.

## ::.right : Set

Returns the second `Batman.Set` passed to the constructor.

# /api/Data Structures/Batman.BinarySetOperation/Batman.SetUnion

`Batman.SetUnion` extends `Batman.BinarySetOperation`. It implements a [union operation](http://en.wikipedia.org/wiki/Union_%28set_theory%29): the `SetUnion` contains members found in _either set_ passed to the constructor, without duplicates.

Since `Batman.SetUnion` is a subclass of `Batman.Set`, you can use it just like a `Batman.Set`.

# /api/Data Structures/Batman.BinarySetOperation/Batman.SetIntersection

`Batman.SetIntersection` extends `Batman.BinarySetOperation`. It implements an [intersection operation](http://en.wikipedia.org/wiki/Intersection_%28set_theory%29): it contains members of _both sets_ passed to its constructor without duplicates.

Since `Batman.SetIntersection` is a subclass of `Batman.Set`, you can use it just like a `Batman.Set`.

# /api/Data Structures/Batman.BinarySetOperation/Batman.SetComplement

`Batman.SetComplement` extends `Batman.BinarySetOperation`. It implements a [complement operation](http://en.wikipedia.org/wiki/Complement_%28set_theory%29): it contains the members of _`left`_ which aren't in _`right`_.

Since `Batman.SetComplement` is a subclass of `Batman.Set`, you can use it just like a `Batman.Set`.


Added functions to handle angles.

Added functions to handle angles.

# misc

## interpolate

- from: A number to interpolate from.
- to: A number to interpolate to.
- alpha: A number, where "0" is "from" and "1" is "to".

Returns the linear interpolation or extrapolation from "from" to "to".

    interpolate = (from, to, alpha) -> from + (to - from) * alpha

## wrapAngle

- radians: A number of radians to wrap.

Returns the input wrapped to the 0...2PI range.

    wrapAngle = (radians) -> radians - (Math.PI * 2 * Math.floor (radians / (Math.PI * 2)))

## interpolateAngle

- from: A number of radians to interpolate from.
- to: A number of radians to interpolate to.
- alpha: A number, where "0" is "from" and "1" is "to".

Returns the linear interpolation or extrapolation from "from" to "to".  Can
shortcut over the 0/2PI boundary.

    interpolateAngle = (from, to, alpha) ->
        from = wrapAngle from
        to = wrapAngle to
        if from < Math.PI / 2 and to > Math.PI * 1.5
            to -= Math.PI * 2
        else if to < Math.PI / 2 and from > Math.PI * 1.5
            to += Math.PI * 2
        wrapAngle (from + (to - from) * alpha)

    module.exports = { interpolate, wrapAngle, interpolateAngle }

	module.exports =

Call the "interpolate" property with a number to interpolate from, a number to
interpolate to, and a number specifying the alpha (0 is from, 1 is to) to return
the linearly interpolated, or extrapolated number.

		interpolate: (from, to, alpha) -> from + (to - from) * alpha


Load render pipeline passed via input

Load render pipeline passed via input

    `#! /usr/bin/env node
    `

    Madul = require 'madul'

    if process.env.SKYLL_MADUL_LOGGING == 'true'
      require 'magnus'

    Skyll = require './index'
    args  = require './arguments'
    uuid  = require 'node-uuid'
    fs    = require 'fs'
    path  = require 'path'

    EXTRACT = [
      'rows'
      'columns'
      'width'
      'height'
      'multiplier'
      'pipeline'
      'block'
      'ground'
      'step_count'
      'wall'
    ]

    new Skyll()
      .initialize args
      .then (mod) ->
        levels = [ ]

        if args._?.length > 0
          levels = levels.concat argv._
        else if args.l?
          for level in [0...argv.l]
            levels.push uuid.v4()
        else if Array.isArray args.levels
          for level in args.levels
            levels.push level
        else if args.levels? == false
          levels.push new Date().toString()

        if args.delegates?
          location = args.delegates
        else
          location = path.join __dirname, 'delegates.js'

        fs.stat location, (err) ->
          if err?
            mod.warn 'file-not-found', location
          else
            delegates = require location
            next      = 0
            input     = { }
            pipe      = [ ]

            for own key, val of args
              input[key] = val if EXTRACT.includes key

            for p in input.pipeline
              if Array.isArray p
                for q in p
                  pipe.push(q) unless pipe.includes q
              else
                pipe.push(p) unless pipe.includes p

            Madul.DUMMY pipe, (dum) ->
              dum.render_pipeline = [ ]

              for p in input.pipeline
                if Array.isArray p
                  new_pipeline = for q in p
                    dum[Madul.PARSE_SPEC(q).ref]

                  dum.render_pipeline.push new_pipeline
                else
                  dum.render_pipeline.push dum[Madul.PARSE_SPEC(p).ref]

              args = { }
              name = new Date().toString()

              for own key, val of input
                args[key] = val if EXTRACT.includes key

              render = (level) ->
                mod.craft level, input, dum.render_pipeline, delegates
                  .then -> render levels[next] if ++next < levels.length

              render levels[next]

    `#! /usr/bin/env node
    `

    Madul = require 'madul'

    if process.env.SKYLL_MADUL_LOGGING == 'true'
      require 'magnus'

    Skyll = require './index'
    args  = require './arguments'
    uuid  = require 'node-uuid'
    fs    = require 'fs'
    path  = require 'path'

    EXTRACT = [
      'rows'
      'columns'
      'width'
      'height'
      'multiplier'
      'pipeline'
      'block'
      'ground'
      'step_count'
      'wall'
    ]

    new Skyll()
      .initialize args
      .then (mod) ->
        levels = [ ]

        if args._?.length > 0
          levels = levels.concat argv._
        else if args.l?
          for level in [0...argv.l]
            levels.push uuid.v4()
        else if Array.isArray args.levels
          for level in args.levels
            levels.push level
        else if args.levels? == false
          levels.push new Date().toString()

        if args.delegates?
          location = args.delegates
        else
          location = path.join __dirname, 'delegates.js'

        fs.stat location, (err) ->
          if err?
            mod.warn 'file-not-found', location
          else
            delegates = require location
            next      = 0
            input     = { }
            pipe      = [ ]

            for own key, val of args
              input[key] = val if EXTRACT.includes key

            Madul.DUMMY pipe, (dum) ->
              dum.render_pipeline = [ ]

              for p in input.pipeline
                if Array.isArray p
                  new_pipeline = for q in p
                    dum[Madul.PARSE_SPEC(q).ref]

                  dum.render_pipeline.push new_pipeline
                else
                  dum.render_pipeline.push dum[Madul.PARSE_SPEC(p).ref]

              args = { }
              name = new Date().toString()

              for own key, val of input
                args[key] = val if EXTRACT.includes key

              render = (level) ->
                mod.craft level, input, dum.render_pipeline, delegates
                  .then -> render levels[next] if ++next < levels.length

              render levels[next]


modify README

modify README

# loopback-with-domain

run loopback server with "domain"

domain is in this context business logic, the same as Domain-Driven Design (DDD).

connection with [base-domain](https://github.com/CureApp/base-domain)

# install

```
npm install loopback-with-domain
```

# run

    lbWithDomain = require 'loopback-with-domain'

    domain = require('base-domain').createInstance(dirname: 'domain')

    config =
        admin:
            accessToken: 'Your Secret Value Here'
        server:
            port: 4000

    lbWithDomain.runWithDomain(domain, config).then ->
        # loopback started

# configs

see JSON files in "default-configs" directory.
you can set the same properties as these JSONs.

## server

 config name | meaning       | default
-------------|---------------|----------------
 restApiRoot | REST api root | /api
 port        | port number   | 3000

## admin

 config name | meaning               | default
-------------|-----------------------|----------------------------
 accessToken | accessToken for admin | (you must set access token)

# loopback-with-domain

run loopback server with "domain"

domain is in this context business logic, the same as Domain-Driven Design (DDD).

connection with [base-domain](https://github.com/CureApp/base-domain)

# install

```
npm install loopback-with-domain
```

# run

    lbWithDomain = require 'loopback-with-domain'

    domain = require('base-domain').createInstance(dirname: 'domain')

    config =
        admin:
            accessToken: 'Your Secret Value Here'
        server:
            port: 4000

    lbWithDomain.runWithDomain(domain, config).then ->
        # loopback started

# configs

## server

 config name | meaning       | default
-------------|---------------|----------------
 restApiRoot | REST api root | /api
 port        | port number   | 3000

## admin

 config name | meaning               | default
-------------|-----------------------|----------------------------
 accessToken | accessToken for admin | (you must set access token)


Convert the day sched display to use the new helper

Day Schedule Table Manager
==========================

We first set everything in a callback, so that it is invoked only
after the loading of the DOM.

    $ ->

Input
-----

We are interested in two key nuggets of input information: the full day
schedule, and the current item within it.

        inputStream = Bacon.combineTemplate
            schedule: Data.daySchedule
            current: CurrentDSItem

Table Management
----------------

We use D3 to set the data within the table.

        nodeHTML = (entry) ->
            dateString = FormatTime(FromUNIX(entry.start), false)
            "#{dateString}
             #{entry.displayName}	"

        inputStream.onValue (state) ->
            DisplayInformation '#day-sched-table',
                               state.schedule,
                               'tr', nodeHTML,
                               (nodes) ->
                                   nodes.classed 'info', (entry) ->
                                       entry.key == state.current?.key

Day Schedule Table Manager
==========================

We first set everything in a callback, so that it is invoked only
after the loading of the DOM.

    $ ->

Input
-----

We are interested in two key nuggets of input information: the full day
schedule, and the current item within it.

        inputStream = Bacon.combineTemplate
            schedule: Data.daySchedule
            current: CurrentDSItem

Table Management
----------------

We use D3 to set the data within the table.

        nodeHTML = (entry) ->
            dateString = FormatTime(FromUNIX(entry.start), false)
            "#{dateString}
             #{entry.displayName}	"

        inputStream.onValue (state) ->
            tableNodes = d3.select('#day-sched-table')
                           .selectAll('tr')
                           .data(state.schedule)
                           .html(nodeHTML)
                           .classed 'info', (entry) ->
                               entry.key == state.current?.key

            tableNodes.enter()
                      .append('tr')
                      .html(nodeHTML)
                      .classed 'info', (entry) ->
                          entry.key == state.current?.key

            tableNodes.exit()
                      .remove()


Improve JS documentation

Improve JS documentation

Frontend JavaScript for nodePush
================================
Copyright Information
---------------------

	"@author	Tim Düsterhus"
	"@copyright	2012-2013 Tim Düsterhus"
	"@license	BSD 3-Clause License <http://opensource.org/licenses/BSD-3-Clause>"
	"@package	be.bastelstu.wcf.nodePush"

Setup
-----
Ensure sane values for `$` and `window`

	(($, window) ->
		# Enable strict mode
		"use strict";

		# Ensure our namespace is present
		window.be ?= {}
		be.bastelstu ?= {}
		be.bastelstu.wcf ?= {}

Overwrite `console` to add the origin in front of the message

		console =
			log: (message) ->
				window.console.log "[be.bastelstu.wcf.nodePush] #{message}"
			warn: (message) ->
				window.console.warn "[be.bastelstu.wcf.nodePush] #{message}"
			error: (message) ->
				window.console.error "[be.bastelstu.wcf.nodePush] #{message}"

be.bastelstu.Chat
=================

Private Attributes
------------------

		socket = null
		connected = false
		initialized = false
		events =
			connect: $.Callbacks()
			disconnect: $.Callbacks()
			message: { }

		be.bastelstu.wcf.nodePush =

Methods
-------

**init(host)**
Initialize socket.io to enable nodePush.

			init: (host) ->
				return if initialized
				initialized = true
				console.log 'Initializing nodePush'

				unless window.io?
					console.error 'nodePush not available, aborting'
					return

				socket = window.io.connect host

				socket.on 'connect', =>
					connected = true
					console.log 'Connected to nodePush'
					events.connect.fire()

				socket.on 'disconnect', =>
					connected = false
					console.warn 'Lost connection to nodePush'
					events.disconnect.fire()

				socket.on 'message', (message) =>
					return unless events.message[message]?

					events.message[message].fire()

**onConnect(callback)**
Adds a new `callback` that will be called when a connection to nodePush is established. The given
`callback` will be called once if a connection is established at time of calling. Returns `true`
on success and `false` otherwise.

			onConnect: (callback) ->
				return false unless $.isFunction callback

				events.connect.add callback

				callback() if connected
				true

**onDisconnect(callback)**
Adds a new `callback` that will be called when the connection to nodePush is lost. Returns `true`
on success and `false` otherwise.

			onDisconnect: (callback) ->
				return false unless $.isFunction callback

				events.disconnect.add callback
				true

**onMessage(message, callback)**
Adds a new `callback` that will be called when the specified `message` is received. Returns `true`
on success and `false` otherwise.

			onMessage: (message, callback) ->
				false unless $.isFunction callback
				false unless /[a-zA-Z0-9-_.]+$/.test message

				events.message[message] ?= $.Callbacks()
				events.message[message].add callback
				true

	)(jQuery, @)

Frontend JavaScript for nodePush
================================
Copyright Information
---------------------

	"@author	Tim Düsterhus"
	"@copyright	2012-2013 Tim Düsterhus"
	"@license	BSD 3-Clause License <http://opensource.org/licenses/BSD-3-Clause>"
	"@package	be.bastelstu.wcf.nodePush"

Setup
-----
Ensure sane values for `$` and `window`

	(($, window) ->
		# Enable strict mode
		"use strict";

		# Ensure our namespace is present
		window.be ?= {}
		be.bastelstu ?= {}
		be.bastelstu.wcf ?= {}

Overwrite `console` to add the origin in front of the message

		console =
			log: (message) ->
				window.console.log "[be.bastelstu.wcf.nodePush] #{message}"
			warn: (message) ->
				window.console.warn "[be.bastelstu.wcf.nodePush] #{message}"
			error: (message) ->
				window.console.error "[be.bastelstu.wcf.nodePush] #{message}"

be.bastelstu.Chat
=================

Private Attributes
------------------

		socket = null
		connected = false
		initialized = false
		events =
			connect: $.Callbacks()
			disconnect: $.Callbacks()
			message: { }

		be.bastelstu.wcf.nodePush =

Methods
-------

**init(host)**
Initialize socket.io to enable nodePush.

			init: (host) ->
				return if initialized
				initialized = true
				console.log 'Initializing nodePush'

				unless window.io?
					console.error 'nodePush not available, aborting'
					return

				socket = window.io.connect host

				socket.on 'connect', =>
					connected = true
					console.log 'Connected to nodePush'
					events.connect.fire()

				socket.on 'disconnect', =>
					connected = false
					console.warn 'Lost connection to nodePush'
					events.disconnect.fire()

				socket.on 'message', (message) =>
					return unless events.message[message]?

					events.message[message].fire()

**onConnect(callback)**
Adds a new callback that will be called when a connection to nodePush is established. The given
callback will be called once if a connection is established at time of calling.

			onConnect: (callback) ->
				return unless $.isFunction callback

				events.connect.add callback

				callback() if connected
				undefined

**onDisconnect(callback)**
Adds a new callback that will be called when the connection to nodePush is lost.

			onDisconnect: (callback) ->
				return unless $.isFunction callback

				events.disconnect.add callback
				undefined

**onMessage(message, callback)**
Adds a new callback that will be called when the specified message is received.

			onMessage: (message, callback) ->
				return unless $.isFunction callback

				events.message[message] ?= $.Callbacks()
				events.message[message].add callback
				undefined

	)(jQuery, @)


Return image exifdata

Return image exifdata

    compression  = require 'compression'
    express      = require 'express'
    errorHandler = require 'errorhandler'
    morgan       = require 'morgan'
    responseTime = require 'response-time'

    multer       = require 'multer'
    async        = require 'async'

    raven        = require 'raven'
    sentry       = require './sentry'

    app = express()
    app.use morgan 'combined'
    app.use compression()
    app.use responseTime()

    Upload = require 's3-uploader'
    s3 = new Upload process.env.AWS_BUCKET_NAME,
      awsBucketUrl: "https://s3-eu-west-1.amazonaws.com/#{process.env.AWS_BUCKET_NAME}/"
      awsBucketPath: process.env.AWS_BUCKET_PATH
      awsBucketAcl: 'public-read'
      awsHttpTimeout: 60000
      returnExif: true

      versions: [{
        original: true
        awsImageAcl: 'private'
      },{
        suffix: '-large'
        quality: 80
        maxHeight: 1040
        maxWidth: 1040
      },{
        suffix: '-medium'
        maxHeight: 780
        maxWidth: 780
      },{
        suffix: '-small'
        maxHeight: 320
        maxWidth: 320
      }]

    origins = process.env.ALLOW_ORIGINS?.split(',') or []

    app.all '/upload', (req, res, next) ->
      res.once 'close', -> sentry.captureResClose res

      if not req.get('Origin') or not (req.get('Origin') in origins)
        return res.status(403).json message: 'Bad Origin Header'

      res.set 'Access-Control-Allow-Origin', req.get('Origin')
      res.set 'Access-Control-Allow-Methods', 'POST'
      res.set 'Access-Control-Allow-Headers', 'X-Requested-With, Content-Type'
      res.set 'Access-Control-Expose-Headers', 'X-Response-Time'
      res.set 'Access-Control-Allow-Max-Age', 0

      return res.send 200 if req.method is 'OPTIONS'
      return next()

    app.post '/upload', multer(dest: require('os').tmpdir()), (req, res, next) ->
      console.log "Recieved #{Object.keys(req.files).length} files"

      async.mapSeries Object.keys(req.files), (key, cb) ->
        # @TODO check if file is valid image
        s3.upload req.files[key].path, {}, (err, images, meta) ->
          return cb err if err
          return cb null, versions: images.splice(1), meta: meta
      , (err, files) ->
        return next err if err
        sentry.captureHeaderSent req, files if res._headerSent
        return res.status(201).json files

    app.use raven.middleware.express sentry
    app.use errorHandler dumpExceptions: true, showStack: true

    if not module.parent
      app.listen process.env.PORT_WWW
      console.log "Server listening on port #{process.env.PORT_WWW}"
    else
      module.exports = app

    compression  = require 'compression'
    express      = require 'express'
    errorHandler = require 'errorhandler'
    morgan       = require 'morgan'
    responseTime = require 'response-time'

    multer       = require 'multer'
    async        = require 'async'

    raven        = require 'raven'
    sentry       = require './sentry'

    app = express()
    app.use morgan 'combined'
    app.use compression()
    app.use responseTime()

    Upload = require 's3-uploader'
    s3 = new Upload process.env.AWS_BUCKET_NAME,
      awsBucketUrl: "https://s3-eu-west-1.amazonaws.com/#{process.env.AWS_BUCKET_NAME}/"
      awsBucketPath: process.env.AWS_BUCKET_PATH
      awsBucketAcl: 'public-read'
      awsHttpTimeout: 60000

      versions: [{
        original: true
        awsImageAcl: 'private'
      },{
        suffix: '-large'
        quality: 80
        maxHeight: 1040
        maxWidth: 1040
      },{
        suffix: '-medium'
        maxHeight: 780
        maxWidth: 780
      },{
        suffix: '-small'
        maxHeight: 320
        maxWidth: 320
      }]

    origins = process.env.ALLOW_ORIGINS?.split(',') or []

    app.all '/upload', (req, res, next) ->
      res.once 'close', -> sentry.captureResClose res

      if not req.get('Origin') or not (req.get('Origin') in origins)
        return res.status(403).json message: 'Bad Origin Header'

      res.set 'Access-Control-Allow-Origin', req.get('Origin')
      res.set 'Access-Control-Allow-Methods', 'POST'
      res.set 'Access-Control-Allow-Headers', 'X-Requested-With, Content-Type'
      res.set 'Access-Control-Expose-Headers', 'X-Response-Time'
      res.set 'Access-Control-Allow-Max-Age', 0

      return res.send 200 if req.method is 'OPTIONS'
      return next()

    app.post '/upload', multer(dest: require('os').tmpdir()), (req, res, next) ->
      console.log "Recieved #{Object.keys(req.files).length} files"

      async.mapSeries Object.keys(req.files), (key, cb) ->
        # @TODO check if file is valid image
        s3.upload req.files[key].path, {}, (err, images, meta) ->
          return cb err if err
          return cb null, images.splice(1)
      , (err, files) ->
        return next err if err
        sentry.captureHeaderSent req, files if res._headerSent
        return res.status(201).json files

    app.use raven.middleware.express sentry
    app.use errorHandler dumpExceptions: true, showStack: true

    if not module.parent
      app.listen process.env.PORT_WWW
      console.log "Server listening on port #{process.env.PORT_WWW}"
    else
      module.exports = app


Updated docs so the examples are not executed as tests

# /api/App Components/Batman.App

`Batman.App` manages routing and action dispatching, as well as the initial start of the application. It is also the namespace for all `Batman.Model`s, `Batman.Controller`s, and `Batman.View`s. Only one `Batman.App` can be running on a page.

A batman.js application extends `Batman.App`. It is never instantiated and it is started by calling `run`.

```coffeescript
class @MyApp extends Batman.App
  @root 'blogPosts#index'

  @on 'run', -> alert("Welcome to my blog!")

class MyApp.BlogPostsController extends Batman.Controller
  index: -> @set('blogPosts', MyApp.BlogPost.get('all'))

class MyApp.BlogPost extends Batman.Model
  # model definition ...

MyApp.run()
```

See [`Batman.App` routing](/docs/api/batman.app_routing.html) for information about batman.js routing.

## @%current : App

The currently-running `Batman.App`. Also available at `Batman.currentApp`.

## @run()

Initializes the `Batman.App` class by:

- Closing any already-running apps
- Creates its [`dispatcher`](/docs/api/batman.app.html#class_accessor_navigator) and [`navigator`](/docs/api/batman.app.html#class_accessor_navigator) and starts the navigator.
- Instantiating the `layout` view according to the `layout` property on the `App`
- Emitting `run`

`@run` can be called before or on the `load` DOMEvent of the window.

```coffeescript
# JavaScript:
window.addEventListener 'load', ->
  MyApp.run()
# or jQuery:
$ ->
  MyApp.run()
```

## @stop() : App

Stops the `App`. The URL will stop being monitored and no more actions will be dispatched. You generally shouldn't have to call this.

## @%routes : NamedRouteQuery

Returns the `Batman.NamedRouteQuery` which allows for binding to routes on objects. See the [`data-route` binding](batman.view_bindings.html#data-route) for more information.

## @%controllers : ControllerDirectory

Returns the `Batman.ControllerDirectory` for application. `Batman.Controller` instances are accessible at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

    test "Multi-word controller names have a lowercase first letter", ->
      class Alfred extends Batman.App
      class Alfred.ReminderEmailsController extends Batman.Controller
      controller = Alfred.get('controllers.reminderEmails')
      equal Batman._functionName(controller.constructor), "ReminderEmailsController"

_Note:_ `@controllers` should not be observed, but it is very useful for debugging.

## @.layout

`@layout` is the base view of the entire view hierarchy. By default, it will parse any `data-*` attributes in the entire document, excluding any `data-yield`'s, when `App.run()` is called. Use `MyApp.layout = null` to disable the creation of this default view.

## @%currentURL : String

The request path relative to `Batman.config.pathToApp`, including query string.

## @%currentParams : Batman.Params

Returns the URL parameters for the current request, including the path relative to the app's base path (`Batman.config.pathToApp`). It includes named parameters (eg `id` from `/items/:id`), query string parameters (eg `key` of `?key=value`).

`currentParams` also offers a way to change the current request URL's parameters without refreshing or reloading anything on the page. This way you can influence data on the page and allow your users to get the same data on hard refreshes. Here's an example:

```coffeescript
Batman.currentApp.get('currentParams.url').update(page: 5)
```

It will even update the URL match a defined route if found:

```coffeescript
Batman.currentApp.get('currentParams.url').update(action: show, id: 6) # /items/6
Batman.currentApp.get('currentParams.url').update(page: 5) # /items/page/5
```

## @%currentRoute : ControllerActionRoute

The `Batman.ControllerActionRoute` for the current route, which exposes routing information such as `controller` and `action`.

## @%navigator : Navigator

The `App`'s `Batman.Navigator` instance.

## @%dispatcher : Dispatcher
## @%routeMap : RouteMap
## @%routeMapBuilder : RouteMapBuilder
## @paramsManager : ParamsReplacer
## @paramsPusher : ParamsPusher

## 'run' class event

`run` is fired after a successful `run`.

## 'ready' class event

`ready` is fired after the app's layout is rendered.

# /api/App Components/Batman.App

`Batman.App` manages routing and action dispatching, as well as the initial start of the application. It is also the namespace for all `Batman.Model`s, `Batman.Controller`s, and `Batman.View`s. Only one `Batman.App` can be running on a page.

A batman.js application extends `Batman.App`. It is never instantiated and it is started by calling `run`.

```coffeescript
class @MyApp extends Batman.App
  @root 'blogPosts#index'

  @on 'run', -> alert("Welcome to my blog!")

class MyApp.BlogPostsController extends Batman.Controller
  index: -> @set('blogPosts', MyApp.BlogPost.get('all'))

class MyApp.BlogPost extends Batman.Model
  # model definition ...

MyApp.run()
```

See [`Batman.App` routing](/docs/api/batman.app_routing.html) for information about batman.js routing.

## @%current : App

The currently-running `Batman.App`. Also available at `Batman.currentApp`.

## @run()

Initializes the `Batman.App` class by:

- Closing any already-running apps
- Creates its [`dispatcher`](/docs/api/batman.app.html#class_accessor_navigator) and [`navigator`](/docs/api/batman.app.html#class_accessor_navigator) and starts the navigator.
- Instantiating the `layout` view according to the `layout` property on the `App`
- Emitting `run`

`@run` can be called before or on the `load` DOMEvent of the window.

```coffeescript
# JavaScript:
window.addEventListener 'load', ->
  MyApp.run()
# or jQuery:
$ ->
  MyApp.run()
```

## @stop() : App

Stops the `App`. The URL will stop being monitored and no more actions will be dispatched. You generally shouldn't have to call this.

## @%routes : NamedRouteQuery

Returns the `Batman.NamedRouteQuery` which allows for binding to routes on objects. See the [`data-route` binding](batman.view_bindings.html#data-route) for more information.

## @%controllers : ControllerDirectory

Returns the `Batman.ControllerDirectory` for application. `Batman.Controller` instances are accessible at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

    test "Multi-word controller names have a lowercase first letter", ->
      class Alfred extends Batman.App
      class Alfred.ReminderEmailsController extends Batman.Controller
      controller = Alfred.get('controllers.reminderEmails')
      equal Batman._functionName(controller.constructor), "ReminderEmailsController"

_Note:_ `@controllers` should not be observed, but it is very useful for debugging.

## @.layout

`@layout` is the base view of the entire view hierarchy. By default, it will parse any `data-*` attributes in the entire document, excluding any `data-yield`'s, when `App.run()` is called. Use `MyApp.layout = null` to disable the creation of this default view.

## @%currentURL : String

The request path relative to `Batman.config.pathToApp`, including query string.

## @%currentParams : Batman.Params

Returns the URL parameters for the current request, including the path relative to the app's base path (`Batman.config.pathToApp`). It includes named parameters (eg `id` from `/items/:id`), query string parameters (eg `key` of `?key=value`).

`currentParams` also offers a way to change the current request URL's parameters without refreshing or reloading anything on the page. This way you can influence data on the page and allow your users to get the same data on hard refreshes. Here's an example:

    Batman.currentApp.get('currentParams.url').update(page: 5)

It will even update the URL match a defined route if found:

    Batman.currentApp.get('currentParams.url').update(action: show, id: 6) # /items/6
    Batman.currentApp.get('currentParams.url').update(page: 5) # /items/page/5

## @%currentRoute : ControllerActionRoute

The `Batman.ControllerActionRoute` for the current route, which exposes routing information such as `controller` and `action`.

## @%navigator : Navigator

The `App`'s `Batman.Navigator` instance.

## @%dispatcher : Dispatcher
## @%routeMap : RouteMap
## @%routeMapBuilder : RouteMapBuilder
## @paramsManager : ParamsReplacer
## @paramsPusher : ParamsPusher

## 'run' class event

`run` is fired after a successful `run`.

## 'ready' class event

`ready` is fired after the app's layout is rendered.


add this.next() to route filter

add this.next() to route filter

# Iron-router configuration

    Router.configure
      layoutTemplate: 'layout'
      loadingTemplate: 'loading'

## Filters

    filters =
      isLoggedIn: ->
        Router.go 'home' unless Meteor.loggingIn() or Meteor.user()
        this.next()

Login filter, except public routes

    Router.onBeforeAction filters.isLoggedIn,
      except: [
        'home'
        'about'
        'atSignIn'
        'atSignUp'
        'atForgotPwd'
        'atResetPwd'
        'atVerifyEmail'
        'atEnrollAccount'
        'atChangePwd'
      ]

# Iron-router configuration

    Router.configure
      layoutTemplate: 'layout'
      loadingTemplate: 'loading'

## Filters

    filters =
      isLoggedIn: ->
        Router.go 'home' unless Meteor.loggingIn() or Meteor.user()

Login filter, except public routes

    Router.onBeforeAction filters.isLoggedIn,
      except: [
        'home'
        'about'
        'atSignIn'
        'atSignUp'
        'atForgotPwd'
        'atResetPwd'
        'atVerifyEmail'
        'atEnrollAccount'
        'atChangePwd'
      ]