javascript_auto_include 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/Gemfile +7 -3
  2. data/Gemfile.lock +69 -19
  3. data/README.markdown +44 -12
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/lib/javascript_auto_include.rb +5 -1
  7. data/lib/javascript_auto_include/dependency.rb +13 -0
  8. data/lib/javascript_auto_include/helpers/action_view.rb +72 -19
  9. data/lib/javascript_auto_include/source_file.rb +61 -0
  10. data/spec/dependency_spec.rb +19 -0
  11. data/spec/javascript_auto_include_spec.rb +11 -0
  12. data/spec/javascript_auto_include_tag_spec.rb +9 -0
  13. data/spec/source_file_spec.rb +52 -0
  14. data/spec/spec_helper.rb +21 -0
  15. data/spec/testbed/Gemfile +7 -0
  16. data/spec/testbed/Gemfile.lock +86 -0
  17. data/spec/testbed/Rakefile +7 -0
  18. data/spec/testbed/config.ru +4 -0
  19. data/spec/testbed/config/application.rb +45 -0
  20. data/spec/testbed/config/boot.rb +6 -0
  21. data/spec/testbed/config/dependencies/another_fake_controller.yml +3 -0
  22. data/spec/testbed/config/dependencies/application.yml +2 -0
  23. data/spec/testbed/config/dependencies/fake_controller.yml +4 -0
  24. data/spec/testbed/config/dependencies/jquery.yml +2 -0
  25. data/spec/testbed/config/dependencies/rails.yml +2 -0
  26. data/spec/testbed/config/environment.rb +5 -0
  27. data/spec/testbed/config/environments/development.rb +26 -0
  28. data/spec/testbed/config/environments/production.rb +49 -0
  29. data/spec/testbed/config/environments/test.rb +35 -0
  30. data/spec/testbed/config/routes.rb +58 -0
  31. data/spec/testbed/log/development.log +0 -0
  32. data/spec/testbed/log/production.log +0 -0
  33. data/spec/testbed/log/server.log +0 -0
  34. data/spec/testbed/log/test.log +8 -0
  35. data/spec/testbed/public/javascripts/another_fake_controller.js +14 -0
  36. data/spec/testbed/public/javascripts/application.js +1 -0
  37. data/spec/testbed/public/javascripts/fake_controller.js +15 -0
  38. data/spec/testbed/public/javascripts/jquery.js +8316 -0
  39. data/spec/testbed/public/javascripts/jquery.ui.core.js +312 -0
  40. data/spec/testbed/public/javascripts/jquery.ui.core.min.js +17 -0
  41. data/spec/testbed/public/javascripts/jquery.ui.mouse.js +160 -0
  42. data/spec/testbed/public/javascripts/jquery.ui.mouse.min.js +17 -0
  43. data/spec/testbed/public/javascripts/jquery.ui.widget.js +262 -0
  44. data/spec/testbed/public/javascripts/jquery.ui.widget.min.js +15 -0
  45. data/spec/testbed/public/javascripts/rails.js +289 -0
  46. metadata +95 -88
  47. data/.document +0 -5
  48. data/javascript_auto_include.gemspec +0 -60
data/Gemfile CHANGED
@@ -1,8 +1,12 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'actionpack', '>= 3.0.0', :require => 'action_pack'
3
+ gem 'rails', '~> 3.0.7'
4
4
 
5
5
  group :development do
6
- gem "bundler", "~> 1.0.0"
7
- gem "jeweler", "~> 1.5.2"
6
+ gem 'bundler'
7
+ gem 'jeweler'
8
+ end
9
+
10
+ group :test, :development do
11
+ gem 'rspec-rails', '>= 2.6.rc'
8
12
  end
