sinatra-support 1.1.2 → 1.1.3
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/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
|