brauser 2.1.4 → 3.0.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.
@@ -103,7 +103,7 @@
103
103
  </div>
104
104
 
105
105
  <div id="footer">
106
- Generated on Tue May 14 10:41:55 2013 by
106
+ Generated on Sun May 19 12:02:56 2013 by
107
107
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
108
108
  0.8.6.1 (ruby-1.9.3).
109
109
  </div>
data/lib/brauser.rb CHANGED
@@ -10,5 +10,6 @@ Lazier.load!(:object)
10
10
 
11
11
  require "brauser/version" if !defined?(Brauser::Version)
12
12
  require "brauser/query"
13
+ require "brauser/definition"
13
14
  require "brauser/browser"
14
15
  require "brauser/hooks"
@@ -14,50 +14,62 @@ module Brauser
14
14
 
15
15
  # Class methods.
16
16
  module ClassMethods
17
- # Registers the default list of browsers that can be recognized.
17
+ # Adds a definitions for recognition.
18
18
  #
19
- # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
20
- def register_default_browsers
21
- @browsers = nil
19
+ # @param type [Symbol] The type of the definition. Can be `:browsers`, `:platforms` or `:languages`.
20
+ # @param definition [Definition|Array] The definition to add. Can be also an array of definitions.
21
+ # @return [Boolean] `true` if at least one definition has been added, `false` otherwise.
22
+ def add(type, definition)
23
+ rv = false
24
+
25
+ if [:browsers, :platforms, :languages].include?(type) then
26
+ @definitions ||= {}
27
+ @definitions[type] ||= {}
28
+
29
+ definition.ensure_array.each do |d|
30
+ if d.is_a?(::Brauser::Definition) then
31
+ @definitions[type][d.tag] = d
32
+ rv = true
33
+ end
34
+ end
35
+ end
22
36
 
23
- register_mobile_browsers
24
- register_desktop_browsers
37
+ rv
38
+ end
25
39
 
26
- @browsers.present? ? true : false
40
+ # Adds definitions for a default list of browsers that can be recognized.
41
+ #
42
+ # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
43
+ def add_default_browsers
44
+ add_mobile_browsers && add_major_desktop_browsers && add_msie_browsers && add_minor_desktop_browsers
27
45
  end
28
46
 
29
- # Registers the default list of platforms that can be recognized.
47
+ # Adds a default list of platforms that can be recognized.
30
48
  #
31
49
  # @return [Boolean] `true` if at least one platform has been added, `false` otherwise.
32
- def register_default_platforms
33
- @platforms = nil
34
-
35
- self.register_platform([
36
- [:symbian, /s60|symb/i, "Symbian"],
37
- [:windows_phone, /windows phone/i, "Microsoft Windows Phone"],
38
- [:kindle, Proc.new { |name, _| name == :kindle }, "Nokia Symbian"],
39
- [:ios, Proc.new { |name, agent| [:iphone, :ipad, :ipod].include?(name) || agent =~ /ipad|iphone|ipod/i }, "Apple iOS"],
40
- [:android, /android/i, "Android"],
41
- [:blackberry, /blackberry/i, "RIM BlackBerry"],
42
- [:psp, /psp/i, "Sony Playstation Portable"],
43
- [:ps3, /playstation 3/i, "Sony Playstation 3"],
44
- [:wii, /wii/i, "Nintendo Wii"],
45
-
46
- [:linux, /linux/i, "Linux"],
47
- [:osx, /mac|macintosh|mac os x/i, "Apple MacOS X"],
48
- [:windows, /windows/i, "Microsoft Windows"]
49
- ])
50
-
51
- @platforms.present? ? true : false
50
+ def add_default_platforms
51
+ add(:platforms, [
52
+ [:symbian, "Symbian", /s60|symb/i],
53
+ [:windows_phone, "Microsoft Windows Phone", /windows phone/i],
54
+ [:kindle, "Nokia Symbian", /kindle|silk/i, ],
55
+ [:ios, "Apple iOS", Proc.new { |_, agent| [:iphone, :ipad, :ipod].include?(name) || agent =~ /ipad|iphone|ipod/i }],
56
+ [:android, "Android", /android/i],
57
+ [:blackberry, "RIM BlackBerry", /blackberry/i],
58
+ [:psp, "Sony Playstation Portable", /psp/i],
59
+ [:ps3, "Sony Playstation 3", /playstation 3/i],
60
+ [:wii, "Nintendo Wii", /wii/i],
61
+
62
+ [:linux, "Linux", /linux/i],
63
+ [:osx, "Apple MacOS X", /mac|macintosh|mac os x/i],
64
+ [:windows, "Microsoft Windows", /windows/i]
65
+ ].collect { |platform| ::Brauser::Definition.send(:new, *platform) })
52
66
  end