data/Gemfile.lock CHANGED
@@ -2,42 +2,92 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  abstract (1.0.0)
5
- actionpack (3.0.3)
6
- activemodel (= 3.0.3)
7
- activesupport (= 3.0.3)
5
+ actionmailer (3.0.8)
6
+ actionpack (= 3.0.8)
7
+ mail (~> 2.2.19)
8
+ actionpack (3.0.8)
9
+ activemodel (= 3.0.8)
10
+ activesupport (= 3.0.8)
8
11
  builder (~> 2.1.2)
9
12
  erubis (~> 2.6.6)
10
- i18n (~> 0.4)
13
+ i18n (~> 0.5.0)
11
14
  rack (~> 1.2.1)
12
- rack-mount (~> 0.6.13)
13
- rack-test (~> 0.5.6)
15
+ rack-mount (~> 0.6.14)
16
+ rack-test (~> 0.5.7)
14
17
  tzinfo (~> 0.3.23)
15
- activemodel (3.0.3)
16
- activesupport (= 3.0.3)
18
+ activemodel (3.0.8)
19
+ activesupport (= 3.0.8)
17
20
  builder (~> 2.1.2)
18
- i18n (~> 0.4)
19
- activesupport (3.0.3)
21
+ i18n (~> 0.5.0)
22
+ activerecord (3.0.8)
23
+ activemodel (= 3.0.8)
24
+ activesupport (= 3.0.8)
25
+ arel (~> 2.0.10)
26
+ tzinfo (~> 0.3.23)
27
+ activeresource (3.0.8)
28
+ activemodel (= 3.0.8)
29
+ activesupport (= 3.0.8)
30
+ activesupport (3.0.8)
31
+ arel (2.0.10)
20
32
  builder (2.1.2)
33
+ diff-lcs (1.1.2)
21
34
  erubis (2.6.6)
22
35
  abstract (>= 1.0.0)
23
36
  git (1.2.5)
24
- i18n (0.4.2)
25
- jeweler (1.5.2)
26
- bundler (~> 1.0.0)
37
+ i18n (0.5.0)
38
+ jeweler (1.6.2)
39
+ bundler (~> 1.0)
27
40
  git (>= 1.2.5)
28
41
  rake
29
- rack (1.2.1)
30
- rack-mount (0.6.13)
42
+ mail (2.2.19)
43
+ activesupport (>= 2.3.6)
44
+ i18n (>= 0.4.0)
45
+ mime-types (~> 1.16)
46
+ treetop (~> 1.4.8)
47
+ mime-types (1.16)
48
+ polyglot (0.3.1)
49
+ rack (1.2.3)
50
+ rack-mount (0.6.14)
31
51
  rack (>= 1.0.0)
32
52
  rack-test (0.5.7)
33
53
  rack (>= 1.0)
54
+ rails (3.0.8)
55
+ actionmailer (= 3.0.8)
56
+ actionpack (= 3.0.8)
57
+ activerecord (= 3.0.8)
58
+ activeresource (= 3.0.8)
59
+ activesupport (= 3.0.8)
60
+ bundler (~> 1.0)
61
+ railties (= 3.0.8)
62
+ railties (3.0.8)
63
+ actionpack (= 3.0.8)
64
+ activesupport (= 3.0.8)
65
+ rake (>= 0.8.7)
66
+ thor (~> 0.14.4)
34
67
  rake (0.8.7)
35
- tzinfo (0.3.24)
68
+ rspec (2.6.0)
69
+ rspec-core (~> 2.6.0)
70
+ rspec-expectations (~> 2.6.0)
71
+ rspec-mocks (~> 2.6.0)
72
+ rspec-core (2.6.4)
73
+ rspec-expectations (2.6.0)
74
+ diff-lcs (~> 1.1.2)
75
+ rspec-mocks (2.6.0)
76
+ rspec-rails (2.6.1)
77
+ actionpack (~> 3.0)
78
+ activesupport (~> 3.0)
79
+ railties (~> 3.0)
80
+ rspec (~> 2.6.0)
81
+ thor (0.14.6)
82
+ treetop (1.4.9)
83
+ polyglot (>= 0.3.1)
84
+ tzinfo (0.3.27)
36
85
 
