sumatra-rails 0.0.3.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +8 -8
  2. data/Gemfile.lock +32 -32
  3. data/lib/sumatra/rails/version.rb +1 -1
  4. data/sumatra-rails.gemspec +1 -1
  5. data/vendor/assets/javascripts/sumatra.js.coffee +1 -121
  6. data/vendor/assets/javascripts/sumatra/.env.example +1 -0
  7. data/vendor/assets/javascripts/sumatra/.gitignore +2 -0
  8. data/vendor/assets/javascripts/sumatra/Cakefile +27 -0
  9. data/vendor/assets/javascripts/sumatra/LICENSE.md +20 -0
  10. data/vendor/assets/javascripts/sumatra/README.md +183 -0
  11. data/vendor/assets/javascripts/sumatra/component.json +30 -0
  12. data/vendor/assets/javascripts/sumatra/docs/docco.css +500 -0
  13. data/vendor/assets/javascripts/sumatra/docs/index.html +177 -0
  14. data/vendor/assets/javascripts/sumatra/docs/index.md +0 -0
  15. data/vendor/assets/javascripts/sumatra/docs/plugin.js.html +207 -0
  16. data/vendor/assets/javascripts/sumatra/docs/public/fonts/aller-bold.eot +0 -0
  17. data/vendor/assets/javascripts/sumatra/docs/public/fonts/aller-bold.ttf +0 -0
  18. data/vendor/assets/javascripts/sumatra/docs/public/fonts/aller-bold.woff +0 -0
  19. data/vendor/assets/javascripts/sumatra/docs/public/fonts/aller-light.eot +0 -0
  20. data/vendor/assets/javascripts/sumatra/docs/public/fonts/aller-light.ttf +0 -0
  21. data/vendor/assets/javascripts/sumatra/docs/public/fonts/aller-light.woff +0 -0
  22. data/vendor/assets/javascripts/sumatra/docs/public/fonts/fleurons.eot +0 -0
  23. data/vendor/assets/javascripts/sumatra/docs/public/fonts/fleurons.ttf +0 -0
  24. data/vendor/assets/javascripts/sumatra/docs/public/fonts/fleurons.woff +0 -0
  25. data/vendor/assets/javascripts/sumatra/docs/public/fonts/novecento-bold.eot +0 -0
  26. data/vendor/assets/javascripts/sumatra/docs/public/fonts/novecento-bold.ttf +0 -0
  27. data/vendor/assets/javascripts/sumatra/docs/public/fonts/novecento-bold.woff +0 -0
  28. data/vendor/assets/javascripts/sumatra/docs/public/images/gray.png +0 -0
  29. data/vendor/assets/javascripts/sumatra/docs/public/stylesheets/normalize.css +375 -0
  30. data/vendor/assets/javascripts/sumatra/docs/runtime.js.html +111 -0
  31. metadata +29 -4
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmFmY2ZmN2IxMWU4NjJkNWQ0ZTExODEzNGZhYTE5NjQ0Mzc2ZWFjZQ==
4
+ YzY4MTVkNTJhZWQ4OTQxNjUyYjhlNjc1MjlmM2YzNjFkZGIyOGM4OQ==
5
5
  data.tar.gz: !binary |-
6
- ZTU2MzU3MmYxMzkzNWE3N2JhM2QxNThlZDA4MjE0YjJiZmQ5ODU2Nw==
6
+ OGEzMzc2NmQyNTg0MGU1NmUzODlhYmU3Mzk5N2UzOTZjMjBmYjI3Mg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MDc4ZDRkZjdhZjBlYTQ1OTI4NjNmYzUzYjhjMTc3NWJkNWI3ZmY1N2IyNTg1
10
- NGFkMWUxM2VmMzBlNGY2YjViMzI0MWQwYjhkNDRjZmY2ZjUxZGJiZmZmYTJj
11
- OWU1Nzk2OWZhZGM4NzEyZGM3NTQ2YmY0YjkxODZhOGJlODYyODM=
9
+ YzU1ZGNjNjRmMWY5MGEyMjA5NzI0YTRkYjk2N2E2MjkxNzZlYjMzM2JlNTNj
10
+ YjQ0ZTQ4NjYxYmMwMDdiZGNjYWM5OGJkYzRkZDZiMDAwMGYzMjkzZTZmZjRm
11
+ ZWJhNjUyYmZjNjI2NTBlNTliMzZkYTNlOWRjMTcxYzRlYmY3YjU=
12
12
  data.tar.gz: !binary |-
