browsernizer 0.1.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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/README.md +53 -0
- data/Rakefile +8 -0
- data/browsernizer.gemspec +25 -0
- data/lib/browsernizer.rb +13 -0
- data/lib/browsernizer/browser.rb +6 -0
- data/lib/browsernizer/browser_version.rb +24 -0
- data/lib/browsernizer/config.rb +26 -0
- data/lib/browsernizer/router.rb +46 -0
- data/lib/browsernizer/version.rb +3 -0
- data/lib/generators/browsernizer/install_generator.rb +12 -0
- data/lib/generators/templates/browsernizer.rb +7 -0
- data/spec/browsernizer/browser_version_spec.rb +31 -0
- data/spec/browsernizer/config_spec.rb +29 -0
- data/spec/browsernizer/router_spec.rb +78 -0
- data/spec/spec_helper.rb +2 -0
- metadata +100 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Browsernizer
|
2
|
+
|
3
|
+
Want friendly "please upgrade your browser" page? This gem is for you.
|
4
|
+
|
5
|
+
You can redirect your visitors to any page you like (static or dynamic).
|
6
|
+
Just specify `config.location` option in initializer file.
|
7
|
+
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add following line to your `Gemfile`:
|
12
|
+
|
13
|
+
gem 'browsernizer'
|
14
|
+
|
15
|
+
Hook it up:
|
16
|
+
|
17
|
+
rails generate browsernizer:install
|
18
|
+
|
19
|
+
Configure browser support in `config/initializers/browsernizer.rb` file.
|
20
|
+
|
21
|
+
All browsers that are not listed in initializer file will be considered to be **supported**.
|
22
|
+
|
23
|
+
|
24
|
+
## Browsers
|
25
|
+
|
26
|
+
You should specify browser name as a string. Here are the available options:
|
27
|
+
|
28
|
+
* Chrome
|
29
|
+
* Firefox
|
30
|
+
* Safari
|
31
|
+
* Opera
|
32
|
+
* Internet Explorer
|
33
|
+
|
34
|
+
And some less popular:
|
35
|
+
|
36
|
+
* Android
|
37
|
+
* webOS
|
38
|
+
* BlackBerry
|
39
|
+
* Symbian
|
40
|
+
* Camino
|
41
|
+
* Iceweasel
|
42
|
+
* Seamonkey
|
43
|
+
|
44
|
+
Browser detection is done using [useragent gem](https://github.com/josh/useragent).
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
## Credits and License
|
49
|
+
|
50
|
+
Developed by Milovan Zogovic.
|
51
|
+
|
52
|
+
I don't believe in licenses and other woody crap.
|
53
|
+
Do whatever you want with this :)
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "browsernizer/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "browsernizer"
|
7
|
+
s.version = Browsernizer::VERSION
|
8
|
+
s.authors = ["Milovan Zogovic"]
|
9
|
+
s.email = ["milovan.zogovic@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Want friendly "please upgrade your browser" page? This gem is for you.}
|
12
|
+
s.description = %q{Rack middleware for redirecting unsupported user agents to "please upgrade" page}
|
13
|
+
|
14
|
+
s.rubyforge_project = "browsernizer"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "rake"
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
|
24
|
+
s.add_runtime_dependency 'useragent', "~> 0.4.6"
|
25
|
+
end
|
data/lib/browsernizer.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#TODO: remove when useragent gem is fixed
|
2
|
+
require 'rubygems'
|
3
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
4
|
+
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
5
|
+
|
6
|
+
|
7
|
+
require "browsernizer/browser"
|
8
|
+
require "browsernizer/browser_version"
|
9
|
+
require "browsernizer/config"
|
10
|
+
require "browsernizer/router"
|
11
|
+
require "browsernizer/version"
|
12
|
+
|
13
|
+
require 'useragent'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Browsernizer
|
2
|
+
class BrowserVersion
|
3
|
+
include ::Comparable
|
4
|
+
|
5
|
+
attr_accessor :to_a
|
6
|
+
|
7
|
+
def initialize(version)
|
8
|
+
@version = version
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_a
|
12
|
+
@version.split(".").map{ |s| s.to_i }
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(other)
|
16
|
+
([0]*6).zip(to_a, other.to_a).each do |dump, a, b|
|
17
|
+
r = (a||0) <=> (b||0)
|
18
|
+
return r unless r.zero?
|
19
|
+
end
|
20
|
+
0
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Browsernizer
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@supported = []
|
6
|
+
@location = "/unsupported-browser.html"
|
7
|
+
end
|
8
|
+
|
9
|
+
def supported(browser, version)
|
10
|
+
@supported << Browser.new(browser.to_s, version.to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
def location(path)
|
14
|
+
@location = path
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_supported
|
18
|
+
@supported
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_location
|
22
|
+
@location
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Browsernizer
|
2
|
+
|
3
|
+
class Router
|
4
|
+
def initialize(app, &block)
|
5
|
+
@app = app
|
6
|
+
@config = Config.new
|
7
|
+
yield(@config)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
@env = env
|
12
|
+
|
13
|
+
if html_request? && !on_redirection_path? && unsupported?
|
14
|
+
[307, {"Content-Type" => "text/plain", "Location" => @config.get_location}, []]
|
15
|
+
elsif html_request? && on_redirection_path? && !unsupported?
|
16
|
+
[303, {"Content-Type" => "text/plain", "Location" => "/"}, []]
|
17
|
+
else
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def html_request?
|
24
|
+
@env["HTTP_ACCEPT"] && @env["HTTP_ACCEPT"].include?("text/html")
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_redirection_path?
|
28
|
+
@env["PATH_INFO"] && @env["PATH_INFO"] == @config.get_location
|
29
|
+
end
|
30
|
+
|
31
|
+
# supported by default
|
32
|
+
def unsupported?
|
33
|
+
agent = ::UserAgent.parse @env["HTTP_USER_AGENT"]
|
34
|
+
@config.get_supported.detect do |supported_browser|
|
35
|
+
if agent.browser.to_s.downcase == supported_browser.browser.to_s.downcase
|
36
|
+
a = BrowserVersion.new agent.version.to_s
|
37
|
+
b = BrowserVersion.new supported_browser.version.to_s
|
38
|
+
a < b
|
39
|
+
end
|
40
|
+
# TODO: when useragent is fixed you can use just this line instead the above
|
41
|
+
# agent < supported_browser
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Browsernizer
|
2
|
+
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
desc "Copies initializer script"
|
7
|
+
def copy_initializer
|
8
|
+
copy_file "browsernizer.rb", "config/initializers/browsernizer.rb"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Browsernizer::BrowserVersion do
|
4
|
+
|
5
|
+
describe "Comparable" do
|
6
|
+
|
7
|
+
it "is greater" do
|
8
|
+
version("2").should > version("1")
|
9
|
+
version("1.1").should > version("1")
|
10
|
+
version("1.1").should > version("1.0")
|
11
|
+
version("2").should > version("1.9")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is equal" do
|
15
|
+
version("1").should == version("1")
|
16
|
+
version("1").should == version("1.0")
|
17
|
+
version("1.0").should == version("1")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "handles strings" do
|
21
|
+
version("1.0").should == version("1.0.alpha")
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def version(str)
|
28
|
+
Browsernizer::BrowserVersion.new(str)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Browsernizer::Config do
|
4
|
+
|
5
|
+
subject { config = Browsernizer::Config.new }
|
6
|
+
|
7
|
+
describe "new" do
|
8
|
+
it "sets the defaults" do
|
9
|
+
subject.get_supported.should == []
|
10
|
+
subject.get_location.should == "/unsupported-browser.html"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "supported(name, version)" do
|
15
|
+
it "defines new supported browser" do
|
16
|
+
subject.supported "Chrome", "16.0"
|
17
|
+
subject.supported "Firefox", "10.0"
|
18
|
+
subject.get_supported.should have(2).items
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "location(path)" do
|
23
|
+
it "sets the redirection path for unsupported browsers" do
|
24
|
+
subject.location "foo.html"
|
25
|
+
subject.get_location.should == "foo.html"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Browsernizer::Router do
|
4
|
+
|
5
|
+
let(:app) { mock() }
|
6
|
+
|
7
|
+
subject do
|
8
|
+
Browsernizer::Router.new(app) do |config|
|
9
|
+
config.supported "Firefox", "4"
|
10
|
+
config.supported "Chrome", "7.1"
|
11
|
+
config.location "/browser.html"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:default_env) do
|
16
|
+
{
|
17
|
+
"HTTP_USER_AGENT" => chrome_agent("7.1.1"),
|
18
|
+
"HTTP_ACCEPT" => "text/html",
|
19
|
+
"PATH_INFO" => "/index"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
context "All Good" do
|
24
|
+
it "propagates request" do
|
25
|
+
app.should_receive(:call).with(default_env)
|
26
|
+
subject.call(default_env)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "Unsupported Browser" do
|
31
|
+
before do
|
32
|
+
@env = default_env.merge({
|
33
|
+
"HTTP_USER_AGENT" => chrome_agent("7")
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
it "prevents propagation" do
|
38
|
+
app.should_not_receive(:call)
|
39
|
+
subject.call(@env)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "redirects to proper location" do
|
43
|
+
response = subject.call(@env)
|
44
|
+
response[0].should == 307
|
45
|
+
response[1]["Location"].should == "/browser.html"
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Non-html request" do
|
49
|
+
before do
|
50
|
+
@env = @env.merge({
|
51
|
+
"HTTP_ACCEPT" => "text/css"
|
52
|
+
})
|
53
|
+
end
|
54
|
+
it "propagates request" do
|
55
|
+
app.should_receive(:call).with(@env)
|
56
|
+
subject.call(@env)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "Already on /browser.html page" do
|
61
|
+
before do
|
62
|
+
@env = @env.merge({
|
63
|
+
"PATH_INFO" => "/browser.html"
|
64
|
+
})
|
65
|
+
end
|
66
|
+
it "propagates request" do
|
67
|
+
app.should_receive(:call).with(@env)
|
68
|
+
subject.call(@env)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def chrome_agent(version)
|
75
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/#{version} Safari/535.7"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: browsernizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Milovan Zogovic
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-06 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70114897960180 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70114897960180
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70114897959760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70114897959760
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: useragent
|
38
|
+
requirement: &70114897959260 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.4.6
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70114897959260
|
47
|
+
description: Rack middleware for redirecting unsupported user agents to "please upgrade"
|
48
|
+
page
|
49
|
+
email:
|
50
|
+
- milovan.zogovic@gmail.com
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- browsernizer.gemspec
|
60
|
+
- lib/browsernizer.rb
|
61
|
+
- lib/browsernizer/browser.rb
|
62
|
+
- lib/browsernizer/browser_version.rb
|
63
|
+
- lib/browsernizer/config.rb
|
64
|
+
- lib/browsernizer/router.rb
|
65
|
+
- lib/browsernizer/version.rb
|
66
|
+
- lib/generators/browsernizer/install_generator.rb
|
67
|
+
- lib/generators/templates/browsernizer.rb
|
68
|
+
- spec/browsernizer/browser_version_spec.rb
|
69
|
+
- spec/browsernizer/config_spec.rb
|
70
|
+
- spec/browsernizer/router_spec.rb
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
homepage: ''
|
73
|
+
licenses: []
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project: browsernizer
|
92
|
+
rubygems_version: 1.8.15
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: Want friendly "please upgrade your browser" page? This gem is for you.
|
96
|
+
test_files:
|
97
|
+
- spec/browsernizer/browser_version_spec.rb
|
98
|
+
- spec/browsernizer/config_spec.rb
|
99
|
+
- spec/browsernizer/router_spec.rb
|
100
|
+
- spec/spec_helper.rb
|