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 +19 -0
- data/README.md +260 -0
- data/lib/haml_coffee_assets.rb +13 -0
- data/lib/haml_coffee_assets/engine.rb +36 -0
- data/lib/haml_coffee_assets/haml_coffee.rb +72 -0
- data/lib/haml_coffee_assets/haml_coffee_assets.js +64 -0
- data/lib/haml_coffee_assets/haml_coffee_template.rb +40 -0
- data/lib/haml_coffee_assets/version.rb +5 -0
- data/lib/js/coffee-script.js +8 -0
- data/lib/js/haml-coffee.js +752 -0
- data/lib/tasks/haml-coffee-rails_tasks.rake +4 -0
- metadata +221 -0
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, '&')
|
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
|
+
})();
|