37
86
  PLATFORMS
38
87
  ruby
39
88
 
40
89
  DEPENDENCIES
41
- actionpack (>= 3.0.0)
42
- bundler (~> 1.0.0)
43
- jeweler (~> 1.5.2)
90
+ bundler
91
+ jeweler
92
+ rails (~> 3.0.7)
93
+ rspec-rails (>= 2.6.rc)
data/README.markdown CHANGED
@@ -6,37 +6,69 @@
6
6
 
7
7
  Should be as easy as:
8
8
 
9
- $ gem install javascript_auto_include
9
+ $ gem install javascript_auto_include
10
10
 
11
11
  Or in your Gemfile:
12
12
 
13
- $ gem 'javascript_auto_include', '~> 0.1.0'
13
+ $ gem 'javascript_auto_include'
14
14
 
15
15
  ## Usage
16
16
 
17
- Put in your layout's head just like you would with javascript_include_tag
17
+ ### javascript_auto_include_tag
18
18
 
19
- ### Basic
19
+ #### Basic
20
20
 
21
- <%= javascript_auto_include_tag :defaults %>
21
+ <%= javascript_auto_include_tag :defaults %>
22
22
 
23
23
  ... will insert the default javascripts (just like `javascript_include_tag`) and also look for an action-specifc javascript file at public/javascripts/:controller/:action.js. If it exists, it will be included as well.
24
24
 
25
- ### With custom pattern
25
+ #### Custom pattern
26
26
 
27
- <%= javascript_auto_include_tag :defaults, :pattern => ':controller_:action.js' %>
27
+ <%= javascript_auto_include_tag :defaults, :pattern => ':controller_:action.js' %>
28
28
 
29
29
  ... will work just like shown above but alter the search path according to the supplied pattern: public/javascripts/:controller_:action.js (e.g. public/javascripts/album_new.js)
30
30
 
31
- ### Compatibility
31
+ ### javascript_auto_include
32
32
 
33
- `javascript_auto_include_tag` uses Rails' `javascript_include_tag` helper and passes on all options (:concat, :cache, ...) and keys (:defaults, :all, ...) supplied.
33
+ #### Basic
34
+
35
+ <%= javascript_auto_include :defaults %>
36
+
37
+ ... will insert the default javascripts (just like `javascript_include_tag`) and also look for an action-specifc javascript file at public/javascripts/:controller/:action.js. If it exists, it will be included as well.
38
+
39
+ In addition to what +javascript_auto_include_tag+ does it will also scan the sourc files' header and include those files name there as well. For that to happen your js-file's header should look something like this:
40
+
41
+ /*
42
+ * [...]
43
+ *
44
+ * Depends:
45
+ * jquery.ui.core.js
46
+ * jquery.ui.mouse.js
47
+ * jquery.ui.widget.js
48
+ */
49
+
50
+ For erformance reasons all dependencies identified will be stored in the config/dependencies directory of your ::Rails.root. In production environments `javascript_auto_include` will automatically pick minified versions if they exist (e.g. use jquery.ui.core.min.js instead of jquery.ui.core.js)
51
+
52
+ #### Custom pattern
53
+
54
+ <%= javascript_auto_include :defaults, :pattern => ':controller_:action.js' %>
55
+
56
+ ... will work just like shown above but alter the search path according to the supplied pattern: public/javascripts/:controller_:action.js (e.g. public/javascripts/album_new.js)
57
+
58
+ #### Forcing re-scan
59
+
60
+ <%= javascript_auto_include :defaults, :force => true %>
61
+
62
+ ... will force +javascript_auto_include+ to parse the javascript headers again even if dependencies exists in config/depdencies/jquery.ui.core.yml)
63
+
64
+ ## Compatibility
65
+
66
+ Both use Rails' `javascript_include_tag` helper and pass on all options (:concat, :cache, ...) and keys (:defaults, :all, ...) supplied.
34
67
 
35
68
  ## TODO
36
69
 