53
67
 
54
- # Registers the default list of languages that can be recognized.
68
+ # Adds a default list of languages that can be recognized.
55
69
  #
56
70
  # @return [Boolean] `true` if at least one language has been added, `false` otherwise.
57
- def register_default_languages
58
- @languages = nil
59
-
60
- self.register_language({
71
+ def add_default_languages
72
+ add(:languages, {
61
73
  "af" => "Afrikaans",
62
74
  "sq" => "Albanian",
63
75
  "eu" => "Basque",
@@ -171,136 +183,74 @@ module Brauser
171
183
  "xh" => "Xshosa",
172
184
  "ji" => "Yiddish",
173
185
  "zu" => "Zulu"
174
- })
175
-
176
- @languages.present? ? true : false
177
- end
178
-
179
- # Registers a new browser that can be recognized.
180
- #
181
- # @param name [Symbol|Array] The browser name or a list of browser (a list of array with `[name, name_match, version_match, label]` entries).
182
- # @param name_match [String|Regexp|Block] The matcher for the name. If a block, it will be yield with the user agent and must return `true` if the name was recognized.
183
- # @param version_match [String|Regexp|Block] The match for the version. If a block, it will be yield with the browser name and the user agent and must return the browser version.
184
- # @param label [String] A human readable name of the browser.
185
- # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
186
- def register_browser(name, name_match = nil, version_match = nil, label = nil)
187
- @browsers ||= []
188
- register_entries(@browsers, (name.is_a?(Array) ? name : [[name.ensure_string, name_match, version_match, label]]))
189
- end
190
-
191
- # Registers a new platform that can be recognized.
192
- #
193
- # @param name [Symbol|Array] The platform name or a list of platforms (a list of array with `[name, matcher, label]` entries).
194
- # @param matcher [StringRegexp|Block] The matcher for the platform. If a block, it will be yielded with the browser name and the user agent and must return `true` if the platform was recognized.
195
- # @param label [String] A human readable name of the platform.
196
- # @return [Boolean] `true` if at least one platform has been added, `false` otherwise.
197
- def register_platform(name, matcher = nil, label = nil)
198
- @platforms ||= []
199
- register_entries(@platforms, (name.is_a?(Array) ? name : [[name.ensure_string, matcher, label]]))
200
- end
201
-
202
- # Registers a new language that can be recognized.
203
- #
204
- # @param code [String|Hash] The language code or an hash with codes as keys and label as values.
205
- # @param label [String] The language name. Ignored if code is an Hash.
206
- # @return [Boolean] `true` if at least one language has been added, `false` otherwise.
207
- def register_language(code, label = nil)
208
- @languages ||= {}
209
- rv = false
210
- code = {code.ensure_string => label.ensure_string} if !code.is_a?(Hash)
211
-
212
- code.each_pair do |c, l|
213
- if c.present? && l.present? then
214
- @languages[c] = l
215
- rv = true
216
- end
217
- end
218
-
219
- rv
186
+ }.collect { |code, name| ::Brauser::Definition.new(code, name, code) })
220
187
  end
221
188
 
222
189
  private
223
- # Register the most common desktop browsers.
190
+ # Registers the most common desktop browsers.
191
+ #
224
192
  # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
