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.
@@ -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: []