13
- Mjc4YmQ2MjdmZDU5NDY0NTRmMWE5NDQyZDVjNzU1ZWE0NGRjYjRlYmVkY2Rk
14
- ZDJmOGVkNTYyNDlmOTg0MjZjYzM4YTc5YmUyNDBmMTU1OTJmYjZiNzAzYzMy
15
- ZDhjOGM0ZjAxZGIyNDY1YTA1NDZjMmYxMjQ5ZDk1ZTA1YjFhMjY=
13
+ YTcyYmNkN2IwZjQ1MTAzODE1MWMyNTdkNDAwZjljZTQxN2NlZWI5YzQ5Yzk3
14
+ MDU1NWFiNmQ0MmRjNTkzOTExOTFiODYwYjZkMjgzNTM2OWJlZDNkZTVlNWZm
15
+ ZWFmZGQ2OGE0MTEwMzgzYmM2MzFmZjU3ZDczZjA3MzdkOGY4ZWE=
data/Gemfile.lock CHANGED
@@ -1,20 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sumatra-rails (0.0.3.1)
4
+ sumatra-rails (0.0.4)
5
5
  coffee-rails
6
6
  jquery-rails
7
- rails (~> 3.2.12)
7
+ rails (~> 3.2)
8
8
 
9
9
  GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
- actionmailer (3.2.12)
13
- actionpack (= 3.2.12)
14
- mail (~> 2.4.4)
15
- actionpack (3.2.12)
16
- activemodel (= 3.2.12)
17
- activesupport (= 3.2.12)
12
+ actionmailer (3.2.13)
13
+ actionpack (= 3.2.13)
14
+ mail (~> 2.5.3)
15
+ actionpack (3.2.13)
16
+ activemodel (= 3.2.13)
17
+ activesupport (= 3.2.13)
18
18
  builder (~> 3.0.0)
19
19
  erubis (~> 2.7.0)
20
20
  journey (~> 1.0.4)
@@ -22,19 +22,19 @@ GEM
22
22
  rack-cache (~> 1.2)
23
23
  rack-test (~> 0.6.1)
24
24
  sprockets (~> 2.2.1)
25
- activemodel (3.2.12)
26
- activesupport (= 3.2.12)
25
+ activemodel (3.2.13)
26
+ activesupport (= 3.2.13)
27
27
  builder (~> 3.0.0)
28
- activerecord (3.2.12)
29
- activemodel (= 3.2.12)
30
- activesupport (= 3.2.12)
28
+ activerecord (3.2.13)
29
+ activemodel (= 3.2.13)
30
+ activesupport (= 3.2.13)
31
31
  arel (~> 3.0.2)
32
32
  tzinfo (~> 0.3.29)
33
- activeresource (3.2.12)
34
- activemodel (= 3.2.12)
35
- activesupport (= 3.2.12)
36
- activesupport (3.2.12)
37
- i18n (~> 0.6)
33
+ activeresource (3.2.13)
34
+ activemodel (= 3.2.13)
35
+ activesupport (= 3.2.13)
36
+ activesupport (3.2.13)
37
+ i18n (= 0.6.1)
38
38
  multi_json (~> 1.0)
39
39
  arel (3.0.2)
40
40
  builder (3.0.4)
@@ -49,18 +49,18 @@ GEM
49
49
  execjs (1.4.0)
50
50
  multi_json (~> 1.0)
51
51
  hike (1.2.1)
52
- i18n (0.6.4)
52
+ i18n (0.6.1)
53
53
  journey (1.0.4)
54
54
  jquery-rails (2.2.1)
55
55
  railties (>= 3.0, < 5.0)
56
56
  thor (>= 0.14, < 2.0)
