javascript_features 1.0.0

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,28 @@
1
+ require 'jsmin'
2
+
3
+ module JavascriptFeatures
4
+ module Compiler
5
+ def self.compile(options = {})
6
+ defaults = {:minify => true, :package => 'main'}
7
+ options = defaults.merge(options)
8
+
9
+ files = files_for_package(options[:package])
10
+ compiled = files.map{|file| File.read(file) }.join("\n")
11
+ minified = JSMin.minify(compiled) if options[:minify]
12
+
13
+ minified || compiled
14
+ end
15
+
16
+ def self.package_modified_time(package = 'main')
17
+ files_for_package(package).map{|f| File.new(f).mtime }.max
18
+ end
19
+
20
+ private
21
+ def self.files_for_package(package)
22
+ lib_files = Dir.glob(Rails.root + 'public/javascripts/lib/**/*.js')
23
+ init_files = [File.join(File.dirname(__FILE__), *%w[ .. .. assets init.js ])]
24
+ feature_files = Dir.glob(Rails.root + "public/javascripts/#{package}/**/*.js")
25
+ lib_files + init_files + feature_files
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ module JavascriptFeatures
2
+ module Helper
3
+
4
+ def self.included(controller)
5
+ controller.helper_method :use_javascript_for, :use_javascript_for?, :javascript_feature_classes, :include_javascript_features if controller.respond_to? :helper_method
6
+ end
7
+
8
+ def use_javascript_for(*features)
9
+ @javascript_features ||= []
10
+ @javascript_features += features.map{|f| f.to_s.downcase }
11
+ response.headers['X-JavascriptFeatures-Init'] = @javascript_features.uniq.join(' ') if request && request.xhr?
12
+ end
13
+
14
+ def use_javascript_for?(feature)
15
+ @javascript_features.include?(feature.to_s.downcase)
16
+ end
17
+
18
+ def javascript_feature_classes
19
+ (@javascript_features || []).uniq.map{ |feature| "with-js-#{feature}" }.join(" ")
20
+ end
21
+
22
+ def include_javascript_features(package = 'main')
23
+ query = Compiler.package_modified_time(package).to_i
24
+ tag = %Q{<script type="text/javascript" src="/javascripts/packaged/#{package}.js?#{query}"></script>}
25
+ if tag.respond_to?(:html_safe)
26
+ tag.html_safe
27
+ else
28
+ tag
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ module JavascriptFeatures
2
+ class TestCase
3
+ class Servlet < ::WEBrick::HTTPServlet::AbstractServlet
4
+ def initialize(server, pages)
5
+ super server
6
+ @pages = pages
7
+ end
8
+
9
+ def service(req, res)
10
+ page = @pages[req.path]
11
+ if page
12
+ res.status = 200
13
+ res['Content-Type'] = 'text/html'
14
+ if page.is_a?(Hash)
15
+ page[:headers].each{ |k,v| res[k] = v }
16
+ res.body = page[:body]
17
+ else
18
+ res.body = page
19
+ end
20
+ elsif req.path =~ %r[^/javascripts/packaged/([^/]+).js$]
21
+ res.status = 200
22
+ res['Content-Type'] = 'text/javascript'
23
+ res.body = JavascriptFeatures::Compiler.compile(:package => $1)
24
+ else
25
+ res.status = 404
26
+ res['Content-Type'] = 'text/plain'
27
+ res.body = 'Not found'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,91 @@
1
+ require 'active_support/test_case'
2
+ require 'harmony'
3
+
4
+ module JavascriptFeatures
5
+ class TestCase < ::ActiveSupport::TestCase
6
+ extend JavascriptFeatures::Helper
7
+
8
+ autoload :Servlet, 'javascript_features/test_case/servlet'
9
+
10
+ class << self
11
+ def request
12
+ nil
13
+ end
14
+
15
+ def uses_feature_package(package)
16
+ @feature_package = package
17
+ end
18
+
19
+ def feature_package
20
+ @feature_package ||= 'main'
21
+ end
22
+
23
+ def tests_feature(*names)
24
+ @feature_names = names
25
+ end
26
+
27
+ def feature_names
28
+ @feature_names ||= [self.name.downcase.sub(/test$/, '')]
29
+ end
30
+
31
+ def stubs_http_request(url, options)
32
+ @server_pages = server_pages.merge(url => options)
33
+ end
34
+
35
+ def server_pages
36
+ @server_pages ||= {}
37
+ end
38
+
39
+ def uses_html(&block)
40
+ define_method(:setup) do
41
+ self.class.feature_names.each{ |f| self.class.use_javascript_for f }
42
+ @html = yield.strip
43
+
44
+ server_config = {:BindAddress => '0.0.0.0', :Port => 8076, :AccessLog => [], :Logger => WEBrick::Log::new('/dev/null', 7)}
45
+ @server = ::WEBrick::HTTPServer.new(server_config)
46
+ pages = self.class.server_pages.merge(
47
+ '/index.html' => @html,
48
+ '/jquery.js' => File.read(File.expand_path('../../../assets/jquery.js', __FILE__))
49
+ )
50
+ @server.mount('/', JavascriptFeatures::TestCase::Servlet, pages)
51
+ Thread.new{ @server.start }
52
+
53
+ @page = Harmony::Page.fetch("http://#{server_config[:BindAddress]}:#{server_config[:Port]}/index.html")
54
+ Harmony::Page::Window::BASE_RUNTIME.wait
55
+ end
56
+
57
+ define_method(:teardown) do
58
+ @server.shutdown
59
+ end
60
+ end
61
+
62
+ def uses_html_body
63
+ uses_html do
64
+ %%
65
+ <!DOCTYPE html>
66
+ <html lang="en">
67
+ <head>
68
+ <title>Test page</title>
69
+ </head>
70
+ <body class="#{javascript_feature_classes}">
71
+ #{yield.strip}
72
+
73
+ <script src='/jquery.js'></script>
74
+ #{include_javascript_features(feature_package)}
75
+ </body>
76
+ </html>
77
+ %
78
+ end
79
+ end
80
+ end
81
+
82
+ def execute_js(*args)
83
+ @page.execute_js(*args)
84
+ end
85
+
86
+ def assert_selector_count(expected_count, selector)
87
+ real_count = execute_js("jQuery(#{selector.to_json}).length")
88
+ assert_equal expected_count, real_count, "Expected #{expected_count} elements matching selector #{selector}, found #{real_count}"
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,7 @@
1
+ module JavascriptFeatures
2
+ autoload :Compiler, 'javascript_features/compiler'
3
+ autoload :Helper, 'javascript_features/helper'
4
+ autoload :TestCase, 'javascript_features/test_case'
5
+ end
6
+
7
+ ActionController::Base.send(:include, JavascriptFeatures::Helper) if defined?(ActionController)
@@ -0,0 +1,48 @@
1
+ require 'javascript_features'
2
+
3
+ module Rack
4
+ class JavascriptFeatures
5
+
6
+ DEFAULT_OPTIONS = {:minify => true}
7
+
8
+ def initialize(app, options = {})
9
+ @app = app
10
+ @options = DEFAULT_OPTIONS.merge(options)
11
+ end
12
+
13
+ def call(env)
14
+ request = Rack::Request.new(env)
15
+
16
+ if package = package_for_path(request.path)
17
+ etag = package_etag(package)
18
+ if etag == env['HTTP_IF_NONE_MATCH']
19
+ [304, {}, []]
20
+ else
21
+ javascript = package_javascript(package)
22
+ [200, {"Content-Type" => "text/javascript", "Cache-Control" => "private", "ETag" => etag}, [javascript]]
23
+ end
24
+ else
25
+ @app.call(env)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def package_for_path(path)
32
+ relevant_url = path =~ %r{javascripts/packaged/([^/]+)\.js}
33
+ package_name = relevant_url && $1
34
+ real_package = package_name && ::File.exists?(::File.join(Rails.root, 'public', 'javascripts', package_name))
35
+ real_package && package_name
36
+ end
37
+
38
+ def package_etag(package_name)
39
+ mtime = ::JavascriptFeatures::Compiler.package_modified_time(package_name)
40
+ etag = Digest::MD5.hexdigest("#{package_name}/#{mtime.to_i}")
41
+ end
42
+
43
+ def package_javascript(package_name)
44
+ ::JavascriptFeatures::Compiler.compile(:package => package_name, :minify => @options[:minify])
45
+ end
46
+
47
+ end
48
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'javascript_features'
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'jsmin'
3
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
4
+
5
+ class CompilerTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ common_files = [
9
+ File.join(Rails.root, *%w[ public javascripts lib jquery_plugin.js ]),
10
+ File.join(File.dirname(__FILE__), *%w[ .. assets init.js ])
11
+ ]
12
+
13
+ @main_files = common_files + [ File.join(Rails.root, *%w[ public javascripts main my_feature.js ]) ]
14
+ @alternative_files = common_files + [ File.join(Rails.root, *%w[ public javascripts alternative alternative.js ]) ]
15
+ end
16
+
17
+ context 'compiling the main JavaScript package' do
18
+ should 'concatenate the relevant files in the correct order and minify the result' do
19
+ assert_equal JSMin.minify(@main_files.map{|f| File.read(f) }.join("\n")), JavascriptFeatures::Compiler.compile
20
+ end
21
+
22
+ should 'optionally disable minification' do
23
+ assert_equal @main_files.map{|f| File.read(f) }.join("\n"), JavascriptFeatures::Compiler.compile(:minify => false)
24
+ end
25
+ end
26
+
27
+ context 'compiling the alternative JavaScript package' do
28
+ should 'take feature files from the /alternative directory instead of /main' do
29
+ assert_equal JSMin.minify(@alternative_files.map{|f| File.read(f) }.join("\n")), JavascriptFeatures::Compiler.compile(:package => 'alternative')
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,5 @@
1
+ Features.alternative = {
2
+ init: function() {
3
+ alert("Hello, world");
4
+ }
5
+ };
@@ -0,0 +1,7 @@
1
+ Features.disabled_feature = {
2
+ init: function() {
3
+ var div = document.createElement("div");
4
+ div.className = "disabled_feature";
5
+ document.body.appendChild(div);
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ Features.enabled_feature = {
2
+ init: function() {
3
+ var div = document.createElement("div");
4
+ div.className = "enabled_feature";
5
+ document.body.appendChild(div);
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ Features.global_feature = {
2
+ global_init: function() {
3
+ var div = document.createElement("div");
4
+ div.className = "global_feature";
5
+ document.body.appendChild(div);
6
+ }
7
+ }
@@ -0,0 +1 @@
1
+ jQuery.plugin = {};
@@ -0,0 +1,5 @@
1
+ Features.MyFeature = {
2
+ init: function($) {
3
+ alert("Initialise my feature!");
4
+ }
5
+ };
@@ -0,0 +1,5 @@
1
+ Features.global_load = {
2
+ global_init: function(context) {
3
+ context.find(".xhr-response").append("<span class=\"touched-by-global-init\"></span>");
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ Features.load = {
2
+ init: function(context) {
3
+ context.find(".xhr-response").addClass("touched-by-load");
4
+ }
5
+ }
@@ -0,0 +1,11 @@
1
+ Features.xhr = {
2
+ init: function() {
3
+ var xhr = jQuery.ajax({
4
+ url: "/xhr",
5
+ context: $(".xhr-target"),
6
+ success: function(data) {
7
+ $(".xhr-target").html(data);
8
+ }
9
+ });
10
+ }
11
+ };
@@ -0,0 +1,108 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ class HelperTest < Test::Unit::TestCase
4
+ include JavascriptFeatures::Helper
5
+
6
+ class TestRequest
7
+ def initialize(options)
8
+ @xhr = options[:xhr]
9
+ end
10
+
11
+ def xhr?
12
+ @xhr
13
+ end
14
+
15
+ def xml_http_request?
16
+ @xhr
17
+ end
18
+ end
19
+
20
+ class TestResponse
21
+ attr_accessor :headers
22
+ def initialize
23
+ @headers = {'Content-Type' => 'text/html'}
24
+ end
25
+ end
26
+
27
+ context "when a JavaScript feature is enabled during a normal request" do
28
+ setup do
29
+ self.request = TestRequest.new(:xhr => false)
30
+ self.response = TestResponse.new
31
+ use_javascript_for "something"
32
+ end
33
+
34
+ should "set the corresponding body class" do
35
+ assert_equal "with-js-something", javascript_feature_classes
36
+ end
37
+
38
+ should 'not modify the headers' do
39
+ assert_equal({'Content-Type' => 'text/html'}, response.headers)
40
+ end
41
+
42
+ should 'be able to check that it is enabled' do
43
+ assert use_javascript_for?('something')
44
+ assert !use_javascript_for?('something-else')
45
+ end
46
+ end
47
+
48
+ context 'when a JavaScript feature is enabled during an XHR request' do
49
+ setup do
50
+ self.request = TestRequest.new(:xhr => true)
51
+ self.response = TestResponse.new
52
+ use_javascript_for "something"
53
+ use_javascript_for "something_else"
54
+ end
55
+
56
+ should 'modify the headers' do
57
+ assert_equal({'Content-Type' => 'text/html', 'X-JavascriptFeatures-Init' => 'something something_else'}, response.headers)
58
+ end
59
+ end
60
+
61
+ context "when the same feature is enabled multiple times" do
62
+ setup do
63
+ use_javascript_for "something"
64
+ use_javascript_for "something-else"
65
+ use_javascript_for "something"
66
+ end
67
+ should "only include each class once" do
68
+ assert_equal "with-js-something with-js-something-else", javascript_feature_classes
69
+ end
70
+ end
71
+
72
+ context "when no features have been enabled" do
73
+ should "not produce any classes" do
74
+ assert_equal "", javascript_feature_classes
75
+ end
76
+ end
77
+
78
+ should "allow to pass several features at one call" do
79
+ use_javascript_for "something", "something-else"
80
+ assert_equal "with-js-something with-js-something-else", javascript_feature_classes
81
+ end
82
+
83
+ context 'including the packaged JavaScript' do
84
+ setup{ @script_tag = include_javascript_features }
85
+ should 'write a script tag containing the correct URL' do
86
+ assert_match %r{/javascripts/packaged/main\.js}, @script_tag
87
+ end
88
+ end
89
+
90
+ context 'including an alternative JavaScript package' do
91
+ setup{ @script_tag = include_javascript_features(:alternative) }
92
+ should 'write a script tag containing the correct URL' do
93
+ assert_match %r{/javascripts/packaged/alternative\.js}, @script_tag
94
+ end
95
+ end
96
+
97
+ context 'including the packaged JavaScript after one of the files has been modified' do
98
+ setup do
99
+ @before_modified = include_javascript_features
100
+ FileUtils.touch File.join(Rails.root, %w[ public javascripts main my_feature.js ])
101
+ @after_modified = include_javascript_features
102
+ end
103
+
104
+ should 'include different query strings to avoid caching' do
105
+ assert @before_modified != @after_modified, "Expected #{@before_modified.inspect} and #{@after_modified.inspect} to be different"
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+ require 'harmony'
3
+ require 'webrick'
4
+
5
+ class JavascriptTest < JavascriptFeatures::TestCase
6
+ uses_html_body{ '<h1>Test page</h1>' }
7
+ uses_feature_package :javascript_test
8
+ tests_feature :enabled_feature
9
+
10
+ should 'initialise the enabled feature' do
11
+ assert_selector_count 1, 'div.enabled_feature'
12
+ end
13
+
14
+ should 'not initialise the disabled feature' do
15
+ assert_selector_count 0, 'div.disabled_feature'
16
+ end
17
+
18
+ should 'initialise the global feature' do
19
+ assert_selector_count 1, 'div.global_feature'
20
+ end
21
+
22
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+ require 'jslint'
3
+
4
+ class JslintTest < Test::Unit::TestCase
5
+
6
+ context 'all built-in JavaScript' do
7
+ should 'pass JSLint' do
8
+ paths = File.join(File.dirname(__FILE__), '../assets/**/*.js')
9
+ exclude = File.join(File.dirname(__FILE__), '../assets/jquery.js')
10
+ JSLint::Lint.new(:paths => paths, :exclude_paths => exclude).run
11
+ end
12
+ end
13
+
14
+ end
data/test/rack_test.rb ADDED
@@ -0,0 +1,79 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+ require 'rack/test'
3
+ require 'rack/javascript_features'
4
+
5
+ class RackTest < Test::Unit::TestCase
6
+ include Rack::Test::Methods
7
+
8
+ def app
9
+ app = lambda{|env| [200, {"Content-Type" => "text/plain"}, ["all is well"]]}
10
+ Rack::JavascriptFeatures.new(app)
11
+ end
12
+
13
+ context "when JavaScript isn't being requested" do
14
+ setup do
15
+ get '/some/other/path'
16
+ end
17
+
18
+ should 'delegate to the app' do
19
+ assert_equal 200, last_response.status
20
+ assert_equal 'all is well', last_response.body
21
+ end
22
+ end
23
+
24
+ context "when the main JavaScript package is being requested" do
25
+ setup do
26
+ get '/javascripts/packaged/main.js'
27
+ end
28
+
29
+ should 'respond with the compiled JavaScript' do
30
+ assert_equal 200, last_response.status
31
+ assert_equal JavascriptFeatures::Compiler.compile, last_response.body
32
+ end
33
+ end
34
+
35
+ context "when the main JavaScript package is being requested with a valid ETag" do
36
+ setup do
37
+ get '/javascripts/packaged/main.js'
38
+ assert_not_nil etag = last_response.headers['ETag'], 'Expected an ETag'
39
+ get '/javascripts/packaged/main.js', {}, {'HTTP_IF_NONE_MATCH' => etag}
40
+ end
41
+
42
+ should "respond with 'not modified'" do
43
+ assert_equal 304, last_response.status
44
+ end
45
+ end
46
+
47
+ context "when the main JavaScript package is being requested with a valid ETag" do
48
+ setup do
49
+ get '/javascripts/package/main.js', {}, {'HTTP_IF_NONE_MATCH' => '12345'}
50
+ end
51
+
52
+ should "respond with some JavaScript" do
53
+ assert_equal 200, last_response.status
54
+ end
55
+ end
56
+
57
+ context "when an alternative JavaScript package is being requested" do
58
+ setup do
59
+ get '/javascripts/packaged/alternative.js'
60
+ end
61
+
62
+ should 'respond with the compiled JavaScript' do
63
+ assert_equal 200, last_response.status
64
+ assert_equal JavascriptFeatures::Compiler.compile(:package => 'alternative'), last_response.body
65
+ end
66
+ end
67
+
68
+ context "when an unknown JavaScript package is being requested" do
69
+ setup do
70
+ get '/javascripts/packaged/does_not_exist.js'
71
+ end
72
+
73
+ should 'delegate to the app' do
74
+ assert_equal 200, last_response.status
75
+ assert_equal 'all is well', last_response.body
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,59 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ class TestCaseTest < JavascriptFeatures::TestCase
4
+ uses_html_body{ '<div class="foo"></div>' }
5
+
6
+ should 'have some HTML' do
7
+ assert_not_nil @html
8
+ end
9
+
10
+ should 'include the main JS package' do
11
+ assert_match %r{<script [^>]*src="/javascripts/packaged/main\.js(\?\d+)?"}, @html
12
+ end
13
+
14
+ should 'take the enabled feature name from the class name' do
15
+ assert_match %r{<body class="with-js-testcase">}, @html
16
+ end
17
+
18
+ should 'create a Harmony::Page for the HTML' do
19
+ assert_not_nil @page
20
+ end
21
+
22
+ should 'load the JavaScript in the Harmony::Page' do
23
+ assert_equal 'object', @page.execute_js('typeof Features')
24
+ end
25
+
26
+ should 'provide a method of executing JS without knowing about the @page variable' do
27
+ assert_equal 'object', execute_js('typeof Features')
28
+ end
29
+
30
+ should 'provide a custom assertion for counting DOM nodes' do
31
+ assert_nothing_raised{ assert_selector_count(1, 'div.foo') }
32
+ assert_raises(Test::Unit::AssertionFailedError){ assert_selector_count(2, 'div.foo') }
33
+ end
34
+
35
+ end
36
+
37
+ class CustomFeatureTest < JavascriptFeatures::TestCase
38
+ uses_html_body{ '<div class="foo"></div>' }
39
+ tests_feature 'foo'
40
+
41
+ should 'use the custom feature instead of deriving the feature from the class name' do
42
+ assert_match %r{<body class="with-js-foo">}, @html
43
+ end
44
+ end
45
+
46
+ class MultipleFeatureTest < JavascriptFeatures::TestCase
47
+ uses_html_body{ '<div class="foo"></div>' }
48
+ tests_feature 'foo', 'bar', 'baz'
49
+
50
+ should 'use all of the custom features' do
51
+ ['foo', 'bar', 'baz'].each do |feature|
52
+ assert execute_js("jQuery('body').hasClass('with-js-#{feature}')")
53
+ end
54
+ end
55
+
56
+ should 'not use the feature name derived from the class name' do
57
+ assert execute_js('!jQuery("body").hasClass("with-js-mulitplefeature")')
58
+ end
59
+ end
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'bundler'
4
+ Bundler.require(:default, :development)
5
+
6
+ class Test::Unit::TestCase
7
+ attr_accessor :request, :response
8
+ end
9
+
10
+ module Rails
11
+ def self.root
12
+ File.join(File.dirname(__FILE__), 'fixtures') + '/'
13
+ end
14
+
15
+ def self.backtrace_cleaner
16
+ ActiveSupport::BacktraceCleaner.new
17
+ end
18
+ end
data/test/xhr_test.rb ADDED
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+ require 'harmony'
3
+
4
+ class XhrTest < JavascriptFeatures::TestCase
5
+
6
+ uses_html_body{%%
7
+ <h1>Test page</h1>
8
+ <div class="xhr-target"></div>
9
+ <div class="unrelated xhr-response">Unrelated</div>
10
+ %}
11
+
12
+ uses_feature_package :xhr_test
13
+
14
+ stubs_http_request('/xhr', :body => '<p class="real xhr-response">Hello, world</p>', :headers => {'X-JavascriptFeatures-Init' => 'load'})
15
+
16
+ should 'complete the XHR request' do
17
+ assert_selector_count 1, '.real.xhr-response'
18
+ end
19
+
20
+ should 'initialise the feature required by the XHR content' do
21
+ assert_match(/touched-by-load/, execute_js('jQuery(".real.xhr-response").attr("class")'))
22
+ end
23
+
24
+ should 'limit the scope of the feature required by the XHR content to the XHR content itself' do
25
+ assert_no_match(/touched-by-load/, execute_js('jQuery(".unrelated.xhr-response").attr("class")'))
26
+ end
27
+
28
+ should 're-run global initialisation code when the XHR completes, limited to the scope of the XHR content' do
29
+ assert_selector_count 1, '.real.xhr-response .touched-by-global-init'
30
+ assert_selector_count 1, '.unrelated.xhr-response .touched-by-global-init'
31
+ end
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,201 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: javascript_features
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - George Brocklehurst
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-15 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: jsmin
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: harmony
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: shoulda
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: redgreen
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: rack-test
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ - !ruby/object:Gem::Dependency
92
+ name: jslint_on_rails
93
+ prerelease: false
94
+ requirement: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :development
104
+ version_requirements: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: activesupport
107
+ prerelease: false
108
+ requirement: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ type: :development
118
+ version_requirements: *id007
119
+ - !ruby/object:Gem::Dependency
120
+ name: json
121
+ prerelease: false
122
+ requirement: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ type: :development
132
+ version_requirements: *id008
133
+ description:
134
+ email: george.brocklehurst@gmail.com
135
+ executables: []
136
+
137
+ extensions: []
138
+
139
+ extra_rdoc_files: []
140
+
141
+ files:
142
+ - test/compiler_test.rb
143
+ - test/fixtures/public/javascripts/alternative/alternative.js
144
+ - test/fixtures/public/javascripts/javascript_test/disabled_feature.js
145
+ - test/fixtures/public/javascripts/javascript_test/enabled_feature.js
146
+ - test/fixtures/public/javascripts/javascript_test/global_feature.js
147
+ - test/fixtures/public/javascripts/lib/jquery_plugin.js
148
+ - test/fixtures/public/javascripts/main/my_feature.js
149
+ - test/fixtures/public/javascripts/xhr_test/global_load.js
150
+ - test/fixtures/public/javascripts/xhr_test/load.js
151
+ - test/fixtures/public/javascripts/xhr_test/xhr.js
152
+ - test/helper_test.rb
153
+ - test/javascript_test.rb
154
+ - test/jslint_test.rb
155
+ - test/rack_test.rb
156
+ - test/test_case_test.rb
157
+ - test/test_helper.rb
158
+ - test/xhr_test.rb
159
+ - lib/javascript_features/compiler.rb
160
+ - lib/javascript_features/helper.rb
161
+ - lib/javascript_features/test_case/servlet.rb
162
+ - lib/javascript_features/test_case.rb
163
+ - lib/javascript_features.rb
164
+ - lib/rack/javascript_features.rb
165
+ - rails/init.rb
166
+ has_rdoc: true
167
+ homepage: http://georgebrock.com
168
+ licenses: []
169
+
170
+ post_install_message:
171
+ rdoc_options: []
172
+
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ hash: 3
181
+ segments:
182
+ - 0
183
+ version: "0"
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ hash: 3
190
+ segments:
191
+ - 0
192
+ version: "0"
193
+ requirements: []
194
+
195
+ rubyforge_project:
196
+ rubygems_version: 1.4.2
197
+ signing_key:
198
+ specification_version: 3
199
+ summary: Structured, unobtrusive JavaScript for Rails applications
200
+ test_files: []
201
+