225
- def register_desktop_browsers
226
- self.register_browser([
227
- [:chrome, /((chrome)|(chromium))/i, /(.+Chrom[a-z]+\/)([a-z0-9.]+)/i, "Google Chrome"],
228
- [:netscape, /(netscape|navigator)\//i, /((Netscape|Navigator)\/)([a-z0-9.]+)/i, "Netscape Navigator"],
229
- [:firefox, /firefox/i, /(.+Firefox\/)([a-z0-9.]+)/i, "Mozilla Firefox"],
230
- [:safari, Proc.new{ |agent| agent =~ /safari/i && agent !~ /((chrome)|(chromium))/i }, /(.+Version\/)([a-z0-9.]+)/i, "Apple Safari"],
231
-
232
- [:msie_compatibility, /(msie 7\.0).+(trident)/i, Proc.new { |_, agent|
233
- version = /(.+Trident\/)([a-z0-9.]+)/i.match(agent)
234
-
235
- if version.is_a?(::MatchData) then
236
- v = version.to_a.last.split(".")
237
- v[0] = v[0].to_integer + 4
238
- version = v.join(".")
239
- end
240
-
241
- version
242
- }, "Microsoft Internet Explorer (Compatibility View)"],
243
- [:msie, Proc.new{ |agent| agent =~ /msie/i && agent !~ /opera/i }, /(.+MSIE )([a-z0-9.]+)/i, "Microsoft Internet Explorer"],
244
-
245
- [:quicktime, /quicktime/i, /(.+((QuickTime\/)|(qtver=)))([a-z0-9.]+)/i, "Apple QuickTime"],
246
-
247
- [:webkit, /webkit/i, /(.+WebKit\/)([a-z0-9.]+)/i, "WebKit Browser"],
248
- [:gecko, /gecko/i, /(.+rv:|Gecko\/)([a-z0-9.]+)/i, "Gecko Browser"],
249
- ])
193
+ def add_major_desktop_browsers
194
+ add(:browsers, [
195
+ [:chrome, "Google Chrome", /((chrome)|(chromium))/i, /(.+Chrom[a-z]+\/)([a-z0-9.]+)/i],
196
+ [:netscape, "Netscape Navigator", /(netscape|navigator)\//i, /((Netscape|Navigator)\/)([a-z0-9.]+)/i],
197
+ [:firefox, "Mozilla Firefox", /firefox/i, /(.+Firefox\/)([a-z0-9.]+)/i],
198
+ [:safari, "Apple Safari", Proc.new{ |_, agent| agent =~ /safari/i && agent !~ /((chrome)|(chromium))/i }, /(.+Version\/)([a-z0-9.]+)/i],
199
+ ].collect { |browser| ::Brauser::Definition.send(:new, *browser) })
250
200
  end
251
201
 
252
- # Register the most common mobile and console browsers.
202
+ # Registers definitions for MSIE browsers.
203
+ #
253
204
  # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
254
- def register_mobile_browsers
255
- self.register_browser([
256
- [:coremedia, /coremedia/i, /.+CoreMedia v([a-z0-9.]+)/i, "Apple CoreMedia"],
257
-
258
- [:opera_mobile, /opera mobi/i, /.+Opera Mobi.+((.+Opera )|(Version\/))([a-z0-9.]+)/i, "Opera Mobile"],
259
- [:opera, /opera/i, Proc.new{ |_, agent|
260
- regexp = (agent !~ /wii/i) ? /((.+Opera )|(Version\/))([a-z0-9.]+)/i : /(.+Nintendo Wii; U; ; )([a-z0-9.]+)/i
261
-
262
- version = regexp.match(agent)
263
- version = version.to_a.last if version.is_a?(MatchData)
264
- version
265
- }, "Opera"],
266
-
267
- [:android, /android/i, /(.+Android )([a-z0-9.]+)/i, "Android"],
268
- [:blackberry, /blackberry/i, /(.+Version\/)([a-z0-9.]+)/i, "RIM BlackBerry"],
269
- [:kindle, /(kindle)/i, /(.+(Kindle|Silk)\/)([a-z0-9.]+)/i, "Amazon Kindle"],
270
- [:psp, /psp/i, /(.+PlayStation Portable\); )([a-z0-9.]+)/i, "Sony Playstation Portable"],
271
- [:ps3, /playstation 3/i, /(.+PLAYSTATION 3; )([a-z0-9.]+)/i, "Sony Playstation 3"],
272
- [:windows_phone, /windows phone/i, /(.+IEMobile\/)([a-z0-9.]+)/i, "Microsoft Windows Phone"],
273
- [:wii, /nintendo wii/, /(.+Nintendo Wii; U; ; )([a-z0-9.]+)/i, "Nintendo Wii"],
274
-
275
- [:ipod, /ipod/i, /(.+Version\/)([a-z0-9.]+)/i, "Apple iPod"],
276
- [:iphone, /iphone/i, /(.+Version\/)([a-z0-9.]+)/i, "Apple iPhone"],
277
- [:ipad, /ipad/i, /(.+Version\/)([a-z0-9.]+)/i, "Apple iPad"],
278
-
279
- [:mobile, /(mobile|symbian|midp|windows ce)/i, /.+\/([a-z0-9.]+)/i, "Other Mobile Browser"],
280
- ])
205
+ def add_msie_browsers
206
+ add(:browsers, [
207
+ [:msie_compatibility, "Microsoft Internet Explorer (Compatibility View)", /(msie 7\.0).+(trident)/i, Proc.new { |_, agent|
208
+ version = /(.+trident\/)(?<version>[a-z0-9.]+)/i.match(agent)["version"].split(".")
209
+ version[0] = version[0].to_integer + 4
210
+ version.join(".")
211
+ }],
212
+ [:msie, "Microsoft Internet Explorer", Proc.new{ |_, agent| agent =~ /msie/i && agent !~ /opera/i }, /(.+MSIE )([a-z0-9.]+)/i],
213
+ ].collect { |browser| ::Brauser::Definition.send(:new, *browser) })
281
214
  end
282
215
 
283
- # Registers a new set of entries to a collection.
216
+ # Registers the least common desktop browsers.
284
217
  #
285
- # @param collection [Array] The collection which add entries to.
286
- # @param entries [Array] The entries to add.
287
- def register_entries(collection, entries)
288
- rv = false
289
-
290
- entries.each do |entry|
291
- entry[0] = entry[0].to_sym
292
- index = collection.find_index { |item| item[0] == entry[0] }
293
-
294
- # Replace a previous entry
295
- if index then
296
- collection[index] = entry
297
- else
298
- collection << entry
299
- rv = true
300
- end
301
- end
218
+ # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
219
+ def add_minor_desktop_browsers
220
+ add(:browsers, [
221
+ [:quicktime, "Apple QuickTime", /quicktime/i, /(.+((QuickTime\/)|(qtver=)))([a-z0-9.]+)/i],
222
+ [:webkit, "WebKit Browser", /webkit/i, /(.+WebKit\/)([a-z0-9.]+)/i],
223
+ [:gecko, "Gecko Browser", /gecko/i, /(.+rv:|Gecko\/)([a-z0-9.]+)/i],
224
+ ].collect { |browser| ::Brauser::Definition.send(:new, *browser) })
225
+ end
302
226
 
303
- rv
227
+ # Register the most common mobile and console browsers.
228
+ #
229
+ # @return [Boolean] `true` if at least one browser has been added, `false` otherwise.
230
+ def add_mobile_browsers
231
+ add(:browsers, [
232
+ [:coremedia, "Apple CoreMedia", /coremedia/i, /.+CoreMedia v([a-z0-9.]+)/i],
233
+
234
+ [:opera_mobile, "Opera Mobile", /opera mobi/i, /.+Opera Mobi.+((.+Opera )|(Version\/))([a-z0-9.]+)/i],
235
+ [:opera, "Opera", /opera/i, Proc.new{ |_, agent|
236
+ version = ((agent !~ /wii/i) ? /((.+Opera )|(Version\/))(?<version>[a-z0-9.]+)/i : /(.+Nintendo Wii; U; ; )(?<version>[a-z0-9.]+)/i).match(agent)
237
+ version ? version["version"] : nil
238
+ }],
239
+
240
+ [:android, "Android", /android/i, /(.+Android )([a-z0-9.]+)/i],
241
+ [:blackberry, "RIM BlackBerry", /blackberry/i, /(.+Version\/)([a-z0-9.]+)/i],
242
+ [:kindle, "Amazon Kindle", /(kindle)/i, /(.+(Kindle|Silk)\/)([a-z0-9.]+)/i],
243
+ [:psp, "Sony Playstation Portable", /psp/i, /(.+PlayStation Portable\); )([a-z0-9.]+)/i],
244
+ [:ps3, "Sony Playstation 3", /playstation 3/i, /(.+PLAYSTATION 3; )([a-z0-9.]+)/i],
245
+ [:windows_phone, "Microsoft Windows Phone", /windows phone/i, /(.+IEMobile\/)([a-z0-9.]+)/i],
246
+ [:wii, "Nintendo Wii", /nintendo wii/, /(.+Nintendo Wii; U; ; )([a-z0-9.]+)/i],
247
+
248
+ [:ipod, "Apple iPod", /ipod/i, /(.+Version\/)([a-z0-9.]+)/i],
249
+ [:iphone, "Apple iPhone", /iphone/i, /(.+Version\/)([a-z0-9.]+)/i],
250
+ [:ipad, "Apple iPad", /ipad/i, /(.+Version\/)([a-z0-9.]+)/i],
251
+
252
+ [:mobile, "Other Mobile Browser", /(mobile|symbian|midp|windows ce)/i, /.+\/([a-z0-9.]+)/i],
253
+ ].collect { |browser| ::Brauser::Definition.send(:new, *browser) })
304
254
  end