57
57
  json (1.7.7)
58
- mail (2.4.4)
58
+ mail (2.5.3)
59
59
  i18n (>= 0.4.0)
60
60
  mime-types (~> 1.16)
61
61
  treetop (~> 1.4.8)
62
62
  mime-types (1.21)
63
- multi_json (1.6.1)
63
+ multi_json (1.7.1)
64
64
  polyglot (0.3.3)
65
65
  rack (1.4.5)
66
66
  rack-cache (1.2)
@@ -69,17 +69,17 @@ GEM
69
69
  rack
70
70
  rack-test (0.6.2)
71
71
  rack (>= 1.0)
72
- rails (3.2.12)
73
- actionmailer (= 3.2.12)
74
- actionpack (= 3.2.12)
75
- activerecord (= 3.2.12)
76
- activeresource (= 3.2.12)
77
- activesupport (= 3.2.12)
72
+ rails (3.2.13)
73
+ actionmailer (= 3.2.13)
74
+ actionpack (= 3.2.13)
75
+ activerecord (= 3.2.13)
76
+ activeresource (= 3.2.13)
77
+ activesupport (= 3.2.13)
78
78
  bundler (~> 1.0)
79
- railties (= 3.2.12)
80
- railties (3.2.12)
81
- actionpack (= 3.2.12)
82
- activesupport (= 3.2.12)
79
+ railties (= 3.2.13)
80
+ railties (3.2.13)
81
+ actionpack (= 3.2.13)
82
+ activesupport (= 3.2.13)
83
83
  rack-ssl (~> 1.3.2)
84
84
  rake (>= 0.8.7)
85
85
  rdoc (~> 3.4)
@@ -93,7 +93,7 @@ GEM
93
93
  rack (~> 1.0)
94
94
  tilt (~> 1.1, != 1.3.0)
95
95
  thor (0.17.0)
96
- tilt (1.3.5)
96
+ tilt (1.3.6)
97
97
  treetop (1.4.12)
98
98
  polyglot
99
99
  polyglot (>= 0.3.1)
@@ -1,5 +1,5 @@
1
1
  module Sumatra
2
2
  module Rails
3
- VERSION = "0.0.3.1"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = Dir["test/**/*"]
18
18
 
19
- s.add_dependency "rails", "~> 3.2.12"
19
+ s.add_dependency "rails", "~> 3.2"
20
20
  s.add_dependency "jquery-rails"
21
21
  s.add_dependency "coffee-rails"
22
22
  end
