browser 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/browser.rb CHANGED
@@ -1,15 +1,35 @@
1
1
  require "set"
2
2
 
3
+ require "browser/middleware"
4
+ require "browser/middleware/context"
5
+ require "browser/rails" if defined?(::Rails)
6
+
7
+ require "browser/methods/ie"
8
+ require "browser/methods/platform"
9
+ require "browser/methods/mobile"
10
+ require "browser/methods/devices"
11
+ require "browser/methods/language"
12
+
13
+ require "browser/meta/base"
14
+ require "browser/meta/generic_browser"
15
+ require "browser/meta/id"
16
+ require "browser/meta/ie"
17
+ require "browser/meta/ios"
18
+ require "browser/meta/mobile"
19
+ require "browser/meta/modern"
20
+ require "browser/meta/platform"
21
+ require "browser/meta/safari"
22
+ require "browser/meta/webkit"
23
+
3
24
  class Browser
4
- # Add Rails helper if ActionController::Base is available
5
- require "browser/action_controller" if defined?(ActionController::Base)
25
+ include IE
26
+ include Platform
27
+ include Mobile
28
+ include Devices
29
+ include Language
6
30
 
7
31
  # Set browser's UA string.
8
32
  attr_accessor :user_agent
9
-
10
- # Set browser's preferred language
11
- attr_writer :accept_language
12
-
13
33
  alias :ua :user_agent
14
34
  alias :ua= :user_agent=
15
35
 
@@ -17,141 +37,25 @@ class Browser
17
37
  :android => "Android",
18
38
  :blackberry => "BlackBerry",
19
39
  :chrome => "Chrome",
40
+ :core_media => "Apple CoreMedia",
20
41
  :firefox => "Firefox",
21
42
  :ie => "Internet Explorer",
22
43
  :ipad => "iPad",
23
44
  :iphone => "iPhone",
24
45
  :ipod => "iPod Touch",
25
46
  :opera => "Opera",
26
- :other => "Other",
27
- :safari => "Safari",
47
+ :phantom_js => "PhantomJS",
28
48
  :psp => "PlayStation Portable",
29
49
  :quicktime => "QuickTime",
30
- :core_media => "Apple CoreMedia"
31
- }
50
+ :safari => "Safari",
32
51
 
33
- VERSIONS = {
34
- :default => /(?:Version|MSIE|Firefox|Chrome|CriOS|QuickTime|BlackBerry[^\/]+|CoreMedia v)[\/ ]?([a-z0-9.]+)/i,
35
- :opera => /Opera\/.*? Version\/([\d.]+)/
52
+ # This must be last item, since Ruby 1.9+ has ordered keys.
53
+ :other => "Other",
36
54
  }
37
55
 