305
255
  end
306
256
  end
@@ -317,7 +267,7 @@ module Brauser
317
267
  #
318
268
  # @return [Hash] The list of browser that can be recognized.
319
269
  def browsers
320
- registered_to_hash(@browsers)
270
+ @definitions[:browsers]
321
271
  end
322
272
 
323
273
  # Returns the list of platforms that can be recognized.
@@ -326,7 +276,7 @@ module Brauser
326
276
  #
327
277
  # @return [Hash] The list of platform that can be recognized.
328
278
  def platforms
329
- registered_to_hash(@platforms)
279
+ @definitions[:platforms]
330
280
  end
331
281
 
332
282
  # Returns the list of languages that can be recognized.
@@ -335,7 +285,7 @@ module Brauser
335
285
  #
336
286
  # @return [Hash] The list of languages that can be recognized.
337
287
  def languages
338
- @languages
288
+ @definitions[:languages]
339
289
  end
340
290
 
341
291
  # Compares two versions.
@@ -348,7 +298,7 @@ module Brauser
348
298
  valid_results = {lt: [-1], lte: [-1, 0], eq: [0], gte: [0, 1], gt: [1]}.fetch(operator, [])
349
299
 
350
300
  if valid_results.present? && v1.ensure_string.present? then
351
- p1, p2 = find_relevant_tokens(v1.ensure_string.strip, v2.ensure_string.strip)
301
+ p1, p2 = find_relevant_tokens(v1, v2)
352
302
  p1, p2 = normalize_tokens(p1, p2)
