├── .document
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── LICENSE.txt
├── README.md
├── Rakefile
├── VERSION
├── headjs-rails.gemspec
├── lib
├── generators
│ └── headjs
│ │ └── install
│ │ └── install_generator.rb
├── headjs-rails.rb
└── headjs-rails
│ └── tag_helper.rb
└── test
├── helper.rb
├── public
└── javascripts
│ ├── jquery.js
│ └── rails.js
├── test_generator.rb
└── test_tag_helper.rb
/.document:
--------------------------------------------------------------------------------
1 | lib/**/*.rb
2 | bin/*
3 | -
4 | features/**/*.feature
5 | LICENSE.txt
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # rcov generated
2 | coverage
3 |
4 | # rdoc generated
5 | rdoc
6 |
7 | # yard generated
8 | doc
9 | .yardoc
10 |
11 | # bundler
12 | .bundle
13 |
14 | # jeweler generated
15 | pkg
16 |
17 | log
18 | .ruby-version
19 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | gem "rails", ">= 3.0.0"
4 |
5 | group :development do
6 | gem "shoulda"
7 | gem "bundler"
8 | gem "jeweler"
9 | end
10 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | actionmailer (3.2.8)
5 | actionpack (= 3.2.8)
6 | mail (~> 2.4.4)
7 | actionpack (3.2.8)
8 | activemodel (= 3.2.8)
9 | activesupport (= 3.2.8)
10 | builder (~> 3.0.0)
11 | erubis (~> 2.7.0)
12 | journey (~> 1.0.4)
13 | rack (~> 1.4.0)
14 | rack-cache (~> 1.2)
15 | rack-test (~> 0.6.1)
16 | sprockets (~> 2.1.3)
17 | activemodel (3.2.8)
18 | activesupport (= 3.2.8)
19 | builder (~> 3.0.0)
20 | activerecord (3.2.8)
21 | activemodel (= 3.2.8)
22 | activesupport (= 3.2.8)
23 | arel (~> 3.0.2)
24 | tzinfo (~> 0.3.29)
25 | activeresource (3.2.8)
26 | activemodel (= 3.2.8)
27 | activesupport (= 3.2.8)
28 | activesupport (3.2.8)
29 | i18n (~> 0.6)
30 | multi_json (~> 1.0)
31 | arel (3.0.2)
32 | builder (3.0.4)
33 | erubis (2.7.0)
34 | git (1.2.5)
35 | hike (1.2.1)
36 | i18n (0.6.1)
37 | jeweler (1.8.4)
38 | bundler (~> 1.0)
39 | git (>= 1.2.5)
40 | rake
41 | rdoc
42 | journey (1.0.4)
43 | json (1.7.5)
44 | mail (2.4.4)
45 | i18n (>= 0.4.0)
46 | mime-types (~> 1.16)
47 | treetop (~> 1.4.8)
48 | mime-types (1.19)
49 | multi_json (1.3.7)
50 | polyglot (0.3.3)
51 | rack (1.4.1)
52 | rack-cache (1.2)
53 | rack (>= 0.4)
54 | rack-ssl (1.3.2)
55 | rack
56 | rack-test (0.6.2)
57 | rack (>= 1.0)
58 | rails (3.2.8)
59 | actionmailer (= 3.2.8)
60 | actionpack (= 3.2.8)
61 | activerecord (= 3.2.8)
62 | activeresource (= 3.2.8)
63 | activesupport (= 3.2.8)
64 | bundler (~> 1.0)
65 | railties (= 3.2.8)
66 | railties (3.2.8)
67 | actionpack (= 3.2.8)
68 | activesupport (= 3.2.8)
69 | rack-ssl (~> 1.3.2)
70 | rake (>= 0.8.7)
71 | rdoc (~> 3.4)
72 | thor (>= 0.14.6, < 2.0)
73 | rake (0.9.2.2)
74 | rdoc (3.12)
75 | json (~> 1.4)
76 | shoulda (3.3.2)
77 | shoulda-context (~> 1.0.1)
78 | shoulda-matchers (~> 1.4.1)
79 | shoulda-context (1.0.1)
80 | shoulda-matchers (1.4.1)
81 | activesupport (>= 3.0.0)
82 | sprockets (2.1.3)
83 | hike (~> 1.2)
84 | rack (~> 1.0)
85 | tilt (~> 1.1, != 1.3.0)
86 | thor (0.16.0)
87 | tilt (1.3.3)
88 | treetop (1.4.12)
89 | polyglot
90 | polyglot (>= 0.3.1)
91 | tzinfo (0.3.35)
92 |
93 | PLATFORMS
94 | ruby
95 | x86-mingw32
96 |
97 | DEPENDENCIES
98 | bundler
99 | jeweler
100 | rails (>= 3.0.0)
101 | shoulda
102 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 David Bittencourt
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # headjs-rails
2 |
3 | This gem adds a helper and a generator to facilitate the use of [Head JS](http://headjs.com) in your Rails 3 projects, the same way you would normally add javascript tags using Rails `javascript_include_tag` helper.
4 |
5 | ## Usage
6 |
7 | In your Gemfile, add this line:
8 |
9 | gem "headjs-rails"
10 |
11 | Then, run `bundle install`. To invoke the generator and install the latest Head JS files in your `public/javascripts` folder, run:
12 |
13 | rails generate headjs:install
14 |
15 | Now just add headjs to your head, using default rails `javascript_include_tag('head.min')` for example, and put the rest of your scripts at the bottom of your layout with the `headjs_include_tag` method the gem provides. This method is a wrapper of `javascript_include_tag` and accepts the exact same methods, so it should work fine with any other gem/plugin that works with it.
16 |
17 | headjs_include_tag(:defaults)
18 | headjs_include_tag(:all)
19 | headjs_include_tag('http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js')
20 | headjs_include_tag('jquery', 'jquery.ui', 'jquery.plugin', 'rails')
21 | headjs_include_tag(:defaults, :cache => true)
22 | headjs_include_tag(:defaults, 'jquery.ui', :cache => 'bundle')
23 |
24 | The sources will have labels automatically assigned based on the filename (removing .js, .min.js and any other parameter).
25 |
26 | headjs_include_tag('jquery', 'rails')
27 | #
28 |
29 | headjs_include_tag(:defaults, :cache => 'bundle')
30 | #
31 |
32 | Don't forget to use `head.ready()` in any code that runs inside your views. More information in [Head JS API](http://headjs.com/#api).
33 |
34 | I also suggest you take a look at the [smurf gem](https://github.com/thumblemonks/smurf), a drop-in gem that automatically minifies Javascript (and CSS) when you use caching and rails default include tag helpers. It works fine with `headjs_include_tag` as well as it's just a wrapper of `javascript_include_tag`.
35 |
36 | ## Testing
37 |
38 | Clone the repo, run `bundle install` and `bundle exec rake test`.
39 |
40 | ## Contributing to headjs-rails
41 |
42 | Fork the project and send pull requests.
43 |
44 | ## Copyright
45 |
46 | Author: David Bittencourt. See LICENSE.txt for further details.
47 |
48 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'bundler'
3 | begin
4 | Bundler.setup(:default, :development)
5 | rescue Bundler::BundlerError => e
6 | $stderr.puts e.message
7 | $stderr.puts "Run `bundle install` to install missing gems"
8 | exit e.status_code
9 | end
10 | require 'rake'
11 |
12 | require 'jeweler'
13 | Jeweler::Tasks.new do |gem|
14 | # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15 | gem.name = "headjs-rails"
16 | gem.homepage = "http://github.com/muitocomplicado/headjs-rails"
17 | gem.license = "MIT"
18 | gem.summary = %Q{Provides Rails 3 helper and generator for adding Head JS support.}
19 | gem.description = %Q{This gem adds a helper and generator to facilitate the use of Head JS in your Rails 3 projects the same way you would normally add javascript tags using Rails default helpers.}
20 | gem.email = "muitocomplicado@gmail.com"
21 | gem.authors = ["David Bittencourt"]
22 | end
23 | Jeweler::RubygemsDotOrgTasks.new
24 |
25 | require 'rake/testtask'
26 | Rake::TestTask.new(:test) do |test|
27 | test.libs << 'lib' << 'test'
28 | test.pattern = 'test/**/test_*.rb'
29 | test.verbose = true
30 | end
31 |
32 | task :default => :test
33 |
34 | require 'rdoc/task'
35 | Rake::RDocTask.new do |rdoc|
36 | version = File.exist?('VERSION') ? File.read('VERSION') : ""
37 |
38 | rdoc.rdoc_dir = 'rdoc'
39 | rdoc.title = "headjs-rails #{version}"
40 | rdoc.rdoc_files.include('README*')
41 | rdoc.rdoc_files.include('lib/**/*.rb')
42 | end
43 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 0.4.2
--------------------------------------------------------------------------------
/headjs-rails.gemspec:
--------------------------------------------------------------------------------
1 | # Generated by jeweler
2 | # DO NOT EDIT THIS FILE DIRECTLY
3 | # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4 | # -*- encoding: utf-8 -*-
5 |
6 | Gem::Specification.new do |s|
7 | s.name = "headjs-rails"
8 | s.version = "0.4.2"
9 |
10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11 | s.authors = ["David Bittencourt"]
12 | s.date = "2013-11-19"
13 | s.description = "This gem adds a helper and generator to facilitate the use of Head JS in your Rails 3 projects the same way you would normally add javascript tags using Rails default helpers."
14 | s.email = "muitocomplicado@gmail.com"
15 | s.extra_rdoc_files = [
16 | "LICENSE.txt",
17 | "README.md"
18 | ]
19 | s.files = [
20 | ".document",
21 | "Gemfile",
22 | "Gemfile.lock",
23 | "LICENSE.txt",
24 | "README.md",
25 | "Rakefile",
26 | "VERSION",
27 | "headjs-rails.gemspec",
28 | "lib/generators/headjs/install/install_generator.rb",
29 | "lib/headjs-rails.rb",
30 | "lib/headjs-rails/tag_helper.rb",
31 | "test/helper.rb",
32 | "test/public/javascripts/jquery.js",
33 | "test/public/javascripts/rails.js",
34 | "test/test_generator.rb",
35 | "test/test_tag_helper.rb"
36 | ]
37 | s.homepage = "http://github.com/muitocomplicado/headjs-rails"
38 | s.licenses = ["MIT"]
39 | s.require_paths = ["lib"]
40 | s.rubygems_version = "1.8.23"
41 | s.summary = "Provides Rails 3 helper and generator for adding Head JS support."
42 |
43 | if s.respond_to? :specification_version then
44 | s.specification_version = 3
45 |
46 | if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47 | s.add_runtime_dependency(%q, [">= 3.0.0"])
48 | s.add_development_dependency(%q, [">= 0"])
49 | s.add_development_dependency(%q, [">= 0"])
50 | s.add_development_dependency(%q, [">= 0"])
51 | else
52 | s.add_dependency(%q, [">= 3.0.0"])
53 | s.add_dependency(%q, [">= 0"])
54 | s.add_dependency(%q, [">= 0"])
55 | s.add_dependency(%q, [">= 0"])
56 | end
57 | else
58 | s.add_dependency(%q, [">= 3.0.0"])
59 | s.add_dependency(%q, [">= 0"])
60 | s.add_dependency(%q, [">= 0"])
61 | s.add_dependency(%q, [">= 0"])
62 | end
63 | end
64 |
65 |
--------------------------------------------------------------------------------
/lib/generators/headjs/install/install_generator.rb:
--------------------------------------------------------------------------------
1 | require "openssl"
2 | module OpenSSL
3 | module SSL
4 | remove_const :VERIFY_PEER
5 | end
6 | end
7 | OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
8 |
9 | module Headjs
10 | module Generators
11 | class InstallGenerator < ::Rails::Generators::Base
12 | desc "This generator downloads and installs Head JS"
13 | class_option :version, :type => :string, :default => "1.0.0", :desc => "Which version of Head JS to fetch"
14 | @@default_version = "1.0.0"
15 | @@dist_url = "https://raw.github.com/headjs/headjs/master/dist/{version}/{file}"
16 |
17 | def remove_headjs
18 | %w(head.js head.min.js).each do |js|
19 | remove_file "public/javascripts/#{js}"
20 | end
21 | end
22 |
23 | def download_headjs
24 | say_status("fetching", "Head JS (#{options.version})", :green)
25 | get_headjs(options.version)
26 | rescue OpenURI::HTTPError
27 | say_status("warning", "could not find Head JS (#{options.version})", :yellow)
28 | say_status("warning", headjs_url(options.version, 'head.js'), :yellow)
29 | say_status("warning", headjs_url(options.version, 'head.min.js'), :yellow)
30 |
31 | if @@default_version != options.version
32 | say_status("fetching", "Head JS (#{@@default_version})", :green)
33 | get_headjs(@@default_version)
34 | end
35 | end
36 |
37 | private
38 |
39 | def get_headjs(version)
40 | %w(head.js head.min.js).each do |js|
41 | get headjs_url(version, js), "public/javascripts/#{js}"
42 | end
43 | end
44 |
45 | def headjs_url(version, file)
46 | @@dist_url.gsub("{version}", version).gsub("{file}", file)
47 | end
48 |
49 | end
50 | end
51 | end
--------------------------------------------------------------------------------
/lib/headjs-rails.rb:
--------------------------------------------------------------------------------
1 | require File.join(File.dirname(__FILE__), 'headjs-rails', 'tag_helper')
2 |
3 | ActionController::Base.helper(Headjs::TagHelper)
--------------------------------------------------------------------------------
/lib/headjs-rails/tag_helper.rb:
--------------------------------------------------------------------------------
1 | module Headjs
2 |
3 | module TagHelper
4 |
5 | def headjs_include_tag(*sources)
6 | content_tag :script, { :type => Mime::JS }, false do
7 | headjs_include_js(*sources)
8 | end
9 | end
10 |
11 | def headjs_include_js(*sources)
12 | "head.js( #{headjs_include_params(*sources)} );".html_safe
13 | end
14 |
15 | def headjs_include_params(*sources)
16 | keys = []
17 | javascript_include_tag(*sources).
18 | scan(/src="([^"]+)"/).
19 | flatten.
20 | map do |src|
21 | cnt = 0
22 | key = original_key =
23 | URI.
24 | parse(src).
25 | path[%r{[^/]+\z}].
26 | gsub(/\.js$/,'').
27 | gsub(/\.min$/,'').
28 | gsub(/-[0-9a-f]{32}$/,'')
29 | while keys.include?(key) do
30 | key = "#{original_key}_#{(cnt = cnt.succ)}"
31 | end
32 | keys << key
33 | "{ '#{key}': '#{src}' }"
34 | end.join(', ').html_safe
35 | end
36 |
37 | end
38 |
39 | end
40 |
--------------------------------------------------------------------------------
/test/helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'bundler'
3 | begin
4 | Bundler.setup(:default, :development)
5 | rescue Bundler::BundlerError => e
6 | $stderr.puts e.message
7 | $stderr.puts "Run `bundle install` to install missing gems"
8 | exit e.status_code
9 | end
10 |
11 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12 | $LOAD_PATH.unshift(File.dirname(__FILE__))
13 |
14 | require 'rails/all'
15 | require 'shoulda'
16 | require 'rails/test_help'
17 | require 'rails/generators'
18 | require 'headjs-rails'
19 |
20 |
--------------------------------------------------------------------------------
/test/public/javascripts/jquery.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/muitocomplicado/headjs-rails/97903ac4b998a4ad06168bb3514fc67db528ce23/test/public/javascripts/jquery.js
--------------------------------------------------------------------------------
/test/public/javascripts/rails.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/muitocomplicado/headjs-rails/97903ac4b998a4ad06168bb3514fc67db528ce23/test/public/javascripts/rails.js
--------------------------------------------------------------------------------
/test/test_generator.rb:
--------------------------------------------------------------------------------
1 | require 'helper'
2 | require 'generators/headjs/install/install_generator'
3 |
4 | class Headjs::Generators::InstallGeneratorTest < Rails::Generators::TestCase
5 | tests Headjs::Generators::InstallGenerator
6 | destination File.join(File.dirname(__FILE__), 'tmp')
7 | teardown :cleanup_destination_root
8 |
9 | context 'the Head JS install generator' do
10 |
11 | should 'download the default 1.0.0 files' do
12 | run_generator %w(headjs:install)
13 | assert_file 'public/javascripts/head.js'
14 | assert_file 'public/javascripts/head.min.js'
15 | end
16 |
17 | should 'download version 0.99 files' do
18 | run_generator %w(headjs:install --version 0.99)
19 | assert_file 'public/javascripts/head.js'
20 | assert_file 'public/javascripts/head.min.js'
21 | end
22 |
23 | end
24 |
25 | private
26 |
27 | def cleanup_destination_root
28 | FileUtils.rm_r(destination_root)
29 | end
30 |
31 | end
--------------------------------------------------------------------------------
/test/test_tag_helper.rb:
--------------------------------------------------------------------------------
1 | require 'helper'
2 |
3 | module Headjs
4 |
5 | class TagHelperTest < Test::Unit::TestCase
6 |
7 | def setup
8 |
9 | ENV["RAILS_ASSET_ID"] = ''
10 | ActionView::Helpers::AssetTagHelper.register_javascript_expansion :defaults => %w(jquery rails)
11 |
12 | public_dir = File.join(File.dirname(__FILE__), 'public')
13 | @helpers = ActionController::Base.helpers
14 | @helpers.config.perform_caching = false
15 | @helpers.config.assets_dir = public_dir
16 | @helpers.config.javascripts_dir = "#{public_dir}/javascripts"
17 |
18 | %w(all.js bundle.js).each do |js|
19 | begin
20 | File.delete(File.join(public_dir, 'javascripts', js))
21 | rescue
22 | end
23 | end
24 |
25 | end
26 |
27 | def jquery
28 | 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'
29 | end
30 |
31 | context "The Head JS helper include tag" do
32 |
33 | should "return a valid script tag" do
34 | assert_equal "", @helpers.headjs_include_tag(jquery)
35 | end
36 |
37 | should "increase label counter to avoid overwriting" do
38 | assert_equal "", @helpers.headjs_include_tag('products/comments', 'reviews/comments')
39 | end
40 |
41 | should "accept strings for local paths" do
42 | assert_equal "", @helpers.headjs_include_tag('jquery', 'other/rails')
43 | end
44 |
45 | should "accept :defaults registered expansions" do
46 | assert_equal "", @helpers.headjs_include_tag(:defaults)
47 | end
48 |
49 | should "accept :defaults mixed with other strings" do
50 | assert_equal "", @helpers.headjs_include_tag(:defaults, 'modernizr')
51 | end
52 |
53 | should "accept :all expansion" do
54 | assert_equal "", @helpers.headjs_include_tag(:all)
55 | end
56 |
57 | should "accept a :cache => true parameter" do
58 | @helpers.config.perform_caching = true
59 | assert_equal "", @helpers.headjs_include_tag(:defaults, :cache => true)
60 | end
61 |
62 | should "accept a :cache => bundle parameter" do
63 | @helpers.config.perform_caching = true
64 | assert_equal "", @helpers.headjs_include_tag(:defaults, :cache => 'bundle')
65 | end
66 |
67 | should "work with random rails asset ids" do
68 | ENV["RAILS_ASSET_ID"] = '123456789'
69 | assert_equal "", @helpers.headjs_include_tag(:defaults)
70 | end
71 |
72 | should "remove rails asset hashes" do
73 | assert_equal "", @helpers.headjs_include_tag('/assets/foo-f1d2d2f924e986ac86fdf7b36c94bcdf.js')
74 | end
75 |
76 | end
77 |
78 | end
79 |
80 | end
81 |
--------------------------------------------------------------------------------