haml_coffee_assets 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Michael Kessler <michi@netzpiraten.ch>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # HamlCoffeeAssets [![Build Status](https://secure.travis-ci.org/netzpirat/haml_coffee_assets.png)](http://travis-ci.org/netzpirat/haml_coffee_assets)
2
+
3
+ HamlCoffeeAssets compiles [Haml CoffeeScript](https://github.com/9elements/haml-coffee) templates in the Rails 3.1 asset
4
+ pipeline.
5
+
6
+ Tested on MRI Ruby 1.8.7, 1.9.2, REE and the latest versions of JRuby.
7
+
8
+ ## HamlCoffee
9
+
10
+ HamlCoffee allows you to write inline [CoffeeScript](http://jashkenas.github.com/coffee-script/) in your
11
+ [HAML](http://haml-lang.com/) template:
12
+
13
+ ```haml
14
+ #cart
15
+ %h2= I18n.t('js.cart.title')
16
+ - if @cart.length == 0
17
+ %p.empty= I18n.t('js.cart.empty')
18
+ - else
19
+ %ul
20
+ - for item in @cart
21
+ %li
22
+ .item
23
+ = item.name
24
+ %a{ :href => "/cart/item/remove/#{ item.id }" }
25
+ = I18n.t('js.cart.item.remove')
26
+ ```
27
+
28
+ ## Installation
29
+
30
+ The simplest way to install Guard is to use [Bundler](http://gembundler.com/).
31
+ Add `haml_coffee_assets` and `execjs` to your `Gemfile`:
32
+
33
+ ```ruby
34
+ group :assets do
35
+ gem 'haml_coffee_assets'
36
+ gem 'execjs'
37
+ end
38
+ ```
39
+
40
+ And require the `hamlcoffee.js` in your `application.js.coffee`
41
+
42
+ ```coffeescript
43
+ #= require hamlcoffee
44
+ ```
45
+
46
+ ### JavaScript runtimes
47
+
48
+ HamlCoffeeAssets uses [ExecJS](https://github.com/sstephenson/execjs) to pick the best runtime to evaluate the
49
+ CoffeeScript and generate the JavaScript template.
50
+
51
+ * With CRuby you want to use a V8 JavaScript Engine or Mozilla SpiderMonkey.
52
+ * With JRuby you want to use the Mozilla Rhino.
53
+ * On Mac OS X you want to use Apple JavaScriptCore.
54
+ * On Linux or as a node.js developer you want to use Node.js (V8).
55
+ * On Windows you want to use Microsoft Windows Script Host.
56
+
57
+ The following sections gives you a short overview of the available JavaScript runtimes and how to install it.
58
+
59
+ ### Node.js (V8)
60
+
61
+ You can install [node.js](http://nodejs.org/) and use its V8 engine. On OS X you may want to install it with
62
+ [Homebrew](http://mxcl.github.com/homebrew/), on Linux with your package manager and on Windows you have to download and
63
+ install the [executable](http://www.nodejs.org/#download).
64
+
65
+ ### V8 JavaScript Engine
66
+
67
+ To use the [V8 JavaScript Engine](http://code.google.com/p/v8/), simple add `therubyracer` to your `Gemfile`.
68
+ The Ruby Racer acts as a bridge between Ruby and the V8 engine, that will be automatically installed by the Ruby Racer.
69
+
70
+ ```ruby
71
+ group :development do
72
+ gem 'therubyracer'
73
+ end
74
+ ```
75
+
76
+ Another alternative is [Mustang](https://github.com/nu7hatch/mustang), a Ruby proxy library for the awesome Google V8
77
+ JavaScript engine. Just add `mustang` to your `Gemfile`:
78
+
79
+ ```ruby
80
+ group :development do
81
+ gem 'mustang'
82
+ end
83
+ ```
84
+
85
+ ### Mozilla SpiderMonkey
86
+
87
+ To use [Mozilla SpiderMonkey](https://developer.mozilla.org/en/SpiderMonkey), simple add `johnson` to your `Gemfile`.
88
+ Johnson embeds the Mozilla SpiderMonkey JavaScript runtime as a C extension.
89
+
90
+ ```ruby
91
+ group :development do
92
+ gem 'johnson'
93
+ end
94
+ ```
95
+
96
+ ### Mozilla Rhino
97
+
98
+ If you're using JRuby, you can embed the [Mozilla Rhino](http://www.mozilla.org/rhino/) runtime by adding `therubyrhino`
99
+ to your `Gemfile`:
100
+
101
+ ```ruby
102
+ group :development do
103
+ gem 'therubyrhino'
104
+ end
105
+ ```
106
+
107
+ ### Apple JavaScriptCore
108
+
109
+ [JavaScriptCore](http://developer.apple.com/library/mac/#documentation/Carbon/Reference/WebKit_JavaScriptCore_Ref/index.html)
110
+ is Safari's Nitro JavaScript Engine and only usable on Mac OS X. You don't have to install anything, because
111
+ JavaScriptCore is already packaged with Mac OS X.
112
+
113
+ ### Microsoft Windows Script Host
114
+
115
+ [Microsoft Windows Script Host](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) is available on any Microsoft
116
+ Windows operating systems.
117
+
118
+ ## Usage
119
+
120
+ You should place all your HamlCoffee templates in the `app/assets/templates` directory and include all templates in
121
+ your `application.js.coffee`:
122
+
123
+ ```coffeescript
124
+ #= require_tree ../templates
125
+ ```
126
+
127
+ Now you can start to add your HamlCoffee templates to your template directory. Make sure all your templates have a
128
+ `.hamlc` extension to be recognized by HamlCoffeeAssets.
129
+
130
+ **Note:** HamlCoffee already generates a JavaScript Template, so there is not need to pass it to the `JST` Sprocket
131
+ processor by using `.jst.hamlc` as extension, and if you do, the HamlCoffee templates will not work.
132
+
133
+ ## Configuration
134
+
135
+ ### Template namespace
136
+
137
+ By default all HamlCoffee templates are registered under the `JST` namespace.
138
+
139
+ Example:
140
+
141
+ A template located in `app/assets/templates/header.hamlc` with the given content:
142
+
143
+ ```haml
144
+ %header
145
+ %h2= title
146
+ ```
147
+
148
+ will be accessible in your browser as `JST.header`. You can now render the precompiled template with:
149
+
150
+ ```javascript
151
+ JST.header.render({ title: 'Hello HamlCoffee' })
152
+ ```
153
+
154
+ If you prefer another namespace, you can set it in your `application.rb`:
155
+
156
+ ```ruby
157
+ config.hamlcoffee.namespace = 'HAML'
158
+ ```
159
+
160
+ ### Escaping
161
+
162
+ By default your code block in your HamlCoffee template will be escaped through the `HAML.escape` function that is
163
+ provided in the `haml_coffee_assets.js`.
164
+
165
+ You can set another escaping function in your `application.rb`:
166
+
167
+ ```ruby
168
+ config.hamlcoffee.escape = 'App.myEscape'
169
+ ```
170
+
171
+ or disable escaping completely:
172
+
173
+ ```ruby
174
+ config.hamlcoffee.escape = false
175
+ ```
176
+
177
+ Your custom escape function must take the unescaped text as parameter and returns the escape function.
178
+ The following example implements only ampersand escaping:
179
+
180
+ ```coffeescript
181
+ App.myEscape = (text) -> text.replace(/&/g, '&amp;')
182
+ ```
183
+
184
+ ### Global Context
185
+
186
+ HamlCoffeeAssets allows you to configure a global context function that gets merged into the local template context for
187
+ each template.
188
+
189
+ There is a example implementation provided in the `haml_coffee_assets.js` that uses the `extend` function
190
+ from these frameworks:
191
+
192
+ * jQuery
193
+ * Underscore.js
194
+ * Prototype
195
+ * MooTools
196
+ * Zepto.js
197
+
198
+ If you use one of these, than you can simply override `HAML.globals` and return the global HAML context object:
199
+
200
+ ```coffeescript
201
+ HAML.globals = ->
202
+ {
203
+ authenticated: App.isAuthenticated()
204
+ isAdmin: App.currentUser.hasRole('admin')
205
+ }
206
+ ```
207
+
208
+ If you like to use your own implementation, simply configure your context function in your `application.rb`:
209
+
210
+ ```ruby
211
+ config.hamlcoffee.context = 'App.globalTemplateContext'
212
+ ```
213
+
214
+ or disable the global context completely:
215
+
216
+ ```ruby
217
+ config.hamlcoffee.context = false
218
+ ```
219
+
220
+ Your custom context function must take the local context as parameter and returns the merged context function.
221
+ The following example implementation used the _.underscore extend function to merge an inline defined global
222
+ context:
223
+
224
+ ```coffeescript
225
+ App.globalTemplateContext = (locals) -> _.extend({}, {
226
+ authenticated: App.isAuthenticated()
227
+ }, locals)
228
+ ```
229
+
230
+ ## Acknowledgement
231
+
232
+ * [Jeremy Ashkenas](http://twitter.com/#!/jashkenas) for CoffeeScript, that little language that compiles into
233
+ JavaScript.
234
+ * The people at [9elements](https://github.com/9elements) who gave us
235
+ [haml-coffee](https://github.com/9elements/haml-coffee), an elegant JavaScript template solution.
236
+
237
+ ## License
238
+
239
+ (The MIT License)
240
+
241
+ Copyright (c) 2011 Michael Kessler
242
+
243
+ Permission is hereby granted, free of charge, to any person obtaining
244
+ a copy of this software and associated documentation files (the
245
+ 'Software'), to deal in the Software without restriction, including
246
+ without limitation the rights to use, copy, modify, merge, publish,
247
+ distribute, sublicense, and/or sell copies of the Software, and to
248
+ permit persons to whom the Software is furnished to do so, subject to
249
+ the following conditions:
250
+
251
+ The above copyright notice and this permission notice shall be
252
+ included in all copies or substantial portions of the Software.
253
+
254
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
255
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
256
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
257
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
258
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
259
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
260
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # coding: UTF-8
2
+
3
+ require 'pathname'
4
+
5
+ require 'rails'
6
+ require 'tilt'
7
+ require 'sprockets'
8
+ require 'execjs'
9
+
10
+ require 'haml_coffee_assets/version'
11
+ require 'haml_coffee_assets/haml_coffee'
12
+ require 'haml_coffee_assets/haml_coffee_template'
13
+ require 'haml_coffee_assets/engine'
@@ -0,0 +1,36 @@
1
+ # coding: UTF-8
2
+
3
+ module HamlCoffeeAssets
4
+
5
+ # Hook the Haml CoffeeScript template into a Rails app.
6
+ #
7
+ class Engine < Rails::Engine
8
+
9
+ config.hamlcoffee = ActiveSupport::OrderedOptions.new
10
+
11
+ DEFAULT_CONFIG = {
12
+ :namespace => 'HAML',
13
+ :escape => 'HAML.escape',
14
+ :context => 'HAML.context'
15
+ }
16
+
17
+ # Initialize Haml Coffee Assets after Sprockets
18
+ #
19
+ initializer 'sprockets.hamlcoffeeassets', :after => 'sprockets.environment' do |app|
20
+ next unless app.assets
21
+
22
+ # Register tilt template
23
+ app.assets.register_engine '.hamlc', HamlCoffeeTemplate
24
+
25
+ # Set application configuration for the HAML templates.
26
+ options = DEFAULT_CONFIG.merge(app.config.hamlcoffee)
27
+
28
+ HamlCoffee.configure do |config|
29
+ config.namespace = options[:namespace]
30
+ config.escape = options[:escape]
31
+ config.context = options[:context]
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,72 @@
1
+ # coding: UTF-8
2
+
3
+ module HamlCoffeeAssets
4
+
5
+ # Handles compilation of Haml CoffeeScript templates to pure JavaScript.
6
+ #
7
+ module HamlCoffee
8
+ class << self
9
+
10
+ mattr_accessor :namespace, :escape, :context
11
+
12
+ # Configure HamlCoffee
13
+ #
14
+ def configure
15
+ yield self
16
+ end
17
+
18
+ # Compile the Haml CoffeeScript template.
19
+ #
20
+ # @param [String] name the template name
21
+ # @param [String] source the template source code
22
+ # @return [String] the compiled template in JavaScript
23
+ #
24
+ def compile(name, source)
25
+ runtime.call('HamlCoffeeAssets.compile', namespace, name, source, escape, context)
26
+ end
27
+
28
+ private
29
+
30
+ # Get the context to compile Haml CoffeeScript templates.
31
+ #
32
+ # @return [Runtime] the JS runtime
33
+ #
34
+ def runtime
35
+ @runtime ||= ExecJS.compile(source)
36
+ end
37
+
38
+ # Get the combined source of haml-coffee and CoffeeScript.
39
+ #
40
+ # @return [String] the source code
41
+ #
42
+ def source
43
+ coffeescript + ';' + haml_coffee + ';' + haml_coffee_assets
44
+ end
45
+
46
+ # Get the Haml CoffeeScript Assets source code.
47
+ #
48
+ # @return [String] the source
49
+ #
50
+ def haml_coffee_assets
51
+ Pathname.new(__FILE__).dirname.join('haml_coffee_assets.js').read
52
+ end
53
+
54
+ # Get the Haml CoffeeScript source code.
55
+ #
56
+ # @return [String] the source
57
+ #
58
+ def haml_coffee
59
+ Pathname.new(__FILE__).dirname.join('..', 'js', 'haml-coffee.js').read
60
+ end
61
+
62
+ # Get the CoffeeScript source code.
63
+ #
64
+ # @return [String] the source
65
+ #
66
+ def coffeescript
67
+ Pathname.new(__FILE__).dirname.join('..', 'js', 'coffee-script.js').read
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Fix for the Ruby Rhino
3
+ */
4
+ if (!String.prototype.trim) {
5
+ String.prototype.trim = function () {
6
+ return this.replace(/^\s*/, "").replace(/\s*$/, "");
7
+ }
8
+ }
9
+
10
+ /**
11
+ * Haml Coffee Asset compiler.
12
+ */
13
+ var HamlCoffeeAssets = (function(){
14
+
15
+ var Compiler = require('/compiler.js');
16
+
17
+ /**
18
+ * Test if the argument is present
19
+ *
20
+ * @param object [Object] the object to test
21
+ * @return [Boolean] whether the object is present
22
+ */
23
+ function isPresent(object) {
24
+ return toString.call(object) === '[object String]' && object.length !== 0
25
+ }
26
+
27
+ return {
28
+
29
+ /**
30
+ * Compile the HAML Coffee template to JavaScript
31
+ *
32
+ * @param namespace [String] the template namespace
33
+ * @param name [String] the name of the template that is registered to the namespace
34
+ * @param source [String] the template source code to be compiled
35
+ * @param escape [String] the name of the function to escape the output
36
+ * @param context [String] the name of the function to merge contexts
37
+ */
38
+ compile: function(namespace, name, source, escape, context) {
39
+
40
+ var compiler, jst;
41
+
42
+ if (!isPresent(namespace)) {
43
+ namespace = 'HAML'
44
+ }
45
+
46
+ if (isPresent(escape)) {
47
+ compiler = new Compiler({ escape_html: true, custom_html_escape: escape });
48
+ } else {
49
+ compiler = new Compiler({ escape_html: false });
50
+ }
51
+
52
+ compiler.parse(source);
53
+
54
+ jst = CoffeeScript.compile(compiler.render(name, namespace));
55
+
56
+ if (isPresent(context)) {
57
+ jst = jst.replace('fn.call(context);', 'fn.call(' + context +'(context));');
58
+ }
59
+
60
+ return jst;
61
+ }
62
+
63
+ }
64
+ })();