rack-modernizr 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.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +21 -0
- data/LICENSE +22 -0
- data/README.md +27 -0
- data/Rakefile +26 -0
- data/lib/rack-modernizr.rb +72 -0
- data/lib/rack-modernizr/version.rb +3 -0
- data/modernizr.gemspec +25 -0
- data/test/spec_rack_modernizr.rb +94 -0
- metadata +114 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rack-modernizr (0.0.1)
|
5
|
+
rack
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
rack (1.2.1)
|
11
|
+
test-spec (0.10.0)
|
12
|
+
test-unit (2.1.1)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
ruby
|
16
|
+
|
17
|
+
DEPENDENCIES
|
18
|
+
rack
|
19
|
+
rack-modernizr!
|
20
|
+
test-spec (>= 0.9.0)
|
21
|
+
test-unit
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2010 Marshall C Yount; http://yountlabs.com
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# rack-modernizr
|
2
|
+
|
3
|
+
[Modernizr](http://modernizr.com) is a javascript utility that interrogates a user's web browser to determine its capabilities. Unfortunately, all this delicious data is only available client-side.
|
4
|
+
|
5
|
+
rack-modernizr is a Rack Middleware that includes the Modernizr javascript and stuffs Modernizr's output into a cookie on the first page request.
|
6
|
+
|
7
|
+
Include it in your config.ru like so:
|
8
|
+
|
9
|
+
# This file is used by Rack-based servers to start the application.
|
10
|
+
|
11
|
+
require ::File.expand_path('../config/environment', __FILE__)
|
12
|
+
require 'modernizr'
|
13
|
+
use Rack::Modernizr
|
14
|
+
|
15
|
+
run MyApp::Application
|
16
|
+
|
17
|
+
or environment.rb
|
18
|
+
|
19
|
+
# Load the rails application
|
20
|
+
require File.expand_path('../application', __FILE__)
|
21
|
+
|
22
|
+
config.middleware.use Rack::Modernizr
|
23
|
+
|
24
|
+
# Initialize the rails application
|
25
|
+
MyApp::Application.initialize!
|
26
|
+
|
27
|
+
rack-modernizr was inspired by [jamesgpearce](https://github.com/jamesgpearce)'s super awesome [modernizr-server](https://github.com/jamesgpearce/modernizr-server). Some javascript was used from that project.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require "net/https"
|
5
|
+
require "uri"
|
6
|
+
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/testtask'
|
9
|
+
|
10
|
+
desc "Run all the tests"
|
11
|
+
task :default => [:test]
|
12
|
+
|
13
|
+
desc "Run specs with test/unit style output"
|
14
|
+
task :test do
|
15
|
+
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS']}"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Run specs with specdoc style output"
|
19
|
+
task :spec do
|
20
|
+
sh "specrb -Ilib:test -s -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS']}"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Run all the tests"
|
24
|
+
task :fulltest do
|
25
|
+
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS']}"
|
26
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Modernizr
|
5
|
+
include Rack::Utils
|
6
|
+
|
7
|
+
def initialize(app, options = {})
|
8
|
+
@app, @options = app, options
|
9
|
+
@options[:modernizr_js_url] ||= "http://cachedcommons.org/cache/modernizr/1.5.0/javascripts/modernizr-min.js"
|
10
|
+
@options[:cookie_name] ||= "Modernizr"
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
@req = Rack::Request.new(env)
|
15
|
+
status, headers, response = @app.call(env)
|
16
|
+
|
17
|
+
if should_add_modernizr?(status, headers, response)
|
18
|
+
response = add_modernizr(response)
|
19
|
+
fix_content_length(headers, response)
|
20
|
+
end
|
21
|
+
|
22
|
+
[status, headers, response]
|
23
|
+
end
|
24
|
+
|
25
|
+
def should_add_modernizr?(status, headers, response)
|
26
|
+
!@req.cookies.has_key?( @options[:cookie_name] ) &&
|
27
|
+
status==200 &&
|
28
|
+
headers["Content-Type"] &&
|
29
|
+
headers["Content-Type"].include?("text/html")
|
30
|
+
end
|
31
|
+
|
32
|
+
def fix_content_length(headers, response)
|
33
|
+
# Set new Content-Length, if it was set before we mutated the response body
|
34
|
+
if headers['Content-Length']
|
35
|
+
length = response.to_ary.inject(0) { |len, part| len + bytesize(part) }
|
36
|
+
headers['Content-Length'] = length.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_modernizr(response, body = "")
|
41
|
+
response.each{ |s| body << s.to_s }
|
42
|
+
[body.gsub(/\<\/body\>/, "#{modernizr_js}</body>")]
|
43
|
+
end
|
44
|
+
|
45
|
+
def modernizr_js
|
46
|
+
"<script src=\"#{@options[:modernizr_js_url]}\" type=\"text/javascript\"></script>" +
|
47
|
+
"<script type=\"text/javascript\">#{set_cookie_js}</script>"
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_cookie_js
|
51
|
+
"var m=Modernizr,c='';" +
|
52
|
+
"for(var f in m){" +
|
53
|
+
"if(f[0]=='_'){continue;}" +
|
54
|
+
"var t=typeof m[f];" +
|
55
|
+
"if(t=='function'){continue;}" +
|
56
|
+
"c+=(c?'|':'#{@options[:cookie_name]}=')+f+':';" +
|
57
|
+
"if(t=='object'){" +
|
58
|
+
"for(var s in m[f]){" +
|
59
|
+
"c+='/'+s+':'+(m[f][s]?'1':'0');" +
|
60
|
+
"}" +
|
61
|
+
"}else{" +
|
62
|
+
"c+=m[f]?'1':'0';" +
|
63
|
+
"}" +
|
64
|
+
"}" +
|
65
|
+
"c+=';path=/';" +
|
66
|
+
"try{" +
|
67
|
+
"document.cookie=c;" +
|
68
|
+
"}catch(e){}" +
|
69
|
+
""
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/modernizr.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rack-modernizr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rack-modernizr"
|
7
|
+
s.version = Modernizr::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Marshall Yount"]
|
10
|
+
s.email = ["marshall@yountlabs.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/rack-modernizr"
|
12
|
+
s.summary = %q{a Rack middleware that brings the power of the Modernizr javascript framework server-side}
|
13
|
+
s.description = %q{Rack::Modernizr is a Rack middleware that automagically includes the Modernizr javascript framework and exposes the results to your server-side scripts.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "rack-modernizr"
|
16
|
+
|
17
|
+
s.add_dependency 'rack'
|
18
|
+
s.add_development_dependency 'test-spec', '>= 0.9.0'
|
19
|
+
s.add_development_dependency 'test-unit'
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
require 'rack/mock'
|
3
|
+
require 'rack-modernizr'
|
4
|
+
|
5
|
+
context "Rack::Modernizr" do
|
6
|
+
|
7
|
+
context "when a modernizr cookie has not been set" do
|
8
|
+
specify "should insert script tag" do
|
9
|
+
test_body = "<html><body>Hello World</body></html>"
|
10
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html'}, [test_body]] }
|
11
|
+
request = Rack::MockRequest.env_for("/test.html")
|
12
|
+
body = Rack::Modernizr.new(app).call(request).last
|
13
|
+
body[0].should.include? "script"
|
14
|
+
end
|
15
|
+
|
16
|
+
specify "should correct Content-Length header" do
|
17
|
+
test_body = "<html><body>Hello World</body></html>"
|
18
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html', 'Content-Length' => 37}, [test_body]] }
|
19
|
+
request = Rack::MockRequest.env_for("/test.html")
|
20
|
+
status, headers, body = Rack::Modernizr.new(app).call(request)
|
21
|
+
|
22
|
+
body[0].length.should.not.equal test_body.length
|
23
|
+
body[0].length.should.equal body[0].length
|
24
|
+
end
|
25
|
+
|
26
|
+
specify "should insert code when charset is specified" do
|
27
|
+
test_body = "<html><body>Hello World</body></html>"
|
28
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html; charset=utf-8'}, [test_body]] }
|
29
|
+
request = Rack::MockRequest.env_for("/test.html")
|
30
|
+
body = Rack::Modernizr.new(app).call(request).last
|
31
|
+
body[0].should.include? "script"
|
32
|
+
end
|
33
|
+
|
34
|
+
specify "should insert correct URL if initialized" do
|
35
|
+
test_body = "<html><body>Hello World</body></html>"
|
36
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html; charset=utf-8'}, [test_body]] }
|
37
|
+
request = Rack::MockRequest.env_for("/test.html")
|
38
|
+
body = Rack::Modernizr.new(app, :modernizr_js_url => "http://distinctive.domain.com/modernizr.js").call(request).last
|
39
|
+
body[0].should.include? "distinctive.domain.com"
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "should use cookie name if initialized" do
|
43
|
+
test_body = "<html><body>Hello World</body></html>"
|
44
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html; charset=utf-8'}, [test_body]] }
|
45
|
+
request = Rack::MockRequest.env_for("/test.html")
|
46
|
+
body = Rack::Modernizr.new(app, :cookie_name => "distinctive_name").call(request).last
|
47
|
+
body[0].should.include? "distinctive_name"
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "should work if request body is fragmented" do
|
51
|
+
test_body = ["<html><body>Hello World</bo", "dy></html>"]
|
52
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html; charset=utf-8'}, test_body] }
|
53
|
+
request = Rack::MockRequest.env_for("/test.html")
|
54
|
+
body = Rack::Modernizr.new(app).call(request).last
|
55
|
+
body[0].should.include? "script"
|
56
|
+
end
|
57
|
+
|
58
|
+
specify "should not insert code if error response" do
|
59
|
+
test_body = "<html><body>Not Found!</body></html>"
|
60
|
+
app = lambda { |env| [404, {'Content-Type' => 'text/html'}, [test_body]] }
|
61
|
+
request = Rack::MockRequest.env_for("/test.html")
|
62
|
+
body = Rack::Modernizr.new(app).call(request).last
|
63
|
+
body[0].should.not.include? "script"
|
64
|
+
end
|
65
|
+
|
66
|
+
specify "should not insert code if non-html response" do
|
67
|
+
test_body = "<html><body>Silly invalid html document that somehow gets stamped to text/css</body></html>"
|
68
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/css'}, [test_body]] }
|
69
|
+
request = Rack::MockRequest.env_for("/test.css")
|
70
|
+
body = Rack::Modernizr.new(app).call(request).last
|
71
|
+
body[0].should.not.include? "script"
|
72
|
+
end
|
73
|
+
|
74
|
+
specify "should not insert code if there is no body tag" do
|
75
|
+
test_body = "<html>Malformed document</html>"
|
76
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html'}, [test_body]] }
|
77
|
+
request = Rack::MockRequest.env_for("/test.html")
|
78
|
+
body = Rack::Modernizr.new(app).call(request).last
|
79
|
+
body[0].should.not.include? "script"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
context "when a modernizr cookie has already been set" do
|
85
|
+
specify "should not mess with the response in any way" do
|
86
|
+
test_body = "<html><body>Hello World</body></html>"
|
87
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html'}, [test_body]] }
|
88
|
+
request = Rack::MockRequest.env_for("/test.html", "HTTP_COOKIE" => "Modernizr=blarghfasel")
|
89
|
+
body = Rack::Modernizr.new(app).call(request).last
|
90
|
+
puts body[0]
|
91
|
+
body[0].should.not.include? "script"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-modernizr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Marshall Yount
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-08 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rack
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: test-spec
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 9
|
44
|
+
- 0
|
45
|
+
version: 0.9.0
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: test-unit
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
type: :development
|
60
|
+
version_requirements: *id003
|
61
|
+
description: Rack::Modernizr is a Rack middleware that automagically includes the Modernizr javascript framework and exposes the results to your server-side scripts.
|
62
|
+
email:
|
63
|
+
- marshall@yountlabs.com
|
64
|
+
executables: []
|
65
|
+
|
66
|
+
extensions: []
|
67
|
+
|
68
|
+
extra_rdoc_files: []
|
69
|
+
|
70
|
+
files:
|
71
|
+
- .gitignore
|
72
|
+
- Gemfile
|
73
|
+
- Gemfile.lock
|
74
|
+
- LICENSE
|
75
|
+
- README.md
|
76
|
+
- Rakefile
|
77
|
+
- lib/rack-modernizr.rb
|
78
|
+
- lib/rack-modernizr/version.rb
|
79
|
+
- modernizr.gemspec
|
80
|
+
- test/spec_rack_modernizr.rb
|
81
|
+
has_rdoc: true
|
82
|
+
homepage: http://rubygems.org/gems/rack-modernizr
|
83
|
+
licenses: []
|
84
|
+
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
version: "0"
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project: rack-modernizr
|
109
|
+
rubygems_version: 1.3.7
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: a Rack middleware that brings the power of the Modernizr javascript framework server-side
|
113
|
+
test_files:
|
114
|
+
- test/spec_rack_modernizr.rb
|