353
303
  valid_results.include?(p1 <=> p2)
354
304
  else
@@ -363,8 +313,8 @@ module Brauser
363
313
  # @param v2 [String] The second version to compare.
364
314
  # @return [Array] The tokens to compare.
365
315
  def find_relevant_tokens(v1, v2)
366
- v1 = v1.split(".")
367
- v2 = v2.split(".")
316
+ v1 = v1.ensure_string.strip.split(".")
317
+ v2 = v2.ensure_string.strip.split(".")
368
318
 
369
319
  p1 = nil
370
320
  p2 = nil
@@ -387,21 +337,14 @@ module Brauser
387
337
  ll = p1.length
388
338
  p1 = p2 + p1
389
339
  p2 = p2 + ("z" * ll)
340
+ else
341
+ ll = [p1.length, p2.length].max
342
+ p1 = p1.rjust(ll, "0")
343
+ p2 = p2.rjust(ll, "0")
390
344
  end
391
345
 
392
346
  [p1, p2]
393
347
  end
394
-
395
- # Converts a list of register entries to an ordered hash.
396
- #
397
- # @param entries [Array] The array to convert.
398
- # @return [OrderedHash] An ordered hash.
399
- def registered_to_hash(entries)
400
- entries.inject(ActiveSupport::OrderedHash.new) do |rv, entry|
401
- rv[entry[0]] = entry[1, entry.length]
402
- rv
403
- end
404
- end
405
348
  end
406
349
  end
407
350
 
@@ -411,16 +354,16 @@ module Brauser
411
354
  #
412
355
  # @return [String] A human-readable browser name.
413
356
  def readable_name
414
- self.parse_agent(@agent) if !@name
415
- ::Brauser::Browser.browsers.fetch(@name, ["Unknown Browser"]).last.ensure_string
357
+ parse_agent(@agent) if !@name
358
+ ::Brauser::Browser.browsers[@name].try(:label) || "Unknown Browser"
416
359
  end
417
360
 
418
361
  # Gets a human-readable platform name.
419
362
  #
420
363
  # @return [String] A readable platform name.
421
364
  def platform_name
422
- self.parse_agent(@agent) if !@platform
423
- ::Brauser::Browser.platforms.fetch(@platform, ["Unknown Platform"]).last.ensure_string
365
+ parse_agent(@agent) if !@platform
366
+ ::Brauser::Browser.platforms[@platform].try(:label) || "Unknown Platform"
424
367
  end
425
368
 
426
369
  # Returns an array of information about the browser. Information are strings which are suitable to use as CSS classes.
@@ -451,29 +394,31 @@ module Brauser
451
394
  #
452
395
  # @param name [Boolean] If non falsy, the string to prepend to the name. If falsy, the name information will not be included.