37
- I just extracted this from a current project. It still lacks specs and testing but so far it seems to work for me.
70
+ Right now it does what I want it to. But you decide. Go fork!
38
71
 
39
72
  ## Copyright
40
73
 
41
- Copyright (c) 2011 Ulf Möhring <hello@ulfmoehring.net>. See LICENSE.txt for
42
- further details.
74
+ Copyright (c) 2011 Ulf Möhring <hello@ulfmoehring.net>. See LICENSE.txt for further details.
data/Rakefile CHANGED
@@ -19,6 +19,6 @@ Jeweler::Tasks.new do |gem|
19
19
  gem.description = "Rails helper for automatically including javascript files. Looks up assets in public/javascripts based on the current controller/action pair."
20
20
  gem.email = "hello@ulfmoehring.net"
21
21
  gem.authors = ["Ulf Moehring"]
22
- gem.add_runtime_dependency 'actionpack', '>= 3.0.0'
22
+ gem.files = FileList["[A-Z]*","{lib,spec}/**/*"]
23
23
  end
24
24
  Jeweler::RubygemsDotOrgTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -1,11 +1,15 @@
1
1
  module JavascriptAutoInclude
2
+ # Load model backend
3
+ require 'javascript_auto_include/dependency'
4
+ require 'javascript_auto_include/source_file'
5
+
6
+ # Tie into Rails
2
7
  class Railtie < Rails::Railtie
3
8
  initializer "javascript_auto_include.action_controller" do |app|
4
9
  require 'javascript_auto_include/helpers/action_controller'
5
10
  ActionController::Base.send(:include, JavascriptAutoInclude::Helpers::ActionController)
6
11
  ActionController::Base.send(:before_filter, :identify_controller_and_action)
7
12
  end
8
-
9
13
  initializer "javascript_auto_include.action_view" do |app|
10
14
  require 'javascript_auto_include/helpers/action_view'
11
15
  ActionView::Base.send(:include, JavascriptAutoInclude::Helpers::ActionView)
@@ -0,0 +1,13 @@
1
+ class Dependency < Array
2
+
3
+ # Override inherited << method to only add existing files
4
+ def << obj
5
+ if File.exists?("#{::Rails.root}#{File::SEPARATOR}public#{File::SEPARATOR}javascripts#{File::SEPARATOR}#{obj}") || File.exists?("#{::Rails.root}#{File::SEPARATOR}public#{File::SEPARATOR}javascripts#{File::SEPARATOR}#{obj}.js")
6
+ super(obj)
7
+ else
8
+ ::Rails.logger.warn "'#{obj}' wasn't found in '#{::Rails.root}#{File::SEPARATOR}public#{File::SEPARATOR}javascripts' but seems to be required. Your app might not work as expected."
9
+ self
10
+ end
11
+ end
12
+
13
+ end
@@ -2,32 +2,37 @@ module JavascriptAutoInclude
2
2
  module Helpers
3
3
  # = ActionView helpers
4
4
  #
5
- # This module contains the helper +javascript_auto_include_tag+, which inserts the javascript
6
- # include tag(s) into a view.
7
- #
8
- # == Basic usage
9
- #
10
- # <%= javascript_auto_include_tag :defaults %>
5
+ # This module contains the helpers +javascript_auto_include_tag+ and +javascript_auto_include+. Both provide convenient automatisms
6
+ # for including javascript source tags in yoru views.
11
7
  #
12
- # ... will insert the default javascripts (just like javascript_include_tag) and also look for an
13
- # action-specifc javascript file at public/javascripts/:controller/:action.js. If it exists, it will
14
- # be included as well.
15
- #
16
- # == Using your own pattern
17
- #
18
- # <%= javascript_auto_include_tag :defaults, :pattern => ':controller_:action.js' %>
8
+ # == Basic usage
19
9
  #
20
- # ... will work just like shown above but alter the search path according to the supplied pattern:
21
- # public/javascripts/:controller_:action.js (e.g. public/javascripts/album_new.js)
10
+ # See helpers below for instructions
22
11
  #