@@ -1,121 +1 @@
1
- # SumatraPlugin
2
- # -------------
3
- #
4
- # A prototype object for common actions when defining jQuery plugins
5
- # in the Sumatra framework. It is designed so that you never have to
6
- # override the constructor. Instead, the constructor sets up a common
7
- # method interface for both initialization (which would happen after
8
- # construction) and the binding of events, a common task in jQuery
9
- # plugins. This prototype even handles some of that for you, with
10
- # the default `bindEvents()` being bound to call the `perform()`
11
- # method (which must be defined by the object extending `SumatraPlugin`)
12
- # whenever the element it was constructed with triggers the event
13
- # defined by `action`.
14
- #
15
- # So essentially, you can define almost any jQuery plugin using this
16
- # interface, even though the only thing binding it to the `sumatra`
17
- # function is its constructor that takes 3 parameters.
18
- #
19
- # `SumatraPlugin` also has facilities for dealing with an options hash
20
- # and merging said options with defaults. You can define the default
21
- # options for your plugin like so:
22
- #
23
- # sumatra 'clickToGo', ->
24
- # class ClickToGo extends SumatraPlugin
25
- # action: 'click'
26
- # defaults: { to: 'http://google.com' }
27
- # perform: (event) =>
28
- # if confirm "Are you sure you want to go to #{@options.goTo}?"
29
- # window.location = @options.goTo
30
- #
31
- # Then, when instantiating, just override them.
32
- #
33
- # $('a').clickToGo(to: 'http://yahoo.com');
34
- #
35
- # This removes the need for writing that boilerplate options hash extend
36
- # code every time you write a jQuery plugin that takes options. All
37
- # plugins defined with `sumatra()` take an optional options hash, which is
38
- # `{}` by default, in case your plugin doesn't require options.
39
- class @SumatraPlugin
40
- # The event to bind to if `perform()` is defined.
41
- action: 'one'
42
-
43
- # A hash of attributes that are extended with an options hash passed
44
- # into the jQuery plugin upon instantiation. Useful for setting up
45
- # data that is required.
46
- defaults: {}
47
-
48
- # Instantiate a `SumatraPlugin` and bind it to the current element
49
- # with options. This also initiates the workflow.
50
- #
51
- # **DO NOT OVERRIDE!!**
52
- constructor: (current_element, index_of_query, init_options) ->
53
- @element = $(current_element)
54
- @index = index_of_query
55
- @options = @mergeDefaultsWith init_options
56
- @initialize() and @bindEvents()
57
-
58
- # Merge `options` hash with the `defaults` as set in the definition
59
- # of this object.
60
- mergeDefaultsWith: (options) ->
61
- _.extend @defaults, @options
62
-
63
- # Run custom constructor code, but blocks instantiation if this method
64
- # returns `false`. This method was pretty much designed to be overridden.
65
- initialize: ->
66
- true
67
-
68
- # Bind the `perform()` method to the `action` as set in the definition
69
- # of this plugin. Overriding this method removes the guarantee that
70
- # perform() will be called at all...
71
- bindEvents: ->
72
- if @action?
73
- @element.on @action, @perform
74
-
75
- # The event binding that handles `action`. Override this with your own
76
- # method. You must override this method or the `bindEvents` method to
77
- # get this plugin to do anything. It takes a single argument, `event`,
78
- # which represents the given DOMEvent represented by `action` as passed
79
- # in by `jQuery.on`.
80
- perform: null
81
-
82
- # SumatraRuntime
83
- # --------------
84
- #
85
- # Defines a jQuery plugin using a service object with a nice,
86
- # consistent, CoffeeScript-style interface. Plugins can extend
87
- # `SumatraPlugin`, a prototype that makes defining plugins with
88
- # Sumatra easier.
89
- #
90
- # The runtime function returns the generated jQuery plugin to the
91
- # global scope so it can be used in your application code.
92
- #
93
- # Arguments:
94
- #
95
- # - **plugin_name:** The jQuery plugin name, called like `$('div').myPlugin();`
96
- # - **plugin_code:** A function that will be executed immediately and must return
97
- # a single object that takes 3 parameters in its constructor. These parameters
98
- # are the `element` being targeted by jQuery, the `index` at which it appears
99
- # in the query, and the `options` hash passed during the instantiation of the
100
- # jQuery plugin.
101
- #
102
- # Example:
103
- #
104
- # sumatra 'myPlugin', ->
105
- # class MyPlugin extends SumatraPlugin
106
- # action: null
107
- # initialize:
108
- # alert 'loaded'
109
- #
110
- @sumatra = (plugin_name, plugin_code) ->
111
- # Instantiate a PluginHelper and apply the current scope. This can
112
- # be any object that responds to 3 parameters in its constructor
113
- # and will be set to whatever is returned by `plugin_code()`.
114
- PluginHelper = plugin_code.apply this
115
-
116
- jQuery.fn[plugin_name] = (options={}) ->
117
- @each (index, element) ->
118
- # For each element, create a `PluginHelper` instance
119
- # of the passed-in `plugin_code` and apply the jQuery
120
- # plugin parameters to the constructor.
121
- new PluginHelper(element, index, options)
1
+ #= require_tree sumatra/pkg
@@ -0,0 +1 @@
1
+ PATH=node_modules/.bin:$PATH
@@ -0,0 +1,2 @@
1
+ node_modules
2
+ components/sumatra/
@@ -0,0 +1,27 @@
1
+ {exec} = require 'child_process'
2
+
3
+ task 'build:javascript', "Compile Sumatra into JavaScript", ->
4
+ exec 'coffee --join pkg/sumatra.js --compile lib/sumatra/*.coffee'
5
+
6
+ task 'build:coffeescript', "Compile Sumatra into CoffeeScript", ->
7
+ fs = require 'fs'
8
+ src = fs.readFileSync 'lib/sumatra/plugin.js.coffee'
9
+ src += fs.readFileSync 'lib/sumatra/runtime.js.coffee'
10
+ fs.writeFile 'pkg/sumatra.coffee', src, (err) ->
11
+ throw err if err
12
+ true
13
+
14
+ task 'build', "Compile Sumatra into both languages", ->
15
+ invoke 'build:coffeescript'
16
+ invoke 'build:javascript'
17
+
18
+ task 'test', "Run all tests", ->
19
+ exec "NODE_ENV=test
20
+ mocha
21
+ --compilers coffee:coffee-script
22
+ --require coffee-script
23
+ --require test/test_helper.js.coffee
24
+ --colors
25
+ ", (err, output) ->
26
+ throw err if err
27
+ console.log output
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Tom Scott
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,183 @@
1
+ # Sumatra
2
+
3
+ Sumatra is a CoffeeScript framework for writing jQuery plugins harder,
4
+ better, faster, stronger.
5
+
6
+ You should use Sumatra if you...
7
+
8
+ - Encapsulate complex jQuery plugins in a service object and call an
9
+ instance of that service object for each DOM element the plugin
10
+ selector is passed
11
+ - Enjoy test-driven development, clear code, and convention over
12
+ configuration
13
+ - Believe unicorns are real
14
+
15
+ ## Why?
16
+
17
+ A lot of jQuery plugins are written to encapsulate a simple bit of
18
+ functionality used throughout the application. But jQuery's syntax was
19
+ designed to improve the way people write JavaScript. CoffeeScript has a
20
+ similar goal, but approaches it from a different angle, it compiles its
21
+ syntax into JavaScript but does so in a safe, syntactically correct and
22
+ (mostly) readable way. This framework unites the two, and finally allows
23
+ jQuery developers to build plugins in CoffeeScript without making their
24
+ code look, well, downright ugly!
25
+
26
+ ## Installation
27
+
28
+ ### Requirements
29
+
30
+ - jQuery
31
+ - CoffeeScript if you want to develop it..
32
+
33
+ We recommend Bower for installing Sumatra as a component:
34
+
35
+ ```bash
36
+ $ bower install sumatra
37
+ ```
38
+
39
+ However, you can also install Sumatra manually by just including the
40
+ `pkg/sumatra.js` file in your javascripts directory.
41
+
42
+ ## Usage
43
+
44
+ Sumatra values convention over configuration, and its usage revolves
45
+ around an established pattern that hopefully others will find useful.
46
+
47
+ ### Defining a Basic Plugin
48
+
49
+ After loading Sumatra, you can build jQuery plugins that are both clear
50
+ and superbly terse:
51
+
52
+ ```coffeescript
53
+ sumatra 'clickMe', ->
54
+ class ClickMe extends SumatraPlugin
55
+ action: 'click'
56
+ perform: (event) =>
57
+ element_id = @element.attr('id') || '<div>'
58
+ alert "You just clicked #{element_id}!"
59
+ ```
60
+
61
+ All this plugin does is show an `alert()` when the element is clicked.
62
+ You can define a single action with `action:` and then define the
63
+ `perform()` event handler that binds to whatever action you've set
64
+ on the element.
65
+
66
+ To bind an element to this event, just call it like any normal
67
+ jQuery plugin:
68
+
69
+ ```coffeescript
70
+ $('#my_element').clickMe();
71
+ ```
72
+
73
+ ### Parameters
74
+
75
+ You can also make plugins that pass in options. All Sumatra plugins
76
+ take an `options` hash as their only argument, regardless of whether
77
+ the service object uses them or not.
78
+
79
+ ```coffeescript
80
+ sumatra 'ajaxSubmit', ->
81
+ class AjaxSubmit extends SumatraPlugin
82
+ action: 'submit'
83
+ mergeOptions: ->
84
+ @defaults = @_getFormDefaults()
85
+ _.extend(@options, @defaults)
86
+
87
+ perform: (event) =>
88
+ event.preventDefault()
89
+ event.stopPropagation()
90
+ $.ajax @options
91
+
92
+ _getFormDefaults: ->
93
+ {
94
+ url: @element.attr('action')
95
+ type: @element.attr('method')
96
+ error: (message, status, xhr) ->
97
+ console.log status, message, xhr
98
+ alert "#{status}: #{message}"
99
+ }
100
+ ```
101
+
102
+ This is an example of [ajaxSubmit from the jQuery.form plugin][jqform],
103
+ implemented using Sumatra. It would especially be useful when rendering
104
+ an inline response with JSON, using something such as Handlebars to
105
+ compile the JSON data into a logic-less client-side template...
106
+
107
+ ```coffeescript
108
+ $('form').ajaxSubmit \
109
+ dataType: 'json'
110
+ success: (context) =>
111
+ template = Handlebars.compile $('#response_template')
112
+ response = template(context)
113
+ @element.html response
114
+ ```
115
+
116
+ ### Basic Properties
117
+
118
+ As a by-product of the jQuery instantation process, each `SumatraPlugin`
119
+ comes with the following three properties, for free:
120
+
121
+ - **element:** References a single jQuery DOM Object, which can perform
122
+ basic functionality on the page. It is obtained from the collection of
123
+ objects which matched the plugin's selector upon instantiation.
124
+ - **index:** The index of the jQuery DOM Object in the collection of
125
+ objects which matched the plugin's selector upon instantiation.
126
+ - **options:** A Hash-notated Object obtained as the only argument in
127
+ the jQuery plugin when instantiated. This object is then merged with
128
+ the `defaults` hash, which are default params in the plugin's
129
+ definition, before initialization occurs.
130
+
131
+ ### Workflow
132
+
133
+ Each SumatraPlugin has a "workflow" that is expressed as a series of
134
+ methods, all run in the `constructor` of the object. The constructor
135
+ is responsible for setup of the object's basic properties. This method
136
+ should never be overridden, instead, each step of the instantiation
137
+ process can be controlled by overriding one of the following methods:
138
+
139
+ - **mergeOptions:** Merge the options with the defaults hash. You can
140
+ override this to use attributes from `@element` as defaults instead.
141
+ - **initialize:** The main override of the constructor method, this is
142
+ where one would actually "construct" the objects they are going to be
143
+ using in this plugin instance, bind events, and call helper methods.
144
+ - **bindEvents:** This is where the `action:` event should be bound in
145
+ some way. In many cases, this is overridden to bind other events as
146
+ well as the `action:`, or binding the event as a `$(document).on`.
147
+ - **perform:** The event handler of the plugin, this is normally called
148
+ when the `action:` event is fired, but it must be defined if it is
149
+ called or it will throw an error.
150
+
151
+ You can define more methods, but these are the only public methods that
152
+ should be overridden. Any method beginning with `_` is considered
153
+ "private" and should not be overridden. Please carry this convention
154
+ to your own code as well.
155
+
156
+ ## Development
157
+
158
+ You can build this code into JavaScript by running the following
159
+ command at the root dir:
160
+
161
+ ```bash
162
+ $ npm install && cake build
163
+ ```
164
+
165
+ ### Contributions
166
+
167
+ Contributions will be accepted via Git/GitHub pull requests, as long as
168
+ you write tests that prove your contributions work. We use Jasmine to
169
+ write tests in CoffeeScript (you know, for the actual framework?) and
170
+ RSpec to write tests for the Rails helpers.
171
+
172
+ ### Releases
173
+
174
+ All releases will be made in both CoffeeScript and JavaScript, and
175
+ available simultaneously on the Bower and RubyGems package managers.
176
+ We use Bower to manage the standalone JavaScript code which has no
177
+ dependency on Sprockets, Rails, or anything Ruby.
178
+
179
+ This code is released under the [MIT License][LICENSE].
180
+
181
+ [jqform]: http://jquery.malsup.com/form
182
+ [LICENSE]: https://github.com/tubbo/sumatra/blob/master/LICENSE.md
183
+ [engine]: http://github.com/tubbo/sumatra-rails