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 CHANGED
@@ -1,3 +1,9 @@
1
+ v1.1.3 - May 27, 2011
2
+ ---------------------
3
+
4
+ ### Added:
5
+ * `Sinatra::UserAgentHelpers` for browser detection
6
+
1
7
  v1.1.2 - May 27, 2011
2
8
  ---------------------
3
9
 
@@ -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
@@ -1,6 +1,6 @@
1
1
  module Sinatra
2
2
  module Support
3
- VERSION = "1.1.2"
3
+ VERSION = "1.1.3"
4
4
 
5
5
  def self.version
6
6
  VERSION
@@ -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.2
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