453
396
  # @param block [Proc] A block to translate browser name.
454
- # @return [String|Array|nil] The browser name(s) or `nil`, if it was set to be skipped
397
+ # @return [String|Array|nil] The browser name(s) or `nil`, if it was set to be skipped.
455
398
  def stringify_name(name, &block)
456
- if !name then
457
- nil
458
- else
399
+ if name then
459
400
  name = "" if name.is_a?(TrueClass)
460
401
  self.parse_agent(@agent) if !@name
461
402
  block ||= Proc.new {|n, *| n == :msie_compatibility ? [:msie_compatibility, :msie] : n }
462
403
 
463
404
  names = block.call(@name, @version, @platform).ensure_array.collect {|n| "#{name}#{n}" }
464
405
  names.length > 1 ? names : names.first
406
+ else
407
+ nil
465
408
  end
466
409
  end
467
410
 
468
411
  # Stringifies a browser version.
469
412
  #
470
413
  # @param version [String|NilClass] If non falsy, the string to prepend to the version. If falsy, the version information will not be included.
471
- # @return [Array] The version strings or `nil`, if it was set to be skipped
414
+ # @return [Array] The version strings or `nil`, if it was set to be skipped.
472
415
  def stringify_version(version)
473
416
  version = "version-" if version.is_a?(TrueClass)
474
- others = @version.split(".")
475
- major = others.shift
476
- !version ? nil : others.inject([version + major]) {|prev, current| prev + [prev.last + "_" + current] }.flatten
417
+ tokens = @version.split(".")
418
+
419
+ !version ? nil : tokens.inject([version + tokens.shift]) {|prev, current|
420
+ prev + [prev.last + "_" + current]
421
+ }.flatten
477
422
  end
478
423
  end
479
424
 
@@ -507,12 +452,12 @@ module Brauser
507
452
  # @return [String|Symbol] The browser name or `:unknown`, if no match was found.
508
453
  def match_name_and_version(agent)
509
454
  catch(:name) do
510
- ::Brauser::Browser.browsers.each do |name, definitions|
511
- matched = match_definition(definitions[0], agent)
455
+ ::Brauser::Browser.browsers.each do |tag, definition|
456
+ matched = definition.match(:primary, definition, agent)
512
457
 
513
458
  if matched then
514
- @version = match_definition(definitions[1], name, agent)
515
- throw(:name, name)
459
+ @version = definition.match(:secondary, definition, agent)
460
+ throw(:name, tag)
516
461
  end
517
462
  end
518
463
 
@@ -521,6 +466,9 @@ module Brauser
521
466
  end
522
467
 
523
468
  # Adjusts a browser version.
469
+ #
470
+ # @param version [String] The version to adjust.
471
+ # @return [String] The adjusted version.
524
472
  def adjust_version(version)
525
473
  # Adjust version
526
474
  if version.blank? then
@@ -538,28 +486,13 @@ module Brauser
538
486
  # @return [String|Symbol] The browser platform or `:unknown`, if no match was found.
539
487
  def match_platform(agent)
540
488
  catch(:platform) do
541
- ::Brauser::Browser.platforms.each do |platform, definitions|
542
- matched = match_definition(definitions[0], @name, agent)
543
- throw(:platform, platform) if matched
489
+ ::Brauser::Browser.platforms.each do |tag, definition|
490
+ throw(:platform, tag) if definition.match(:primary, definition, agent)
544
491
  end
545
492
 
546
493
  :unknown
547
494
  end
548
495
  end
549
-
550
- # Matches a subject against a definition
551
- #
552
- # @param subject [Array] The subject to match.
553
- # @param definition [StringRegexp|Block] The definition. If a block, it will be yielded with the subject must return `true` if the subject was recognized.
554
- def match_definition(definition, *subject)
555
- if definition.is_a?(::Regexp) then
556
- definition.match(subject.last)
557
- elsif definition.respond_to?(:call) then
558
- definition.call(*subject)
559
- else
560
- subject.last == definition.ensure_string ? subject.last : nil
561
- end
562
- end
563
496
  end
564
497
 
565
498
  # Methods to query with chaining.
@@ -574,7 +507,7 @@ module Brauser
574
507
  # @param platforms [Symbol|Array] A list of specific platform to match. Valid values are all those possible for the platform attribute.
575
508
  # @return [Query] A query which can evaluated for concatenation or result.