38
- TRIDENT_VERSION_REGEX = /Trident\/([0-9.]+)/
39
-
40
- LANGUAGES = {
41
- "af" => "Afrikaans",
42
- "sq" => "Albanian",
43
- "eu" => "Basque",
44
- "bg" => "Bulgarian",
45
- "be" => "Byelorussian",
46
- "ca" => "Catalan",
47
- "zh" => "Chinese",
48
- "zh-cn" => "Chinese/China",
49
- "zh-tw" => "Chinese/Taiwan",
50
- "zh-hk" => "Chinese/Hong Kong",
51
- "zh-sg" => "Chinese/singapore",
52
- "hr" => "Croatian",
53
- "cs" => "Czech",
54
- "da" => "Danish",
55
- "nl" => "Dutch",
56
- "nl-nl" => "Dutch/Netherlands",
57
- "nl-be" => "Dutch/Belgium",
58
- "en" => "English",
59
- "en-gb" => "English/United Kingdom",
60
- "en-us" => "English/United States",
61
- "en-au" => "English/Australian",
62
- "en-ca" => "English/Canada",
63
- "en-nz" => "English/New Zealand",
64
- "en-ie" => "English/Ireland",
65
- "en-za" => "English/South Africa",
66
- "en-jm" => "English/Jamaica",
67
- "en-bz" => "English/Belize",
68
- "en-tt" => "English/Trinidad",
69
- "et" => "Estonian",
70
- "fo" => "Faeroese",
71
- "fa" => "Farsi",
72
- "fi" => "Finnish",
73
- "fr" => "French",
74
- "fr-be" => "French/Belgium",
75
- "fr-fr" => "French/France",
76
- "fr-ch" => "French/Switzerland",
77
- "fr-ca" => "French/Canada",
78
- "fr-lu" => "French/Luxembourg",
79
- "gd" => "Gaelic",
80
- "gl" => "Galician",
81
- "de" => "German",
82
- "de-at" => "German/Austria",
83
- "de-de" => "German/Germany",
84
- "de-ch" => "German/Switzerland",
85
- "de-lu" => "German/Luxembourg",
86
- "de-li" => "German/Liechtenstein",
87
- "el" => "Greek",
88
- "he" => "Hebrew",
89
- "he-il" => "Hebrew/Israel",
90
- "hi" => "Hindi",
91
- "hu" => "Hungarian",
92
- "ie-ee" => "Internet Explorer/Easter Egg",
93
- "is" => "Icelandic",
94
- "id" => "Indonesian",
95
- "in" => "Indonesian",
96
- "ga" => "Irish",
97
- "it" => "Italian",
98
- "it-ch" => "Italian/ Switzerland",
99
- "ja" => "Japanese",
100
- "km" => "Khmer",
101
- "km-kh" => "Khmer/Cambodia",
102
- "ko" => "Korean",
103
- "lv" => "Latvian",
104
- "lt" => "Lithuanian",
105
- "mk" => "Macedonian",
106
- "ms" => "Malaysian",
107
- "mt" => "Maltese",
108
- "no" => "Norwegian",
109
- "pl" => "Polish",
110
- "pt" => "Portuguese",
111
- "pt-br" => "Portuguese/Brazil",
112
- "rm" => "Rhaeto-Romanic",
113
- "ro" => "Romanian",
114
- "ro-mo" => "Romanian/Moldavia",
115
- "ru" => "Russian",
116
- "ru-mo" => "Russian /Moldavia",
117
- "gd" => "Scots Gaelic",
118
- "sr" => "Serbian",
119
- "sk" => "Slovack",
120
- "sl" => "Slovenian",
121
- "sb" => "Sorbian",
122
- "es" => "Spanish",
123
- "es-do" => "Spanish",
124
- "es-ar" => "Spanish/Argentina",
125
- "es-co" => "Spanish/Colombia",
126
- "es-mx" => "Spanish/Mexico",
127
- "es-es" => "Spanish/Spain",
128
- "es-gt" => "Spanish/Guatemala",
129
- "es-cr" => "Spanish/Costa Rica",
130
- "es-pa" => "Spanish/Panama",
131
- "es-ve" => "Spanish/Venezuela",
132
- "es-pe" => "Spanish/Peru",
133
- "es-ec" => "Spanish/Ecuador",
134
- "es-cl" => "Spanish/Chile",
135
- "es-uy" => "Spanish/Uruguay",
136
- "es-py" => "Spanish/Paraguay",
137
- "es-bo" => "Spanish/Bolivia",
138
- "es-sv" => "Spanish/El salvador",
139
- "es-hn" => "Spanish/Honduras",
140
- "es-ni" => "Spanish/Nicaragua",
141
- "es-pr" => "Spanish/Puerto Rico",
142
- "sx" => "Sutu",
143
- "sv" => "Swedish",
144
- "sv-se" => "Swedish/Sweden",
145
- "sv-fi" => "Swedish/Finland",
146
- "ts" => "Thai",
147
- "tn" => "Tswana",
148
- "tr" => "Turkish",
149
- "uk" => "Ukrainian",
150
- "ur" => "Urdu",
151
- "vi" => "Vietnamese",
152
- "xh" => "Xshosa",
153
- "ji" => "Yiddish",
154
- "zu" => "Zulu"
56
+ VERSIONS = {
57
+ :default => %r[(?:Version|MSIE|Firefox|Chrome|CriOS|QuickTime|BlackBerry[^/]+|CoreMedia v|PhantomJS)[/ ]?([a-z0-9.]+)]i,
58
+ :opera => %r[(?:Opera/.*? Version/([\d.]+)|Chrome/([\d.]+).*?OPR)]
155
59
  }
156
60
 
157
61
  # Create a new browser instance and set
@@ -163,8 +67,8 @@ class Browser
163
67
  # })
164
68
  #
165
69
  def initialize(options = {}, &block)
166
- @user_agent = (options[:user_agent] || options[:ua]).to_s
167
- @accept_language = options[:accept_language].to_s
70
+ self.user_agent = (options[:user_agent] || options[:ua]).to_s
71
+ self.accept_language = options[:accept_language].to_s
168
72
 
169
73
  yield self if block_given?
170
74
  end
@@ -174,30 +78,10 @@ class Browser
174
78
  NAMES[id]
175
79
  end
176
80
 
177
- # Return a symbol that identifies the browser.
81
+ # Get the browser identifier.
178
82
  def id
179
- case
180
- when chrome? then :chrome
181
- when iphone? then :iphone
182
- when ipad? then :ipad
183
- when ipod? then :ipod
184
- when ie? then :ie
185
- when opera? then :opera
186
- when firefox? then :firefox
187
- when android? then :android
188
- when blackberry? then :blackberry
189
- when safari? then :safari
190
- when psp? then :psp
191
- when quicktime? then :quicktime
192
- when core_media? then :core_media
193
- else
194
- :other
195
- end
196
- end
197
-
198
- # Return an array with all preferred languages that this browser accepts.
199
- def accept_language
200
- @accept_language.gsub(/;q=[\d.]+/, "").split(",").collect {|l| l.downcase.gsub(/\s/m, "")}
83
+ NAMES.keys
84
+ .find {|id| respond_to?("#{id}?") ? public_send("#{id}?") : id }
201
85
  end
202
86
 
203
87
  # Return major version.
@@ -207,17 +91,16 @@ class Browser
207
91
 
208
92
  # Return the full version.
209
93
  def full_version
210
- _, v = *ua.match(VERSIONS.fetch(id, VERSIONS[:default]))
211
- v || "0.0"
94
+ _, *v = *ua.match(VERSIONS.fetch(id, VERSIONS[:default]))
95
+ v.compact.first || "0.0"
212
96
  end
213
97
 
214
- # Return true if browser supports some CSS 3 (Safari, Firefox, Opera & IE7+).
215
- def capable?
216
- webkit? || firefox? || opera? || (ie? && version >= "7")
217
- end
218
-
219
- def compatibility_view?
220
- ie? && ua.match(TRIDENT_VERSION_REGEX) && version.to_i < ($1.to_i + 4)
98
+ # Return true if browser is modern (Webkit, Firefox 17+, IE9+, Opera 12+).
99
+ def modern?
100
+ webkit? ||
101
+ (firefox? && version.to_i >= 17) ||
102
+ (ie? && version.to_i >= 9) ||
103
+ (opera? && version.to_i >= 12)
221
104
  end
222
105
 
223
106
  # Detect if browser is WebKit-based.
@@ -225,54 +108,24 @@ class Browser
225
108
  !!(ua =~ /AppleWebKit/i)
226
109
  end
227
110
 
228
- # Detect if browser is ios?.
229
- def ios?
230
- ipod? || ipad? || iphone?
231
- end
232
-
233
- # Detect if browser is mobile.
234
- def mobile?
235
- !!(ua =~ /(Mobi(le)?|Symbian|MIDP|Windows CE)/) || blackberry? || psp? || opera_mini?
236
- end
237
-
238
111
  # Detect if browser is QuickTime
239
112
  def quicktime?
240
113
  !!(ua =~ /QuickTime/i)
241
114
  end
242
115
 
243
- # Detect if browser is BlackBerry
244
- def blackberry?
245
- !!(ua =~ /BlackBerry/)
246
- end
247
-
248
- # Detect if browser is Android.
249
- def android?
250
- !!(ua =~ /Android/ && !opera?)
251
- end
252
-
253
116
  # Detect if browser is Apple CoreMedia.
254
117
  def core_media?
255
118
  !!(ua =~ /CoreMedia/)
256
119
  end
257
120
 
258
- # Detect if browser is iPhone.
259
- def iphone?
260
- !!(ua =~ /iPhone/)
261
- end
262
-
263
- # Detect if browser is iPad.
264
- def ipad?
265
- !!(ua =~ /iPad/)
266
- end
267
-
268
- # Detect if browser is iPod.
269
- def ipod?
270
- !!(ua =~ /iPod/)
121
+ # Detect if browser is PhantomJS
122
+ def phantom_js?
123
+ !!(ua =~ /PhantomJS/)
271
124
  end
272
125
 
273
126
  # Detect if browser is Safari.
274
127
  def safari?
275
- ua =~ /Safari/ && ua !~ /Chrome|CriOS/
128
+ ua =~ /Safari/ && ua !~ /Chrome|CriOS|PhantomJS/
276
129
  end
277
130
 
278
131
  # Detect if browser is Firefox.
@@ -282,99 +135,20 @@ class Browser
282
135
 
283
136
  # Detect if browser is Chrome.
284
137
  def chrome?
285
- !!(ua =~ /Chrome|CriOS/)
286
- end
287
-
288
- # Detect if browser is Internet Explorer.
289
- def ie?
290
- !!(ua =~ /MSIE/ && ua !~ /Opera/)
291
- end
292
-
293
- # Detect if browser is Internet Explorer 6.
294
- def ie6?
295
- ie? && version == "6"
296
- end
297
-
298
- # Detect if browser is Internet Explorer 7.
299
- def ie7?
300
- ie? && version == "7"
301
- end
302
-
303
- # Detect if browser is Internet Explorer 8.
304
- def ie8?
305
- ie? && version == "8"
306
- end
307
-
308
- # Detect if browser is Internet Explorer 9.
309
- def ie9?
310
- ie? && version == "9"
311
- end
312
-
313
- # Detect if browser is running from PSP.
314
- def psp?
315
- !!(ua =~ /PSP/)
138
+ !!(ua =~ /Chrome|CriOS/) && !opera?
316
139
  end
317
140
 
318
141
  # Detect if browser is Opera.
319
142
  def opera?
320
- !!(ua =~ /Opera/)
321
- end
322
-
323
- # Detect if browser is Opera Mini.
324
- def opera_mini?
325
- !!(ua =~ /Opera Mini/)
326
- end
327
-
328
- # Detect if current platform is Macintosh.
329
- def mac?
330
- !!(ua =~ /Mac OS X/)
331
- end
332
-
333
- # Detect if current platform is Windows.
334
- def windows?
335
- !!(ua =~ /Windows/)
336
- end
337
-
338
- # Detect if current platform is Linux flavor.
339
- def linux?
340
- !!(ua =~ /Linux/)
341
- end
342
-
343
- # Detect if browser is tablet (currently just iPad or Android).
344
- def tablet?
345
- !!(ipad? || (android? && !mobile?))
346
- end
347
-
348
- # Detect if browser is Kindle.
349
- def kindle?
350
- !!(ua =~ /Kindle/)
351
- end
352
-
353
- # Return the platform.
354
- def platform
355
- case
356
- when linux? then :linux
357
- when mac? then :mac
358
- when windows? then :windows
359
- else
360
- :other
361
- end
143
+ !!(ua =~ /(Opera|OPR)/)
362
144
  end
363
145
 
364
146
  # Return a meta info about this browser.
365
147
  def meta
366
- set = Set.new.tap do |m|
367
- m << id.to_s
368
- m << "webkit" if webkit?
369
- m << "ios" if ios?
370
- m.merge(%W[safari safari#{version}]) if safari?
371
- m << "#{id}#{version}" unless safari? || chrome?
372
- m << platform.to_s
373
- m << "capable" if capable?
374
- m << "mobile" if mobile?
375
- end
376
-
377
- set.to_a
148
+ Meta.constants.each_with_object(Set.new) do |meta_name, meta|
149
+ meta_class = Meta.const_get(meta_name)
150
+ meta.merge(meta_class.new(self).to_a)
151
+ end.to_a
378
152
  end
379
153
 
380
154
  alias_method :to_a, :meta
@@ -1,17 +1,19 @@
1
+ require "action_controller/railtie"
2
+
1
3
  class Browser
2
- module ActionController # :nodoc: all
3
- def self.included(base)
4
- base.send :helper_method, :browser
4
+ module ActionController
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper_method :browser
5
9
  end
6
10
 
7
11
  private
8
12
  def browser
9
13
  @browser ||= Browser.new(
10
- :accept_language => request.headers["Accept-Language"],
11
- :ua => request.headers["User-Agent"]
14
+ accept_language: request.headers["Accept-Language"],
15
+ ua: request.headers["User-Agent"]
12
16
  )
13
17
  end
14
18
  end
15
19
  end
16
-
17
- ActionController::Base.send :include, Browser::ActionController