browser 0.1.6 → 0.2.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/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