name: Helpers

namespace: Marionette

extends:
  - Backbone.extend

description: |
  Marionette provides a set of utility/helper functions that are used to facilitate
  common behaviors throughout the framework. These functions may be useful to those that
  are building on top of Marionette, as they provide a way to get the same behaviors and
  conventions from your own code.

functions:
  extend:
    description: |
      Borrow the Backbone `extend` method so we can use it as needed
      
      @api public
      @static
      @param {Object} protoProps
      @param {Object} staticProps
      @borrows Backbone.extend as Marionette.extend
      @return {Object}
      
    examples:
      -
        name: Marionette.extend
        example: |
          Backbone's `extend` function is a useful utility to have, and is used in
          various places in Marionette. To make the use of this method more consistent,
          Backbone's `extend` has been aliased to `Marionette.extend`. This allows
          you to get the extend functionality for your object without having to
          decide if you want to use Backbone.View or Backbone.Model or another
          Backbone object to grab the method from.
          
          ```js
          var Foo = function(){};
          
          // use Marionette.extend to make Foo extendable, just like other
          // Backbone and Marionette objects
          Foo.extend = Marionette.extend;
          
          // Now Foo can be extended to create a new class, with methods
          var Bar = Foo.extend({
          
            someMethod: function(){ ... }
          
            // ...
          });
          
          // Create an instance of Bar
          var b = new Bar();
          ```

  getOption:
    description: |
      Retrieve an object, function or other value from a target object or its `options`, with
      `options` taking precedence.
      
      @api public
      @static
      @param {Object} target
      @param {String} optionName
      @return {String}

    examples:
      -
        name: getOption
        example: |
          Retrieve an object's attribute either directly from the object, or from
          the object's `this.options`, with `this.options` taking precedence.
          
          ```js
          var M = Backbone.Model.extend({
            foo: "bar",
          
            initialize: function(){
              var f = Marionette.getOption(this, "foo");
              console.log(f);
            }
          });
          
          new M(); // => "bar"
          
          new M({}, { foo: "quux" }); // => "quux"
          ```
          
          This is useful when building an object that can have configuration set
          in either the object definition or the object's constructor options.

      -
        name: Falsey Values
        example: |
          The `getOption` function will return any falsey value from the `options`,
          other than `undefined`. If an object's options has an `undefined` value, it will
          attempt to read the value from the object directly.
          
          For example:
          
          ```js
          var M = Backbone.Model.extend({
            foo: "bar",
          
            initialize: function(){
              var f = Marionette.getOption(this, "foo");
              console.log(f);
            }
          });
          
          new M(); // => "bar"
          
          var f;
          new M({}, { foo: f }); // => "bar"
          ```
          
          In this example, "bar" is returned both times because the second
          example has an `undefined` value for `f`.

  proxyGetOption:
    description: |
      Proxy `Marionette.getOption`
      
      @api public
      @static
      @param {String} optionName
      @return {String}

    examples:
      -
        name: proxyGetOption
        example: |
          This method proxies `Marionette.getOption` so that it can be easily added to an instance.
          
          Say you've written your own Pagination class and you always pass options to it.
          With `proxyGetOption`, you can easily give this class the `getOption` function.
          
          ```js
          _.extend(Pagination.prototype, {
          
            getFoo: function(){
              return this.getOption("foo");
            },
          
            getOption: Marionette.proxyGetOption
          });
          ```

  triggerMethod:
    description: |
      Trigger an event and a corresponding method on the target object.
      
      @api public
      @static
      @param {String} event
      @param {...*} [arguments]
      @return {*}

    examples:
      -
        name: triggerMethod
        example: |
          Trigger an event and a corresponding method on the target object.
          
          When an event is triggered, the first letter of each section of the
          event name is capitalized, and the word `on` is tagged on to the front
          of it. Examples:
          
          * `triggerMethod("render")` fires the `onRender` function
          * `triggerMethod("before:destroy")` fires the `onBeforeDestroy` function
          
          All arguments that are passed to the triggerMethod call are passed along to both the event and
          the method, with the exception of the event name not being passed to the corresponding method.
          
          `triggerMethod("foo", bar)` will call `onFoo: function(bar){...})`
          
          Note that `triggerMethod` can be called on objects that do not have
          `Backbone.Events` mixed in to them. These objects will not have a `trigger`
          method, and no attempt to call `.trigger()` will be made. The `on{Name}`
          callback methods will still be called, though.

  triggerMethodOn:
    description: |
      Invoke `triggerMethod` on a specific context.
      
      @api public
      @static
      @param {String} context
      @param {String} event
      @param {...*} [arguments]

    examples:
      -
        name: triggerMethodOn
        example: |
          Invoke `triggerMethod` on a specific context.
          
          This is useful when it's not clear that the object has `triggerMethod` defined. In the case of views,
          `Marionette.View` defines `triggerMethod`, but `Backbone.View` does not.
          
          ```js
          Marionette.triggerMethodOn(ctx, "foo", bar);
          // will invoke `onFoo: function(bar){...})`
          // will trigger "foo" on ctx
          ```

  bindEntityEvents:
    description: |
      Bind a backbone "entity" (collection/model) to methods on a target object.
      
      @api public
      @static
      @param {Object} target
      @param {Object} entity
      @param {Object} bindings

    examples:
      -
        name: bindEntityEvents
        example: |
          This method is used to bind a backbone "entity" (collection/model)
          to methods on a target object.
          
          ```js
          Backbone.View.extend({
          
            modelEvents: {
              "change:foo": "doSomething"
            },
          
            initialize: function(){
              Marionette.bindEntityEvents(this, this.model, this.modelEvents);
            },
          
            doSomething: function(){
              // the "change:foo" event was fired from the model
              // respond to it appropriately, here.
            }
          
          });
          ```
          
          The first parameter, `target`, must have a `listenTo` method from the
          EventBinder object.
          
          The second parameter is the entity (Backbone.Model or Backbone.Collection)
          to bind the events from.
          
          The third parameter is a hash of `{ "event:name": "eventHandler" }`
          configuration. Multiple handlers can be separated by a space. A
          function can be supplied instead of a string handler name.


  unbindEntityEvents:
    description: |
      Unbind a backbone "entity" (collection/model) to methods on a target object.
      
      @api public
      @static
      @param {Object} target
      @param {Object} entity
      @param {Object} bindings

    examples:
      -
        name: unbindEntityEvents
        example: |
          This method can be used to unbind callbacks from entities' (collection/model) events. It's
          the opposite of `bindEntityEvents`. Consequently, the APIs are identical for each method.
          
          ```js
          // Just like the above example we bind our model events.
          // This time, however, we unbind them on close.
          Backbone.View.extend({
          
            modelEvents: {
              "change:foo": "doSomething"
            },
          
            initialize: function(){
              Marionette.bindEntityEvents(this, this.model, this.modelEvents);
            },
          
            doSomething: function(){
              // the "change:foo" event was fired from the model
              // respond to it appropriately, here.
            },
          
            onClose: function() {
              Marionette.unbindEntityEvents(this, this.model, this.modelEvents);
            }
          
          });
          ```

  proxyBindEntityEvents:
    description: |
      Proxy `Marionette.bindEntityEvents`
      
      @api public
      @static
      @param {Object} entity
      @param {Object} bindings

    examples:
      -
        name: proxyBindEntityEvents
        example: |
          This method proxies `Marionette.bindEntityEvents` so that it can easily be added to an instance.
          
          Say you've written your own Pagination class and you want to easily listen to some entities events.
          With `proxyBindEntityEvents`, you can easily give this class the `bindEntityEvents` function.
          
          ```js
          _.extend(Pagination.prototype, {
          
             bindSomething: function() {
               this.bindEntityEvents(this.something, this.somethingEvents)
             },
          
             bindEntityEvents: Marionette.proxyBindEntityEvents
          
          });
          ```

  proxyUnbindEntityEvents:
    description: |
      Proxy `Marionette.unbindEntityEvents`
      
      @api public
      @static
      @param {Object} entity
      @param {Object} bindings

    examples:
      -
        name: proxyUnbindEntityEvents
        example: |
          This method proxies `Marionette.unbindEntityEvents`.
          
          Like `Marionette.proxyBindEntityEvents`, unbinding proxied events can be done similarly.
          
          ```js
          _.extend(Pagination.prototype, {
          
             bindSomething: function() {
               this.bindEntityEvents(this.something, this.somethingEvents)
             },
          
             bindEntityEvents: Marionette.proxyBindEntityEvents,
          
             unbindEntityEvents: Marionette.proxyUnbindEntityEvents
          
          });
          ```

  normalizeMethods:
    description: |
      Pass in a mapping of events to functions or function names and return a mapping of events to functions.
      
      @api public
      @static
      @param {Object} hash
      @return {Object}

    examples:
      -
        name: normalizeMethods
        example: |
          Receives a hash of event names and functions and/or function names, and returns the
          same hash with the function names replaced with the function references themselves.
          
          This function is attached to the `Marionette.View` prototype by default. To use it from non-View classes
          you'll need to attach it yourself.
          
          ```js
          var View = Marionette.ItemView.extend({
          
            initialize: function() {
              this.someFn = function() {};
              this.someOtherFn = function() {};
              var hash = {
                eventOne: "someFn", // This will become a reference to `this.someFn`
                eventTwo: this.someOtherFn
              };
              this.normalizedHash = this.normalizeMethods(hash);
            }
          
          });
          ```

  normalizeUIString:
    description: |
      Utility method for parsing `@ui.` syntax string into associated selector
      
      @api public
      @static
      @param {String} uiString
      @param {Object} ui
      @return {String}

    examples:
      -
        name: normalizeUIString
        example: |
          ```js
          var ui = {
            'list': 'ul'
          };
          
          // This turns a `ui` hash string into it's applicable selector
          var normalized = Marionette.normalizeUIString('@ui.foo', ui);          
          ```

  normalizeUIKeys:
    description: |
      Allows for the use of the @ui. syntax within a given key for triggers and events
      swaps the @ui with the associated selector
      
      @api public
      @static
      @param {Object} hash
      @param {Object} ui
      @return {Object}

    examples:
      -
        name: normalizeUIKeys
        example: |
          This method allows you to use the `@ui.` syntax within a given key for triggers and events hashes. It
          swaps the `@ui.` reference with the associated selector.
          
          ```js
          var hash = {
            'click @ui.list': 'myCb'
          };
          
          var ui = {
            'list': 'ul'
          };
          
          // This sets 'click @ui.list' to be 'click ul' in the newHash object
          var newHash = Marionette.normalizeUIKeys(hash, ui);
          ```

  normalizeUIValues:
    description: |
      Allows for the use of the @ui. syntax within a given value for regions swaps the @ui with the associated selector
      
      @api public
      @static
      @param {Object} hash
      @param {Object} ui
      @return {Object}

    examples:
      -
        name: normalizeUIValues
        example: |
          This method allows you to use the `@ui.` syntax within a given hash value (for example region hashes). It
          swaps the `@ui.` reference with the associated selector.
          
          ```js
          var hash = {
            'foo': '@ui.bar'
          };
          
          var ui = {
            'bar': '.quux'
          };
          
          // This sets 'foo' to be '.quux' in the newHash object
          var newHash = Marionette.normalizeUIValues(hash, ui);
          ```


  actAsCollection:
    description: |
      Mix in methods from Underscore, for iteration, and other collection related features. Borrowing this code
      from `Backbone.Collection`. See http://backbonejs.org/docs/backbone.html#section-121
      
      @api public
      @static
      @param {Object} object
      @param {Object} listProperty

    examples:
      -
        name: Object Literal
        example: |
          It works by taking an object and a property field, in this example 'list',
          and appending collection functions to the object so that it can
          delegate collection calls to its list.
          
          ```js
          var obj = {
            list: [1, 2, 3]
          }
          
          Marionette.actAsCollection(obj, 'list');
          
          var double = function(v){ return v*2};
          console.log(obj.map(double)); // [2, 4, 6]
          ```

      -
          name: Function Prototype
          example: |
            ```js
            var Func = function(list) {
              this.list = list;
            };
          
            Marionette.actAsCollection(Func.prototype, 'list');
            var func = new Func([1,2,3]);
          
            var double = function(v){ return v*2};
            console.log(func.map(double)); // [2, 4, 6]
            ```