23
12
  # == Compatibility
24
13
  #
25
- # +javascript_auto_include_tag+ uses Rails' javascript_include_tag helper and passes on all options
14
+ # Both helpers use Rails' javascript_include_tag helper and pass on all options
26
15
  # (:concat, :cache, ...) and keys (:defaults, :all, ...) supplied
27
16
  #
28
17
  module ActionView
29
-
30
- def javascript_auto_include_tag(*sources) #:nodoc:
18
+ # = javascript_auto_include_tag
19
+ #
20
+ # == Basic usage
21
+ #
22
+ # <%= javascript_auto_include_tag :defaults %>
23
+ #
24
+ # ... will insert the default javascripts (just like javascript_include_tag) and also look for an
25
+ # action-specifc javascript file at public/javascripts/:controller/:action.js. If it exists, it will
26
+ # be included as well.
27
+ #
28
+ # == Using your own pattern
29
+ #
30
+ # <%= javascript_auto_include_tag :defaults, :pattern => ':controller_:action.js' %>
31
+ #
32
+ # ... will work just like shown above but alter the search path according to the supplied pattern:
33
+ # public/javascripts/:controller_:action.js (e.g. public/javascripts/album_new.js)
34
+ #
35
+ def javascript_auto_include_tag(*sources)
31
36
  options = sources.extract_options!.stringify_keys
32
37
  pattern = options.key?("pattern") ? options.delete("pattern") : ":controller#{File::SEPARATOR}:action"
33
38
 
@@ -36,7 +41,55 @@ module JavascriptAutoInclude
36
41
  sources << auto_javascript_file if File.exists?(Rails.root.join('public','javascripts',auto_javascript_file))
37
42
  javascript_include_tag(*sources << options)
38
43
  end
39
-
44
+ # = javascript_auto_include_tag
45
+ #
46
+ # == Basic usage
47
+ #
48
+ # <%= javascript_auto_include :defaults %>
49
+ #
50
+ # ... will insert the default javascripts (just like javascript_include_tag) and also look for an
51
+ # action-specifc javascript file at public/javascripts/:controller/:action.js. If it exists, it will
52
+ # be included as well.
53
+ #
54
+ # In addition to what +javascript_auto_include_tag+ does it will also scan the sourc files' header and include those
55
+ # files name there as well. For that to happen your js-file's header should look something like this:
56
+ # /*
57
+ # * [...]
58
+ # *
59
+ # * Depends:
60
+ # * jquery.ui.core.js
61
+ # * jquery.ui.mouse.js
62
+ # * jquery.ui.widget.js
63
+ # */
64
+ #
65
+ # For erformance reasons all dependencies identified will be stored in the config/dependencies directory of your ::Rails.root.
66
+ # In production environments +javascript_auto_include+ will automatically pick minified versions if they exist (e.g. use
67
+ # jquery.ui.core.min.js instead of jquery.ui.core.js)
68
+ #
69
+ # == Using your own pattern
70
+ #
71
+ # <%= javascript_auto_include :defaults, :pattern => ':controller_:action.js' %>
72
+ #
73
+ # ... will work just like shown above but alter the search path according to the supplied pattern:
74
+ # public/javascripts/:controller_:action.js (e.g. public/javascripts/album_new.js)
75
+ #
76
+ # == Forcing re-scan
77
+ #
78
+ # <%= javascript_auto_include :defaults, :force => true %>
79
+ #
80
+ # ... will force +javascript_auto_include+ to parse the javascript headers again even if dependencies exists in
81
+ # config/depdencies/jquery.ui.core.yml)
82
+ #
83
+ def javascript_auto_include(*sources) #:nodoc:
84
+ options = sources.extract_options!.stringify_keys
85
+ pattern = options.key?("pattern") ? options.delete("pattern") : ":controller#{File::SEPARATOR}:action"
86
+ force = options.key?("force") ? options.delete("force") : false
87
+
88
+ source = SourceFile.new(expand_javascript_sources(sources << pattern.sub(":controller",$CONTROLLER).sub(":action",$ACTION)))
89
+ sources = source.dependencies(force)
90
+
91
+ javascript_include_tag(*sources << options)
92
+ end
40
93
  end
