minispade-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,94 @@
1
+ # minispade-rails [![Build Status](https://secure.travis-ci.org/keithpitt/minispade-rails.png)](http://travis-ci.org/keithpitt/minispade-rails) [![Dependency Status](https://gemnasium.com/keithpitt/minispade-rails.png)](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,15 @@
1
+ module MinispadeRails
2
+
3
+ module Config
4
+
5
+ def self.deferred=(val)
6
+ @deferred = val
7
+ end
8
+
9
+ def self.deferred
10
+ @deferred
11
+ end
12
+
13
+ end
14
+
15
+ 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,9 @@
1
+ module MinispadeRails
2
+ class Railtie < Rails::Engine
3
+
4
+ initializer :setup_minispade do |app|
5
+ app.assets.register_preprocessor 'application/javascript', MinispadeRails::DirectiveProcessor
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module MinispadeRails
2
+ VERSION = "0.0.1"
3
+ 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: []