576
509
  def is(names = [], versions = {}, platforms = [])
577
- self.parse_agent(@agent) if !@name
510
+ parse_agent(@agent) if !@name
578
511
 
579
512
  names = adjust_names(names)
580
513
  versions = parse_versions_query(versions)
@@ -582,8 +515,8 @@ module Brauser
582
515
 
583
516
  ::Brauser::Query.new(self,
584
517
  (names.blank? || (names.include?(@name) && check_capable(names))) &&
585
- (versions.blank? || self.v?(versions)) &&
586
- (platforms.blank? || self.on?(platforms))
518
+ (versions.blank? || v?(versions)) &&
519
+ (platforms.blank? || on?(platforms))
587
520
  )
588
521
  end
589
522
 
@@ -592,15 +525,8 @@ module Brauser
592
525
  # @param versions [String|Hash] A string in the form `operator version && ...` (example: `>= 7 && < 4`) or an hash with specific version to match against, in form `{:operator => version}`, where operator is one of `:lt, :lte, :eq, :gt, :gte`.
593
526
  # @return [Query] A query which can evaluated for concatenation or result.
594
527
  def v(versions = {})
595
- self.parse_agent(@agent) if !@version
596
-
597
- versions = if versions.is_a?(String) then
598
- parse_versions_query(versions)
599
- elsif !versions.is_a?(::Hash) then
600
- {}
601
- else
602
- versions
603
- end
528
+ parse_agent(@agent) if !@version
529
+ versions = versions.is_a?(String) ? parse_versions_query(versions) : versions.ensure_hash
604
530
 
605
531
  ::Brauser::Query.new(self, versions.all? { |operator, value| Brauser::Browser.compare_versions(@version, operator, value) })
606
532
  end
@@ -610,8 +536,9 @@ module Brauser
610
536
  # @param platforms [Symbol|Array] A list of specific platform to match.
611
537
  # @return [Query] A query which can evaluated for concatenation or result.
612
538
  def on(platforms = [])
613
- self.parse_agent(@agent) if !@platform
614
- ::Brauser::Query.new(self, platforms.blank? || platforms.ensure_array.uniq.compact.collect {|p| p.ensure_string.to_sym }.include?(@platform))
539
+ parse_agent(@agent) if !@platform
540
+
541
+ ::Brauser::Query.new(self, platforms.blank? || platforms.ensure_array(nil, true, true, :to_sym).include?(@platform))
615
542
  end
616
543
 
617
544
  # Check if the browser accepts the specified languages.
@@ -619,8 +546,9 @@ module Brauser
619
546
  # @param langs [String|Array] A list of languages to match against.
620
547
  # @return [Query] A query which can evaluated for concatenation or result.
621
548
  def accepts(langs = [])
622
- self.parse_accept_language(@accept_language) if !@languages
623
- ::Brauser::Query.new(self, (@languages & langs.ensure_array.uniq.compact.collect {|l| l.to_s }).present?)
549
+ parse_accept_language(@accept_language) if !@languages
550
+
551
+ ::Brauser::Query.new(self, (@languages & langs.ensure_array(nil, true, true, :to_s)).present?)
624
552
  end
625
553
 
626
554
  private
@@ -630,7 +558,7 @@ module Brauser
630
558
  # @return [Array] The adjusted list of names.
631
559
  def adjust_names(names)
632
560
  # Adjust names
633
- names = names.ensure_array.compact.collect {|n| n.ensure_string.to_sym }
561
+ names = names.ensure_array(nil, true, true, :to_sym)
634
562
  names << [:msie, :msie_compatibility] if names.include?(:ie) || names.include?(:msie)
635
563
  names << [:chromium] if names.include?(:chrome)
636
564
  names << [:chrome, :firefox, :safari, :opera, :msie] if names.include?(:capable)
@@ -680,7 +608,7 @@ module Brauser
680
608
  # @param platforms [Symbol|Array] A list of specific platform to match. Valid values are all those possible for the platform attribute.
681
609
  # @return [Boolean] `true` if current browser matches, `false` otherwise.
682
610
  def is?(names = [], versions = {}, platforms = [])
683
- self.is(names, versions, platforms).result
611
+ is(names, versions, platforms).result
684
612
  end
685
613
 
686
614
  # Checks if the browser is a specific version.
@@ -688,7 +616,7 @@ module Brauser
688
616
  # @param versions [String|Hash] A string in the form `operator version && ...` (example: `>= 7 && < 4`) or an hash with specific version to match against, in form `{:operator => version}`, where operator is one of `:lt, :lte, :eq, :gt, :gte`.
