vendor/assets/javascripts/sumatra.js.coffee in sumatra-rails-0.0.4.1 vs vendor/assets/javascripts/sumatra.js.coffee in sumatra-rails-0.0.5
- old
+ new
@@ -1,121 +1,242 @@
-#= require_tree ./sumatra/pkg
+# SumatraPlugin
+# -------------
+#
+# A prototype object for common actions when defining jQuery plugins
+# in the Sumatra framework. It is designed so that you never have to
+# override the constructor. Instead, the constructor sets up a common
+# method interface for both initialization (which would happen after
+# construction) and the binding of events, a common task in jQuery
+# plugins. This prototype even handles some of that for you, with
+# the default `bindEvents()` being bound to call the `perform()`
+# method (which must be defined by the object extending `SumatraPlugin`)
+# whenever the element it was constructed with triggers the event
+# defined by `action`.
+#
+# So essentially, you can define almost any jQuery plugin using this
+# interface, even though the only thing binding it to the `sumatra`
+# function is its constructor that takes 3 parameters.
+#
+# `SumatraPlugin` also has facilities for dealing with an options hash
+# and merging said options with defaults. You can define the default
+# options for your plugin like so:
+#
+# sumatra 'clickToGo', ->
+# class ClickToGo extends SumatraPlugin
+# action: 'click'
+# defaults: { to: 'http://google.com' }
+# perform: (event) =>
+# if confirm "Are you sure you want to go to #{@options.goTo}?"
+# window.location = @options.goTo
+#
+# Then, when instantiating, just override them.
+#
+# $('a').clickToGo(to: 'http://yahoo.com');
+#
+# This removes the need for writing that boilerplate options hash extend
+# code every time you write a jQuery plugin that takes options. All
+# plugins defined with `sumatra()` take an optional options hash, which is
+# `{}` by default, in case your plugin doesn't require options.
+class @SumatraPlugin
+ # The event to bind to if `perform()` is defined.
+ action: 'one'
+
+ # A hash of attributes that are extended with an options hash passed
+ # into the jQuery plugin upon instantiation. Useful for setting up
+ # data that is required.
+ defaults: {}
+
+ # Instantiate a `SumatraPlugin` and bind it to the current element
+ # with options. This also initiates the workflow.
+ #
+ # **DO NOT OVERRIDE!!**
+ constructor: (current_element, index_of_query, init_options) ->
+ @element = $(current_element)
+ @index = index_of_query
+ @options = @mergeDefaultsWith init_options
+ @element.data 'serviceObject', this
+ @initialize() and @bindEvents()
+
+ # Merge `options` hash with the `defaults` as set in the definition
+ # of this object.
+ mergeDefaultsWith: (options) ->
+ _.extend @defaults, @options
+
+ # Run custom constructor code, but blocks instantiation if this method
+ # returns `false`. This method was pretty much designed to be overridden.
+ initialize: ->
+ true
+
+ # Bind the `perform()` method to the `action` as set in the definition
+ # of this plugin. Overriding this method removes the guarantee that
+ # perform() will be called at all...
+ bindEvents: ->
+ if @action?
+ @element.on @action, @perform
+
+ # The event binding that handles `action`. Override this with your own
+ # method. You must override this method or the `bindEvents` method to
+ # get this plugin to do anything. It takes a single argument, `event`,
+ # which represents the given DOMEvent represented by `action` as passed
+ # in by `jQuery.on`.
+ perform: null
+
+# SumatraRuntime
+# --------------
+#
+# Defines a jQuery plugin using a service object with a nice,
+# consistent, CoffeeScript-style interface. Plugins can extend
+# `SumatraPlugin`, a prototype that makes defining plugins with
+# Sumatra easier.
+#
+# The runtime function returns the generated jQuery plugin to the
+# global scope so it can be used in your application code.
+#
+# Arguments:
+#
+# - **plugin_name:** The jQuery plugin name, called like `$('div').myPlugin();`
+# - **plugin_code:** A function that will be executed immediately and must return
+# a single object that takes 3 parameters in its constructor. These parameters
+# are the `element` being targeted by jQuery, the `index` at which it appears
+# in the query, and the `options` hash passed during the instantiation of the
+# jQuery plugin.
+#
+# Example:
+#
+# sumatra 'myPlugin', ->
+# class MyPlugin extends SumatraPlugin
+# action: null
+# initialize:
+# alert 'loaded'
+#
+@sumatra = (plugin_name, plugin_code) ->
+ # Instantiate a PluginHelper and apply the current scope. This can
+ # be any object that responds to 3 parameters in its constructor
+ # and will be set to whatever is returned by `plugin_code()`.
+ PluginHelper = plugin_code.apply this
+
+ jQuery.fn[plugin_name] = (options={}) ->
+ @each (index, element) ->
+ # For each element, create a `PluginHelper` instance
+ # of the passed-in `plugin_code` and apply the jQuery
+ # plugin parameters to the constructor.
+ new PluginHelper(element, index, options)