41
94
  end
42
95
  end
@@ -0,0 +1,61 @@
1
+ require 'yaml'
2
+
3
+ class SourceFile
4
+
5
+ # Retrieve javascript file as full path
6
+ def initialize(files)
7
+ Dir.mkdir("#{::Rails.root}#{File::SEPARATOR}config#{File::SEPARATOR}dependencies") unless Dir.exists?("#{::Rails.root}#{File::SEPARATOR}config#{File::SEPARATOR}dependencies")
8
+ @config_files = files.collect { |file| [file, "#{::Rails.root}#{File::SEPARATOR}config#{File::SEPARATOR}dependencies#{File::SEPARATOR}#{file}.yml"] }
9
+ @source_files = files.collect { |file| [file, "#{::Rails.root}#{File::SEPARATOR}public#{File::SEPARATOR}javascripts#{File::SEPARATOR}#{file}#{file.match(/\.js$/) ? '' : '.js' }"] }
10
+ @dependencies = Dependency.new
11
+ end
12
+
13
+ # Read dependencies from config file or scan source file
14
+ def dependencies(force = false)
15
+ 0.upto(@source_files.size-1) do |i|
16
+ if force || !config_exists?(i)
17
+ @dependencies += read_from_source(@source_files[i], @config_files[i]) if File.exists?(@source_files[i][1])
18
+ else
19
+ @dependencies += read_from_config(@config_files[i])
20
+ end
21
+ end
22
+ ENV["RAILS_ENV"] == 'production' ? minify(@dependencies.uniq) : @dependencies.uniq
23
+ end
24
+
25
+ private
26
+ # Checks whether config file exists
27
+ def config_exists?(index)
28
+ File.exists?(@config_files[index][1])
29
+ end
30
+
31
+ # Read previously identified dependencies from cache
32
+ def read_from_config(config)
33
+ YAML.load_file(config[1]).to_a << config[0]
34
+ end
35
+
36
+ # Scan comment section of a javascript source file for dependencies and save result in config file
37
+ def read_from_source(source, config)
38
+ start = false
39
+ dependencies = []
40
+ File.open(source[1],'r') do |source_file|
41
+ while (line = source_file.gets)
42
+ break if line.match(/^ \*\//)
43
+ dependencies << line.match(/^ \*[\t ](.*\.js)/).captures.first if start && line.match(/^ \*[\t ].*\.js/)
44
+ start = true if line.match(/^ \* Depends:/)
45
+ end
46
+ end
47
+ File.open(config[1],'w') do |config_file|
48
+ YAML.dump(dependencies.to_a, config_file)
49
+ end
50
+ return dependencies << source[0]
51
+ end
52
+
53
+ # Looks for minified file versions
54
+ def minify(sources)
55
+ sources.each do |source|
56
+ minified_version = source.match(/\.js$/) ? source.gsub('.js','.min.js') : "#{source}.min.js"
57
+ sources[sources.index(source)] = (File.exists?("#{::Rails.root}#{File::SEPARATOR}public#{File::SEPARATOR}javascripts#{File::SEPARATOR}#{minified_version}") ? minified_version : source)
58
+ end
59
+ return sources
60
+ end
61
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Dependency do
4
+
5
+ before(:each) do
6
+ @dependency = Dependency.new
7
+ end
8
+
9
+ it "stores existing files" do
10
+ @dependency << 'jquery.js'
11
+ @dependency.to_a.should eq(['jquery.js'])
12
+ end
13
+
14
+ it "rejects non-existing files" do
15
+ @dependency << 'prototype.js'
16
+ @dependency.to_a.should eq([])
17
+ end
18
+
19
+ end