689
617
  # @return [Boolean] `true` if current browser matches, `false` otherwise.
690
618
  def v?(versions = {})
691
- self.v(versions).result
619
+ v(versions).result
692
620
  end
693
621
 
694
622
  # Check if the browser is on a specific platform.
@@ -696,7 +624,7 @@ module Brauser
696
624
  # @param platforms [Symbol|Array] A list of specific platform to match.
697
625
  # @return [Boolean] `true` if current browser matches, `false` otherwise.
698
626
  def on?(platforms = [])
699
- self.on(platforms).result
627
+ on(platforms).result
700
628
  end
701
629
 
702
630
  # Check if the browser accepts the specified languages.
@@ -704,7 +632,7 @@ module Brauser
704
632
  # @param langs [String|Array] A list of languages to match against.
705
633
  # @return [Boolean] `true` if current browser matches, `false` otherwise.
706
634
  def accepts?(langs = [])
707
- self.accepts(langs).result
635
+ accepts(langs).result
708
636
  end
709
637
  end
710
638
  end
@@ -747,15 +675,15 @@ module Brauser
747
675
  # @param agent [String] The User-Agent HTTP header.
748
676
  # @param accept_language [String] The Accept-Language HTTP header.
749
677
  def initialize(agent = "", accept_language = "")
750
- ::Brauser::Browser.register_default_browsers
751
- ::Brauser::Browser.register_default_platforms
752
- ::Brauser::Browser.register_default_languages
678
+ ::Brauser::Browser.add_default_browsers
679
+ ::Brauser::Browser.add_default_platforms
680
+ ::Brauser::Browser.add_default_languages
753
681
 
754
682
  @agent = agent
755
683
  @accept_language = accept_language
756
684
 
757
- @languages = self.parse_accept_language(@accept_language) if @accept_language
758
- self.parse_agent(@agent) if @agent
685
+ @languages = parse_accept_language(@accept_language) if @accept_language
686
+ parse_agent(@agent) if @agent
759
687
  end
760
688
 
761
689
  # This method enables the use of dynamic queries in just one method.
@@ -763,7 +691,7 @@ module Brauser
763
691
  # For example:
764
692
  #
765
693
  # ```ruby
766
- # browser.is_msie_gt_4_1__on_windows?
694
+ # browser.is_msie_gt_4_1_on_windows?
767
695
  # #=> true
768
696
  # ```
769
697
  #
@@ -771,15 +699,15 @@ module Brauser
771
699
  #
772
700
  # If the syntax is invalid, a `NoMethodError` exception will be raised.
773
701
  #
774
- # @param query [String] The query to issue. Use `__` to separate query and `_` in place of `.` in the version.
702
+ # @param query [String] The query to issue. Use `_` in place of `.` in the version.
775
703
  # @param arguments [Array] The arguments to pass the method. Unused from the query.
776
704
  # @param block [Proc] A block to pass to the method. Unused from the query.
777
705
  # @return [Boolean|Query|nil] A query or a boolean value (if `method` ends with `?`). If the query is not valid, `NoMethodError` will be raised.
778
706
  def method_missing(query, *arguments, &block)
779
707
  begin
780
- parsed_query = parse_query(query.ensure_string)
781
- rv = execute_query(parsed_query) || Brauser::Query.new(self, false)
782
- query.ensure_string =~ /\?$/ ? rv.result : rv
708
+ query_s = query.ensure_string
709
+ rv = execute_query(parse_query(query_s)) || Brauser::Query.new(self, false)
710
+ query_s =~ /\?$/ ? rv.result : rv
783
711
  rescue NoMethodError
784
712
  super(query, *arguments, &block)
785
713
  end
@@ -796,10 +724,11 @@ module Brauser
796
724
 
797
725
  private
798
726
  # Parse query, getting all arguments.
727
+ #
799
728
  # @param query [String] The query to issue. Use `__` to separate query and `_` in place of `.` in the version.
800
729
  # @return [Array] And array of `[method, arguments]` entries.
801
730
  def parse_query(query)
802
- query.gsub(/\?$/, "").split("__").collect do |part|
731
+ query.gsub(/\?$/, "").gsub(/(_(v|on|is))/, " \\2").split(" ").collect do |part|
803
732
  parse_query_part(part)
804
733
  end
805
734
  end