minispade-rails 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +94 -0
- data/lib/minispade-rails.rb +12 -0
- data/lib/minispade-rails/compiler.rb +28 -0
- data/lib/minispade-rails/config.rb +15 -0
- data/lib/minispade-rails/directive_processor.rb +56 -0
- data/lib/minispade-rails/railtie.rb +9 -0
- data/lib/minispade-rails/version.rb +3 -0
- data/vendor/assets/javascripts/minispade.js +51 -0
- metadata +70 -0
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# minispade-rails [](http://travis-ci.org/keithpitt/minispade-rails) [](https://gemnasium.com/keithpitt/minispade-rails)
|
2
|
+
|
3
|
+
For large JavaScript applications, you need to include and parse alot of JavaScript just to start showing something on the page. minispade-rails allows you to defer the parsing of parts of your application until you need it.
|
4
|
+
|
5
|
+
minispade-rails allows you to compile your javascript files into strings that can be required at runtime using [minispade.js](https://github.com/wycats/minispade)
|
6
|
+
|
7
|
+
To understand the problem that minispade-rails solves, read [AMD is Not the Answer](http://tomdale.net/2012/01/amd-is-not-the-answer/) by [@tomdale](http://github.com/tomdale) and [Lazy evaluation of CommonJS modules](http://calendar.perfplanet.com/2011/lazy-evaluation-of-commonjs-modules/) by [Tobie Langel](http://tobielangel.com/)
|
8
|
+
|
9
|
+
## Getting started
|
10
|
+
|
11
|
+
Add the gem to your application Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem "minispade-rails"
|
15
|
+
```
|
16
|
+
|
17
|
+
Then replace `require_tree` with `require_spade` and things should _"just work"_, for example:
|
18
|
+
|
19
|
+
```javascript
|
20
|
+
//= require_tree ./your_application
|
21
|
+
// Becomes...
|
22
|
+
//= require_spade ./your_application
|
23
|
+
```
|
24
|
+
|
25
|
+
## What does require_spade do?
|
26
|
+
|
27
|
+
Usually, `require_tree` will recursively go through your folder structure, compile the asset, and drop it into the current file. So you get something that looks like this:
|
28
|
+
|
29
|
+
```javascript
|
30
|
+
// path/to/file_1.js
|
31
|
+
(function() {
|
32
|
+
alert('File #1');
|
33
|
+
}).call(this)
|
34
|
+
// path/to/file_2.js
|
35
|
+
(function() {
|
36
|
+
alert('File #2');
|
37
|
+
}).call(this)
|
38
|
+
// path/to/file_3.js
|
39
|
+
(function() {
|
40
|
+
alert('File #3');
|
41
|
+
}).call(this)
|
42
|
+
```
|
43
|
+
|
44
|
+
What `require_spade` will do, is it will compile the asset, and drop the contents into a `minispade.register` call, like so:
|
45
|
+
|
46
|
+
```javascript
|
47
|
+
minispade.register("path/to/file_1.js", "alert('File #1')");
|
48
|
+
minispade.register("path/to/file_2.js", "alert('File #2')");
|
49
|
+
minispade.register("path/to/file_3.js", "alert('File #3')");
|
50
|
+
```
|
51
|
+
|
52
|
+
Then during your application code, as you need access to "file_1", you simply call `minispade.require` like so:
|
53
|
+
|
54
|
+
```javascript
|
55
|
+
minispade.require("path/to/file_1.js")
|
56
|
+
```
|
57
|
+
|
58
|
+
And it will execute the file. If you've already called `minispade.require` before on the same file, it will do nothing. Note that calling `minispade.require` is a synchronous function call.
|
59
|
+
|
60
|
+
## Configuration
|
61
|
+
|
62
|
+
The only configuration option that minispade-rails supports at the moment is the ability to switch on/off using a string to defer the parsing of the JavaScript.
|
63
|
+
|
64
|
+
Setting `MinispadeRails::Config.deferred` in an initializer to `true` will cause the following output:
|
65
|
+
|
66
|
+
```javascript
|
67
|
+
minispade.register("path/to/file_1.js", "alert('File #1')");
|
68
|
+
```
|
69
|
+
|
70
|
+
Setting it to `false` will give you something like this:
|
71
|
+
|
72
|
+
```javascript
|
73
|
+
minispade.register("path/to/file_1.js", function() { alert('File #1') });
|
74
|
+
```
|
75
|
+
|
76
|
+
Sometimes, evaling code is actually slower than just parsing it. If you have a very small app, but want to future-proof the code, then setting `deferred` to false early on, will give you faster loading times.
|
77
|
+
|
78
|
+
See http://blog.sproutcore.com/faster-loading-through-eval/ for more details.
|
79
|
+
|
80
|
+
## Contributors / Credits
|
81
|
+
|
82
|
+
Thanks to the following:
|
83
|
+
|
84
|
+
- [@robmonie](http://twitter.com/robmonie) and [@hassox](http://twitter.com/hassox) for suggesting that this gem could be possible.
|
85
|
+
- [@wycats](http://github.com/wycats) for writing minispade.js
|
86
|
+
- [@tomdale](http://github.com/tomdale) for writing his excellent article on AMD
|
87
|
+
|
88
|
+
## Note on Patches/Pull Requests
|
89
|
+
|
90
|
+
1. Fork the project.
|
91
|
+
2. Make your feature addition or bug fix.
|
92
|
+
3. Add tests for it. This is important so I don't break it in a future version unintentionally.
|
93
|
+
4. Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
94
|
+
5. Send me a pull request. Bonus points for topic branches.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
require 'sprockets/engines'
|
3
|
+
|
4
|
+
require "minispade-rails/config"
|
5
|
+
require 'minispade-rails/directive_processor'
|
6
|
+
require 'minispade-rails/compiler'
|
7
|
+
require 'minispade-rails/railtie'
|
8
|
+
require "minispade-rails/version"
|
9
|
+
|
10
|
+
module MinispadeRails
|
11
|
+
Sprockets.register_engine '.spade', MinispadeRails::Compiler
|
12
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module MinispadeRails
|
4
|
+
|
5
|
+
# = Sprockets engine for Minispade templates
|
6
|
+
class Compiler < Tilt::Template
|
7
|
+
|
8
|
+
def self.default_mime_type
|
9
|
+
'application/javascript'
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize_engine
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
end
|
17
|
+
|
18
|
+
def evaluate(scope, locals, &block)
|
19
|
+
if MinispadeRails::Config.deferred
|
20
|
+
"minispade.register(\"#{scope.logical_path}\", #{data.inspect});\n"
|
21
|
+
else
|
22
|
+
"minispade.register(\"#{scope.logical_path}\", function() { #{data} });\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module MinispadeRails
|
2
|
+
class DirectiveProcessor < Sprockets::DirectiveProcessor
|
3
|
+
|
4
|
+
def process_source
|
5
|
+
super
|
6
|
+
|
7
|
+
if @spades
|
8
|
+
output = @spades.map do |spade|
|
9
|
+
# Create a custom context for the spade require
|
10
|
+
attributes = context.environment.attributes_for(spade)
|
11
|
+
spade_context = context.environment.context_class.new(context.environment, attributes.logical_path, spade)
|
12
|
+
|
13
|
+
# Add the minispade custom processor as the last item
|
14
|
+
processors = [ *attributes.processors, MinispadeRails::Compiler ]
|
15
|
+
|
16
|
+
# Remove the directive processors for the individual file
|
17
|
+
processors.delete(Sprockets::DirectiveProcessor)
|
18
|
+
|
19
|
+
# Evaluate the spade
|
20
|
+
spade_context.evaluate(spade, :processors => processors)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Prepend the requires
|
24
|
+
@result = output.join("") + @result
|
25
|
+
end
|
26
|
+
|
27
|
+
@result
|
28
|
+
end
|
29
|
+
|
30
|
+
def process_require_spade_directive(path = ".")
|
31
|
+
if relative?(path)
|
32
|
+
root = pathname.dirname.join(path).expand_path
|
33
|
+
|
34
|
+
unless (stats = stat(root)) && stats.directory?
|
35
|
+
raise ArgumentError, "require_spade argument must be a directory"
|
36
|
+
end
|
37
|
+
|
38
|
+
context.depend_on(root)
|
39
|
+
|
40
|
+
@spades ||= []
|
41
|
+
each_entry(root) do |pathname|
|
42
|
+
if context.asset_requirable?(pathname)
|
43
|
+
context.depend_on pathname
|
44
|
+
@spades << pathname
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
# The path must be relative and start with a `./`.
|
49
|
+
raise ArgumentError, "require_spade argument must be a relative path"
|
50
|
+
end
|
51
|
+
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
/*jshint evil:true*/
|
2
|
+
|
3
|
+
if (typeof document !== "undefined") {
|
4
|
+
(function() {
|
5
|
+
minispade = {
|
6
|
+
root: null,
|
7
|
+
modules: {},
|
8
|
+
loaded: {},
|
9
|
+
|
10
|
+
globalEval: function(data) {
|
11
|
+
if ( data ) {
|
12
|
+
// We use execScript on Internet Explorer
|
13
|
+
// We use an anonymous function so that context is window
|
14
|
+
// rather than jQuery in Firefox
|
15
|
+
( window.execScript || function( data ) {
|
16
|
+
window[ "eval" ].call( window, data );
|
17
|
+
} )( data );
|
18
|
+
}
|
19
|
+
},
|
20
|
+
|
21
|
+
require: function(name) {
|
22
|
+
var loaded = minispade.loaded[name];
|
23
|
+
var mod = minispade.modules[name];
|
24
|
+
|
25
|
+
if (!loaded) {
|
26
|
+
if (mod) {
|
27
|
+
minispade.loaded[name] = true;
|
28
|
+
|
29
|
+
if (typeof mod === "string") {
|
30
|
+
this.globalEval(mod);
|
31
|
+
} else {
|
32
|
+
mod();
|
33
|
+
}
|
34
|
+
} else {
|
35
|
+
if (minispade.root && name.substr(0,minispade.root.length) !== minispade.root) {
|
36
|
+
return minispade.require(minispade.root+name);
|
37
|
+
} else {
|
38
|
+
throw "The module '" + name + "' could not be found";
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
return loaded;
|
44
|
+
},
|
45
|
+
|
46
|
+
register: function(name, callback) {
|
47
|
+
minispade.modules[name] = callback;
|
48
|
+
}
|
49
|
+
};
|
50
|
+
})();
|
51
|
+
}
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minispade-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Keith Pitt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &70146629093640 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.1'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70146629093640
|
25
|
+
description:
|
26
|
+
email:
|
27
|
+
- me@keithpitt.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- README.md
|
33
|
+
- lib/minispade-rails/compiler.rb
|
34
|
+
- lib/minispade-rails/config.rb
|
35
|
+
- lib/minispade-rails/directive_processor.rb
|
36
|
+
- lib/minispade-rails/railtie.rb
|
37
|
+
- lib/minispade-rails/version.rb
|
38
|
+
- lib/minispade-rails.rb
|
39
|
+
- vendor/assets/javascripts/minispade.js
|
40
|
+
homepage: https://github.com/keithpitt/minispade-rails
|
41
|
+
licenses: []
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
hash: 739185026345522521
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
hash: 739185026345522521
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.8.17
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Compile your javascript into minispade modules using the asset pipeline
|
70
|
+
test_files: []
|