sinatra-support 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +6 -0
- data/lib/sinatra/support.rb +1 -0
- data/lib/sinatra/support/useragenthelpers.rb +134 -0
- data/lib/sinatra/support/version.rb +1 -1
- data/test/test_useragent_app.rb +25 -0
- metadata +3 -1
data/HISTORY.md
CHANGED
data/lib/sinatra/support.rb
CHANGED
@@ -8,6 +8,7 @@ module Sinatra
|
|
8
8
|
autoload :HtmlHelpers, File.expand_path('../support/htmlhelpers', __FILE__)
|
9
9
|
autoload :JsSupport, File.expand_path('../support/jssupport', __FILE__)
|
10
10
|
autoload :OhmErrorHelpers, File.expand_path('../support/ohmerrorhelpers', __FILE__)
|
11
|
+
autoload :UserAgentHelpers,File.expand_path('../support/useragenthelpers', __FILE__)
|
11
12
|
autoload :Numeric, File.expand_path('../support/numeric', __FILE__)
|
12
13
|
autoload :IfHelpers, File.expand_path('../support/ifhelpers', __FILE__)
|
13
14
|
autoload :I18nSupport, File.expand_path('../support/i18nsupport', __FILE__)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# == Usage
|
2
|
+
#
|
3
|
+
# register Sinatra::UserAgentHelpers
|
4
|
+
#
|
5
|
+
# == Example
|
6
|
+
#
|
7
|
+
# After you have registered the UserAgentHelpers, use the {#browser} helper to
|
8
|
+
# check for features:
|
9
|
+
#
|
10
|
+
# <% if browser.ios? %>
|
11
|
+
# <p>Download our mobile app!</p>
|
12
|
+
# <% end %>
|
13
|
+
#
|
14
|
+
# Or use the #body_class method:
|
15
|
+
#
|
16
|
+
# <body class="<%= browser.body_class %>">
|
17
|
+
#
|
18
|
+
# The above line can have an output like so:
|
19
|
+
#
|
20
|
+
# <body class="webkit safari mac">
|
21
|
+
# <body class="windows ie ie6">
|
22
|
+
#
|
23
|
+
# == Helper
|
24
|
+
#
|
25
|
+
# #browser -- provides the browser helper. Refer to the {UserAgent} class
|
26
|
+
# for more info.
|
27
|
+
#
|
28
|
+
module Sinatra::UserAgentHelpers
|
29
|
+
def browser
|
30
|
+
UserAgent.new(env['HTTP_USER_AGENT'] || '')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class UserAgent
|
35
|
+
UA_REGEXP = %r{([^ /]+)/([^ ]+)(?: \(([^)]+)\))?}
|
36
|
+
|
37
|
+
def initialize(ua)
|
38
|
+
@ua_string = ua
|
39
|
+
@ua = ua.scan(UA_REGEXP).map { |r|
|
40
|
+
r[2] = r[2].split(';').map { |s| s.strip } unless r[2].nil?
|
41
|
+
{ :product => r[0], :version => r[1], :details => r[2] }
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
# Browsers
|
46
|
+
def webkit?() product?('AppleWebKit'); end
|
47
|
+
def chrome?() product?('Chrome'); end
|
48
|
+
def safari?() product?('Safari') && !chrome?; end
|
49
|
+
def ios?() product?('Safari') && product?('Mobile'); end
|
50
|
+
def gecko?() product?('Gecko'); end
|
51
|
+
def opera?() product?('Opera'); end
|
52
|
+
def ie?() detail?(/^MSIE/, 'Mozilla'); end
|
53
|
+
|
54
|
+
# OS's and devices
|
55
|
+
def linux?() detail?(/^Linux/, 'Mozilla'); end
|
56
|
+
def iphone?() detail?(/^iPhone/, 'Mozilla'); end
|
57
|
+
def rim?() detail?(/^Blackberry/, 'Mozilla'); end
|
58
|
+
def android?() detail?(/^Android/, 'Mozilla'); end
|
59
|
+
def android1?() detail?(/^Android 1\./, 'Mozilla'); end
|
60
|
+
def android2?() detail?(/^Android 2\./, 'Mozilla'); end
|
61
|
+
def nokia?() detail?(/^Nokia/, 'Mozilla') || detail?(/^Series[38]0/, 'Mozilla'); end
|
62
|
+
def ipad?() detail?(/^iPad/, 'Mozilla'); end
|
63
|
+
def windows?() detail?(/^Windows/, 'Mozilla'); end
|
64
|
+
def osx?() detail?(/^(Intel )?Mac OS X/, 'Mozilla'); end
|
65
|
+
def mac?() detail?(/^Macintosh/, 'Mozilla') || osx?; end
|
66
|
+
def blackberry?() detail?(/^Blackberry/, 'Mozilla'); end
|
67
|
+
|
68
|
+
# IE
|
69
|
+
def ie9?() detail?('MSIE 9.0', 'Mozilla'); end
|
70
|
+
def ie8?() detail?('MSIE 8.0', 'Mozilla'); end
|
71
|
+
def ie7?() detail?(/^MSIE 7.0/, 'Mozilla'); end
|
72
|
+
def ie6?() detail?(/^MSIE 6/, 'Mozilla'); end
|
73
|
+
|
74
|
+
# Different Firefox versions
|
75
|
+
def gecko40?() gecko_version?(20100401, 20110101); end
|
76
|
+
def gecko36?() gecko_version?(20091111, 20100401); end
|
77
|
+
def gecko35?() gecko_version?(20090612, 20091111); end
|
78
|
+
def gecko30?() gecko_version?(20080610, 20090612); end
|
79
|
+
def gecko20?() gecko_version?(20061010, 20080610); end
|
80
|
+
def gecko_old?() gecko_version?(0, 20061010); end
|
81
|
+
|
82
|
+
def gecko_version?(from, to)
|
83
|
+
g = product('Gecko')
|
84
|
+
return nil if g.nil?
|
85
|
+
v = g[:version][0...8].to_i
|
86
|
+
(v >= from) and (v < to)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the list of applicable browser features.
|
90
|
+
#
|
91
|
+
# == Examples
|
92
|
+
#
|
93
|
+
# <body class="<%= browser.body_class %>">
|
94
|
+
#
|
95
|
+
# This can return one of the following:
|
96
|
+
#
|
97
|
+
# <body class="ios webkit ipad">
|
98
|
+
# <body class="chrome linux webkit">
|
99
|
+
# <body class="gecko linux">
|
100
|
+
# <body class="windows ie ie6">
|
101
|
+
#
|
102
|
+
def body_class
|
103
|
+
(%w(webkit chrome safari ios gecko opera ie linux) +
|
104
|
+
%w(blackberry nokia android iphone) +
|
105
|
+
%w(gecko36 gecko35 gecko30 gecko20 gecko_old) +
|
106
|
+
%w(ipad windows osx mac ie6 ie7 ie8 ie9)).map do |aspect|
|
107
|
+
aspect if self.send :"#{aspect}?"
|
108
|
+
end.compact.join(' ')
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
def to_s() @ua_string; end
|
113
|
+
def inspect() @ua.inspect; end
|
114
|
+
|
115
|
+
# Checks for, say, 'Gecko' in 'Gecko/3.9.82'
|
116
|
+
def product?(str)
|
117
|
+
!! product(str)
|
118
|
+
end
|
119
|
+
|
120
|
+
def product(str)
|
121
|
+
@ua.detect { |p| p[:product] == str }
|
122
|
+
end
|
123
|
+
|
124
|
+
# Checks for, say, 'MSIE' in 'Mozilla/5.0 (MSIE; x; x)'
|
125
|
+
def detail?(detail, prod=nil)
|
126
|
+
!! @ua.detect { |p|
|
127
|
+
prod.nil? || prod == p[:product] && has_spec(p[:details], detail)
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
def has_spec(haystack, spec)
|
132
|
+
!haystack.nil? && haystack.detect { |d| d.match(spec) }
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
Encoding.default_external = 'utf-8'
|
4
|
+
|
5
|
+
class UserAgentAppTest < Test::Unit::TestCase
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
class App < Sinatra::Base
|
9
|
+
helpers Sinatra::UserAgentHelpers
|
10
|
+
get('/class') { "<body class='#{browser.body_class}'>" }
|
11
|
+
end
|
12
|
+
|
13
|
+
UA_CHROME = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.68 Safari/534.24"
|
14
|
+
|
15
|
+
def app
|
16
|
+
App.new
|
17
|
+
end
|
18
|
+
|
19
|
+
test "boogie" do
|
20
|
+
header 'User-Agent', UA_CHROME
|
21
|
+
get '/class'
|
22
|
+
|
23
|
+
assert_equal "<body class='webkit chrome osx mac'>", last_response.body.strip
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: sinatra-support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.1.
|
5
|
+
version: 1.1.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Cyril David
|
@@ -116,6 +116,7 @@ files:
|
|
116
116
|
- lib/sinatra/support/multirender.rb
|
117
117
|
- lib/sinatra/support/numeric.rb
|
118
118
|
- lib/sinatra/support/ohmerrorhelpers.rb
|
119
|
+
- lib/sinatra/support/useragenthelpers.rb
|
119
120
|
- lib/sinatra/support/version.rb
|
120
121
|
- lib/sinatra/support.rb
|
121
122
|
- test/fixtures/css/style-less.less
|
@@ -141,6 +142,7 @@ files:
|
|
141
142
|
- test/test_multirender.rb
|
142
143
|
- test/test_numeric.rb
|
143
144
|
- test/test_ohmerror.rb
|
145
|
+
- test/test_useragent_app.rb
|
144
146
|
- HISTORY.md
|
145
147
|
- Rakefile
|
146
148
|
has_rdoc: true
|