Class: Brauser::Browser

Inherits:
Object
  • Object
show all
Defined in:
lib/brauser/browser.rb

Overview

This class represents a detection of the current user browser.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(agent = "", accept_language = "") ⇒ Browser

Creates a new browser.

Parameters:

  • agent (String) (defaults to: "")

    The User-Agent HTTP header.

  • accept_language (String) (defaults to: "")

    The Accept-Language HTTP header.



448
449
450
451
452
453
454
455
456
457
458
# File 'lib/brauser/browser.rb', line 448

def initialize(agent = "", accept_language = "")
  self.class.register_default_browsers
  self.class.register_default_platforms
  self.class.register_default_languages

  @agent = agent
  @accept_language = accept_language

  @languages = self.parse_accept_language(@accept_language) if @accept_language
  self.parse_agent(@agent) if @agent
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(query, *arguments, &block) ⇒ Boolean|Query|nil

This method enables the use of dynamic queries in just one method.

For example:

browser.is_msie_gt_4_1__on_windows?
#=> true

If you don't provide a trailing ?, you will get a Brauser::Query.

If the syntax is invalid, a NoMethodError exception will be raised.

Parameters:

  • query (String)

    The query to issue. Use __ to separate query and _ in place of . in the version.

  • arguments (Array)

    The arguments to pass the method. Unused from the query.

  • block (Proc)

    A block to pass to the method. Unused from the query.

Returns:

  • (Boolean|Query|nil)

    A query or a boolean value (if method ends with ?). If the query is not valid, NoMethodError will be raised.



695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
# File 'lib/brauser/browser.rb', line 695

def method_missing(query, *arguments, &block)
  rv = nil
  oq = query
  oa = arguments

  query = query.ensure_string

  # See if return a boolean in case of valid query
  as_result = query =~ /\?$/
  query = query.gsub(/\?$/, "")

  # Parse the query
  query.ensure_string.split("__").each do |parts|
    tokens = parts.split("_")
    method = tokens[0]
    arguments = tokens[1, tokens.length].join("_")

    if method == "v" then
      arguments.gsub("_", ".")
    end

    if ["is", "v", "on"].include?(method) then
      if method == "v" then
        arguments = arguments.gsub(/_?eq_?/, " == ") # Parse ==
        arguments = arguments.gsub(/_?lte_?/, " <= ").gsub(/_?gte_?/, " >= ") # Parse <= and >=
        arguments = arguments.gsub(/_?lt_?/, " < ").gsub(/_?gt_?/, " > ") # Parse < and >
        arguments = arguments.gsub(/_?and_?/, " && ") # Parse &&
        arguments = arguments.gsub("_", ".").gsub(/\s+/, " ").strip # Replace _ and spaces, then strip
      end

      rv = Brauser::Query.new(self, true) if !rv
      rv = rv.send(method, *arguments)

      break if rv.result == false
    else # Invalid finder
      rv = nil
      break
    end
  end

  rv = rv.result if !rv.nil? && as_result
  !rv.nil? ? rv : super(oq, *oa, &block)
end

Instance Attribute Details

#accept_languageObject

The raw Accept-Language HTTP header.



15
16
17
# File 'lib/brauser/browser.rb', line 15

def accept_language
  @accept_language
end

#agentObject Also known as: ua

The raw User-Agent HTTP header.



12
13
14
# File 'lib/brauser/browser.rb', line 12

def agent
  @agent
end

#languagesObject

The accepted languages.



18
19
20
# File 'lib/brauser/browser.rb', line 18

def languages
  @languages
end

#nameObject

The current browser name.



21
22
23
# File 'lib/brauser/browser.rb', line 21

def name
  @name
end

#platformObject

The current browser platform.



27
28
29
# File 'lib/brauser/browser.rb', line 27

def platform
  @platform
end

#versionObject

The current browser version.



24
25
26
# File 'lib/brauser/browser.rb', line 24

def version
  @version
end

Class Method Details

.browsersHash

Returns the list of browser that can be recognized.

The keys are the browser name, the values are arrays of the name matcher, the version match and the label.

Returns:

  • (Hash)

    The list of browser that can be recognized.



38
39
40
41
42
43
44
45
46
# File 'lib/brauser/browser.rb', line 38

def self.browsers
  rv = ActiveSupport::OrderedHash.new

  @browsers.each do |browser|
    rv[browser[0]] = browser[1, browser.length]
  end

  rv
end

.compare_versions(v1 = "", operator = :eq, v2 = "") ⇒ Boolean

Compares two versions.

Parameters:

  • v1 (String) (defaults to: "")

    The first versions to compare.

  • operator (Symbol) (defaults to: :eq)

    The operator to use for comparison, can be one of [:lt, :lte, :eq, :gte, :gt].

  • v2 (Symbol) (defaults to: "")

    The second version to compare.

Returns:

  • (Boolean)

    true if comparison is valid, false otherwise.



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/brauser/browser.rb', line 382

def self.compare_versions(v1 = "", operator = :eq, v2 = "")
  rv = true

  if [:lt, :lte, :eq, :gte, :gt].include?(operator) && v1.ensure_string.present? then
    # At first, split versions
    vv1 = v1.ensure_string.split(".").reverse
    vv2 = v2.ensure_string.split(".").reverse

    left = vv1.pop
    right = vv2.pop

    # Start comparison, picking from length
    rv = catch(:result) do
      while true do
        left = (left || "0").ensure_string
        right = (right || "0").ensure_string

        # Adjust for alpha, beta, etc
        if !left.is_integer? then
          ll = left.length
          left = right + left
          right = right + ("z" * ll)
        end

        # Pad arguments to make correct string comparisons
        len = [left.length, right.length].max
        left = left.rjust(len, "0")
        right = right.rjust(len, "0")

        if left == right then # If we have still an equal version
          # Goto next tokens
          left = vv1.pop
          right = vv2.pop

          # We end the left version, so until now all tokens were equal. Check what to do.
          if left.blank? then
            case operator
              when :lt then throw(:result, right.present? && right.to_integer > 0) # The comparison is true if there is at least another right version number greater than 0.
              when :lte then throw(:result, right.blank? || right.is_integer?) # The comparison is true if there is no other right version or that is a integer (so it means no alpha, beta etc).
              when :eq then throw(:result, right.blank? || ([right] + vv2).uniq.first == "0") # The comparison is true if also right version ends or only zero are left.
              when :gte then throw(:result, right.blank? || !right.is_integer?) # The comparison is true if there is no other right version or that is not a integer (so it means alpha, beta etc).
              when :gt then throw(:result, right.present? && !right.is_integer?) # The comparison is true if there is at least another right version not a integer (so it means alpha, beta etc).
            end
          end

            throw(:result, [:lte, :eq, :gte].include?(operator)) if left.blank? # If we end the left version, it means that all tokens were equal. Return accordingly
        else # We can compare a different token
          case operator
            when :lt, :lte then throw(:result, left < right)
            when :eq then throw(:result, false)
            when :gt, :gte then throw(:result, left > right)
          end
        end
      end
    end
  else
    rv = false
  end

  rv
end

.languagesHash

Returns the list of languages that can be recognized.

The keys are the languages code, the values the labels.

Returns:

  • (Hash)

    The list of languages that can be recognized.



68
69
70
# File 'lib/brauser/browser.rb', line 68

def self.languages
  @languages
end

.platformsHash

Returns the list of platforms that can be recognized.

The keys are the platform name, values are arrays of the matcher and the label.

Returns:

  • (Hash)

    The list of platform that can be recognized.



53
54
55
56
57
58
59
60
61
# File 'lib/brauser/browser.rb', line 53

def self.platforms
  rv = ActiveSupport::OrderedHash.new

  @platforms.each do |platform|
    rv[platform[0]] = platform[1, platform.length]
  end

  rv
end

.register_browser(name, name_match = nil, version_match = nil, label = nil) ⇒ Boolean

Registers a new browser that can be recognized.

Parameters:

  • name (Symbol|Array)

    The browser name or a list of browser (a list of array with [name, name_match, version_match, label] entries).

  • name_match (String|Regexp|Block) (defaults to: nil)

    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.

  • version_match (String|Regexp|Block) (defaults to: nil)

    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.

  • label (String) (defaults to: nil)

    A human readable name of the browser.

Returns:

  • (Boolean)

    true if at least one browser has been added, false otherwise.



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/brauser/browser.rb', line 289

def self.register_browser(name, name_match = nil, version_match = nil, label = nil)
  if !@browsers then
    @browsers = []
    @browsers_indexes = {}
  end

  rv = false
  name = [[name.ensure_string.to_sym, name_match, version_match, label]] if !name.is_a?(Array)

  name.each do |browser|
    browser[0] = browser[0].to_sym

    index = @browsers.index do |item|
      item[0] == browser[0]
    end

    # Replace a previous entry
    if index then
      @browsers[index] = browser
    else
      @browsers << browser
      @browsers_indexes[browser[0]] = @browsers.length - 1
    end

    rv = true
  end

  rv
end

.register_default_browsersBoolean

Registers the default list of browsers that can be recognized.

Returns:

  • (Boolean)

    true if at least one browser has been added, false otherwise.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/brauser/browser.rb', line 75

def self.register_default_browsers
  @browsers = nil

  self.register_browser([
    [:coremedia, /coremedia/i, /.+CoreMedia v([a-z0-9.]+)/i, "Apple CoreMedia"],

    [:opera_mobile, /opera mobi/i, /.+Opera Mobi.+((.+Opera )|(Version\/))([a-z0-9.]+)/i, "Opera Mobile"],
    [:opera, /opera/i, Proc.new{ |name, agent|
      regexp = (agent !~ /wii/i) ? /((.+Opera )|(Version\/))([a-z0-9.]+)/i : /(.+Nintendo Wii; U; ; )([a-z0-9.]+)/i

      version = regexp.match(agent)
      version = version.to_a.last if version.is_a?(MatchData)
      version
    }, "Opera"],

    [:android, /android/i, /(.+Android )([a-z0-9.]+)/i, "Android"],
    [:blackberry, /blackberry/i, /(.+Version\/)([a-z0-9.]+)/i, "RIM BlackBerry"],
    [:kindle, /(kindle)/i, /(.+(Kindle|Silk)\/)([a-z0-9.]+)/i, "Amazon Kindle"],
    [:psp, /psp/i, /(.+PlayStation Portable\); )([a-z0-9.]+)/i, "Sony Playstation Portable"],
    [:ps3, /playstation 3/i, /(.+PLAYSTATION 3; )([a-z0-9.]+)/i, "Sony Playstation 3"],
    [:windows_phone, /windows phone/i, /(.+IEMobile\/)([a-z0-9.]+)/i, "Microsoft Windows Phone"],
    [:wii, /nintendo wii/, /(.+Nintendo Wii; U; ; )([a-z0-9.]+)/i, "Nintendo Wii"],

    [:ipod, /ipod/i, /(.+Version\/)([a-z0-9.]+)/i, "Apple iPod"],
    [:iphone, /iphone/i, /(.+Version\/)([a-z0-9.]+)/i, "Apple iPhone"],
    [:ipad, /ipad/i, /(.+Version\/)([a-z0-9.]+)/i, "Apple iPad"],

    [:mobile, /(mobile|symbian|midp|windows ce)/i, /.+\/([a-z0-9.]+)/i, "Other Mobile Browser"],

    [:chrome, /((chrome)|(chromium))/i, /(.+Chrom[a-z]+\/)([a-z0-9.]+)/i, "Google Chrome"],
    [:netscape, /(netscape|navigator)\//i, /((Netscape|Navigator)\/)([a-z0-9.]+)/i, "Netscape Navigator"],
    [:firefox, /firefox/i, /(.+Firefox\/)([a-z0-9.]+)/i, "Mozilla Firefox"],
    [:safari, Proc.new{ |agent| agent =~ /safari/i && agent !~ /((chrome)|(chromium))/i }, /(.+Version\/)([a-z0-9.]+)/i, "Apple Safari"],

      [:msie_compatibility, /trident/i, Proc.new { |name, agent|
      version = /(.+Trident\/)([a-z0-9.]+)/i.match(agent)

      if version.is_a?(::MatchData) then
        v = version.to_a.last.split(".")
        v[0] = v[0].to_integer + 4
        version = v.join(".")
      end

      version
    }, "Microsoft Internet Explorer (Compatibility View)"],
    [:msie, Proc.new{ |agent| agent =~ /msie/i && agent !~ /opera/i }, /(.+MSIE )([a-z0-9.]+)/i, "Microsoft Internet Explorer"],

    [:quicktime, /quicktime/i, /(.+((QuickTime\/)|(qtver=)))([a-z0-9.]+)/i, "Apple QuickTime"],

    [:webkit, /webkit/i, /(.+WebKit\/)([a-z0-9.]+)/i, "WebKit Browser"],
    [:gecko, /gecko/i, /(.+rv:|Gecko\/)([a-z0-9.]+)/i, "Gecko Browser"],
  ])

  @browsers.present? ? true : false
end

.register_default_languagesBoolean

Registers the default list of languages that can be recognized.

Returns:

  • (Boolean)

    true if at least one language has been added, false otherwise.



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/brauser/browser.rb', line 159

def self.register_default_languages
  @languages = nil

  self.register_language({
    "af" => "Afrikaans",
    "sq" => "Albanian",
    "eu" => "Basque",
    "bg" => "Bulgarian",
    "be" => "Byelorussian",
    "ca" => "Catalan",
    "zh" => "Chinese",
    "zh-cn" => "Chinese/China",
    "zh-tw" => "Chinese/Taiwan",
    "zh-hk" => "Chinese/Hong Kong",
    "zh-sg" => "Chinese/singapore",
    "hr" => "Croatian",
    "cs" => "Czech",
    "da" => "Danish",
    "nl" => "Dutch",
    "nl-nl" => "Dutch/Netherlands",
    "nl-be" => "Dutch/Belgium",
    "en" => "English",
    "en-gb" => "English/United Kingdom",
    "en-us" => "English/United States",
    "en-au" => "English/Australian",
    "en-ca" => "English/Canada",
    "en-nz" => "English/New Zealand",
    "en-ie" => "English/Ireland",
    "en-za" => "English/South Africa",
    "en-jm" => "English/Jamaica",
    "en-bz" => "English/Belize",
    "en-tt" => "English/Trinidad",
    "et" => "Estonian",
    "fo" => "Faeroese",
    "fa" => "Farsi",
    "fi" => "Finnish",
    "fr" => "French",
    "fr-be" => "French/Belgium",
    "fr-fr" => "French/France",
    "fr-ch" => "French/Switzerland",
    "fr-ca" => "French/Canada",
    "fr-lu" => "French/Luxembourg",
    "gd" => "Gaelic",
    "gl" => "Galician",
    "de" => "German",
    "de-at" => "German/Austria",
    "de-de" => "German/Germany",
    "de-ch" => "German/Switzerland",
    "de-lu" => "German/Luxembourg",
    "de-li" => "German/Liechtenstein",
    "el" => "Greek",
    "he" => "Hebrew",
    "he-il" => "Hebrew/Israel",
    "hi" => "Hindi",
    "hu" => "Hungarian",
    "ie-ee" => "Internet Explorer/Easter Egg",
    "is" => "Icelandic",
    "id" => "Indonesian",
    "in" => "Indonesian",
    "ga" => "Irish",
    "it" => "Italian",
    "it-ch" => "Italian/ Switzerland",
    "ja" => "Japanese",
    "km" => "Khmer",
    "km-kh" => "Khmer/Cambodia",
    "ko" => "Korean",
    "lv" => "Latvian",
    "lt" => "Lithuanian",
    "mk" => "Macedonian",
    "ms" => "Malaysian",
    "mt" => "Maltese",
    "no" => "Norwegian",
    "pl" => "Polish",
    "pt" => "Portuguese",
    "pt-br" => "Portuguese/Brazil",
    "rm" => "Rhaeto-Romanic",
    "ro" => "Romanian",
    "ro-mo" => "Romanian/Moldavia",
    "ru" => "Russian",
    "ru-mo" => "Russian /Moldavia",
    "gd" => "Scots Gaelic",
    "sr" => "Serbian",
    "sk" => "Slovack",
    "sl" => "Slovenian",
    "sb" => "Sorbian",
    "es" => "Spanish",
    "es-do" => "Spanish",
    "es-ar" => "Spanish/Argentina",
    "es-co" => "Spanish/Colombia",
    "es-mx" => "Spanish/Mexico",
    "es-es" => "Spanish/Spain",
    "es-gt" => "Spanish/Guatemala",
    "es-cr" => "Spanish/Costa Rica",
    "es-pa" => "Spanish/Panama",
    "es-ve" => "Spanish/Venezuela",
    "es-pe" => "Spanish/Peru",
    "es-ec" => "Spanish/Ecuador",
    "es-cl" => "Spanish/Chile",
    "es-uy" => "Spanish/Uruguay",
    "es-py" => "Spanish/Paraguay",
    "es-bo" => "Spanish/Bolivia",
    "es-sv" => "Spanish/El salvador",
    "es-hn" => "Spanish/Honduras",
    "es-ni" => "Spanish/Nicaragua",
    "es-pr" => "Spanish/Puerto Rico",
    "sx" => "Sutu",
    "sv" => "Swedish",
    "sv-se" => "Swedish/Sweden",
    "sv-fi" => "Swedish/Finland",
    "ts" => "Thai",
    "tn" => "Tswana",
    "tr" => "Turkish",
    "uk" => "Ukrainian",
    "ur" => "Urdu",
    "vi" => "Vietnamese",
    "xh" => "Xshosa",
    "ji" => "Yiddish",
    "zu" => "Zulu"
  })

  @languages.present? ? true : false
end

.register_default_platformsBoolean

Registers the default list of platforms that can be recognized.

Returns:

  • (Boolean)

    true if at least one platform has been added, false otherwise.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/brauser/browser.rb', line 134

def self.register_default_platforms
  @platforms = nil

  self.register_platform([
    [:symbian, /s60|symb/i, "Symbian"],
    [:windows_phone, /windows phone/i, "Microsoft Windows Phone"],
    [:kindle, Proc.new { |name, agent| name == :kindle }, "Nokia Symbian"],
    [:ios, Proc.new { |name, agent| [:iphone, :ipad, :ipod].include?(name) || agent =~ /ipad|iphone|ipod/i }, "Apple iOS"],
    [:android, /android/i, "Android"],
    [:blackberry, /blackberry/i, "RIM BlackBerry"],
    [:psp, /psp/i, "Sony Playstation Portable"],
    [:ps3, /playstation 3/i, "Sony Playstation 3"],
    [:wii, /wii/i, "Nintendo Wii"],

    [:linux, /linux/i, "Linux"],
    [:osx, /mac|macintosh|mac os x/i, "Apple MacOS X"],
    [:windows, /windows/i, "Microsoft Windows"]
  ])

  @platforms.present? ? true : false
end

.register_language(code, label = nil) ⇒ Boolean

Registers a new language that can be recognized.

Parameters:

  • code (String|Hash)

    The language code or an hash with codes as keys and label as values.

  • label (String) (defaults to: nil)

    The language name. Ignored if code is an Hash.

Returns:

  • (Boolean)

    true if at least one language has been added, false otherwise.



361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/brauser/browser.rb', line 361

def self.register_language(code, label = nil)
  @languages ||= {}
  rv = false
  code = {code.ensure_string => label.ensure_string} if !code.is_a?(Hash)

  code.each_pair do |c, l|
    if c.present? && l.present? then
      @languages[c] = l
      rv = true
    end
  end

  rv
end

.register_platform(name, matcher = nil, label = nil) ⇒ Boolean

Registers a new platform that can be recognized.

Parameters:

  • name (Symbol|Array)

    The platform name or a list of platforms (a list of array with [name, matcher, label] entries).

  • matcher (StringRegexp|Block) (defaults to: nil)

    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.

  • label (String) (defaults to: nil)

    A human readable name of the platform.

Returns:

  • (Boolean)

    true if at least one platform has been added, false otherwise.



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/brauser/browser.rb', line 325

def self.register_platform(name, matcher = nil, label = nil)
  if !@platforms then
    @platforms = []
    @platforms_indexes = {}
  end


  rv = false
  name = [[name.ensure_string.to_sym, matcher, label]] if !name.is_a?(Array)

  name.each do |platform|
    platform[0] = platform[0].to_sym

    index = @platforms.index do |item|
      item[0] == platform[0]
    end

    # Replace a previous entry
    if index then
      @platforms[index] = platform
    else
      @platforms << platform
      @platforms_indexes[platform[0]] = @platforms.length - 1
    end

    rv = true
  end

  rv
end

Instance Method Details

#accepts(langs = []) ⇒ Query

Check if the browser accepts the specified languages.

Parameters:

  • langs (String|Array) (defaults to: [])

    A list of languages to match against.

Returns:

  • (Query)

    A query which can evaluated for concatenation or result.



665
666
667
668
# File 'lib/brauser/browser.rb', line 665

def accepts(langs = [])
  self.parse_accept_language(@accept_language) if !@languages
  ::Brauser::Query.new(self, (@languages & langs.ensure_array).present?)
end

#accepts?(langs = []) ⇒ Boolean

Check if the browser accepts the specified languages.

Parameters:

  • langs (String|Array) (defaults to: [])

    A list of languages to match against.

Returns:

  • (Boolean)

    true if current browser matches, false otherwise.



674
675
676
# File 'lib/brauser/browser.rb', line 674

def accepts?(langs = [])
  self.accepts(langs).result
end

#classes(join = " ", name = "", version = "version-", platform = "platform-") ⇒ String|Array Also known as: meta

Returns an array of information about the browser. Information are strings which are suitable to use as CSS classes.

For version, it will be included a class for every token of the version. For example, version 7.0.1.2 will return this:

["version-7", "version-7_0", "version-7_0_1", "version-7_0_1_2"]

If you provide a block (with accepts name, version and platform as arguments), it will be used for translating the name.

Parameters:

  • join (String|NilClass) (defaults to: " ")

    If non falsy, the separator to use to join information. If falsy, informations will be returned as array.

  • name (Boolean) (defaults to: "")

    If non falsy, the string to prepend to the name. If falsy, the name information will not be included.

  • version (String|NilClass) (defaults to: "version-")

    If non falsy, the string to prepend to the version. If falsy, the version information will not be included.

  • platform (String|NilClass) (defaults to: "platform-")

    If non falsy, the string to prepend to the platform. If falsy, the platform information will not be included.

Returns:

  • (String|Array)

    CSS ready information of the current browser.



754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
# File 'lib/brauser/browser.rb', line 754

def classes(join = " ", name = "", version = "version-", platform = "platform-")
  self.parse_agent(@agent) if !@name
  rv = []
  name = "" if name == true
  version = "version-" if version == true
  platform = "platform-" if platform == true

  # Manage name
  if name then
    final_name = block_given? ? yield(@name, @version, @platform) : @name
    rv << name + final_name.ensure_string
  end

  # Manage platform
  if version then
    vbuffer = []
    vtokens = @version.split(".")

    vtokens.each do |v|
      vbuffer << v
      rv << (version + vbuffer.join("_"))
    end
  end

  rv << (platform + @platform.to_s) if platform

  # Return
  join ? rv.join(join) : rv
end

#is(names = [], versions = {}, platforms = []) ⇒ Query

Checks if the browser is a specific name and optionally of a specific version and platform.

Parameters:

  • names (Symbol|Array) (defaults to: [])

    A list of specific names to match. Also, this meta-names are supported: :capable and :tablet.

  • versions (Hash) (defaults to: {})

    An hash with specific version to match against. Need to be in form {:operator => version}, where operator is one of :lt, :lte, :eq, :gt, :gte.

  • platforms (Symbol|Array) (defaults to: [])

    A list of specific platform to match. Valid values are all those possible for the platform attribute.

Returns:

  • (Query)

    A query which can evaluated for concatenation or result.

See Also:



552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
# File 'lib/brauser/browser.rb', line 552

def is(names = [], versions = {}, platforms = [])
  self.parse_agent(@agent) if !@name
  versions = {} if !versions.is_a?(::Hash)
  platforms = platforms.ensure_array

  # Adjust names
  names = names.ensure_array
  names << [:msie] if names.include?(:ie)
  names << [:chromium] if names.include?(:chrome)

  if names.delete(:capable) then
    names += [:chrome, :firefox, :safari, :opera, :msie]

    # Add version 9 as minimum for IE if capable is specified
    versions[:gte] = 9 if @name == :msie
  end

  names << [:ipad, :android, :kindle] if names.delete(:tablet)
  names.compact!

  rv = names.blank? || names.include?(@name)

  # Look also for version
  rv = rv && self.v?(versions) if rv && versions.present?

  # Look also for platforms
  rv = rv && self.on?(platforms) if rv && platforms.present?

  ::Brauser::Query.new(self, rv)
end

#is?(names = [], versions = {}, platforms = []) ⇒ Boolean

Checks if the browser is a specific name and optionally of a specific version and platform.

Parameters:

  • names (Symbol|Array) (defaults to: [])

    A list of specific names to match. Also, this meta-names are supported: :capable and :tablet.

  • versions (Hash) (defaults to: {})

    An hash with specific version to match against. Need to be in form {:operator => version}, where operator is one of :lt, :lte, :eq, :gt, :gte.

  • platforms (Symbol|Array) (defaults to: [])

    A list of specific platform to match. Valid values are all those possible for the platform attribute.

Returns:

  • (Boolean)

    true if current browser matches, false otherwise.

See Also:



592
593
594
# File 'lib/brauser/browser.rb', line 592

def is?(names = [], versions = {}, platforms = [])
  self.is(names, versions, platforms).result
end

#on(platforms = []) ⇒ Query

Check if the browser is on a specific platform.

Parameters:

  • platforms (Symbol|Array) (defaults to: [])

    A list of specific platform to match.

Returns:

  • (Query)

    A query which can evaluated for concatenation or result.



648
649
650
651
# File 'lib/brauser/browser.rb', line 648

def on(platforms = [])
  self.parse_agent(@agent) if !@platform
  ::Brauser::Query.new(self, platforms.blank? || platforms.ensure_array.collect {|p| p.ensure_string.to_sym }.include?(@platform))
end

#on?(platforms = []) ⇒ Boolean

Check if the browser is on a specific platform.

Parameters:

  • platforms (Symbol|Array) (defaults to: [])

    A list of specific platform to match.

Returns:

  • (Boolean)

    true if current browser matches, false otherwise.



657
658
659
# File 'lib/brauser/browser.rb', line 657

def on?(platforms = [])
  self.on(platforms).result
end

#parse_accept_language(accept_language = nil) ⇒ Array

Parses the Accept-Language header.

Parameters:

  • accept_language (String) (defaults to: nil)

    The Accept-Language header.

Returns:

  • (Array)

    The list of accepted languages.



523
524
525
# File 'lib/brauser/browser.rb', line 523

def parse_accept_language(accept_language = nil)
  accept_language.ensure_string.gsub(/;q=[\d.]+/, "").split(",").collect {|l| l.downcase.strip }.select{|l| l.present? }
end

#parse_agent(agent = nil) ⇒ Boolean

Parses the User-Agent header.

Parameters:

  • agent (String) (defaults to: nil)

    The User-Agent header.

Returns:

  • (Boolean)

    true if the browser was detected, false otherwise.



463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/brauser/browser.rb', line 463

def parse_agent(agent = nil)
  agent = agent.ensure_string

  # At first, detect name and version. Tries order is important to avoid false positives.
  @name = catch(:name) do
    self.class.browsers.each do |name, definitions|
      matched = false

      if definitions[0].is_a?(::Regexp) then
        matched = definitions[0].match(agent) ? true : false
      elsif definitions[0].respond_to?(:call) then
        matched = (definitions[0].call(agent) ? true : false)
      else
        matched = (agent == definitions[0].ensure_string)
      end

      if matched then # Found a match, go through version
        if definitions[1].is_a?(::Regexp) then
          @version = definitions[1].match(agent)
          @version = @version.to_a.last if @version.is_a?(::MatchData)
        elsif @version = definitions[1].respond_to?(:call) then
          @version = definitions[1].call(name, agent).ensure_string
        else
          @version = definitions[1].ensure_string
        end
      end

      throw(:name, name) if matched
    end

    :unknown
  end

  # Adjust version
  @version = "0.0" if @version.blank?

  # At last, detect platform
  @platform = catch(:platform) do
    self.class.platforms.each do |platform, definitions|
      if definitions[0].is_a?(::Regexp) then
        matched = definitions[0].match(agent) ? true : false
      elsif definitions[0].respond_to?(:call) then
        matched = (definitions[0].call(@name, agent) ? true : false)
      else
        matched = (agent == definitions[0].ensure_string)
      end

      throw(:platform, platform) if matched
    end

    :unknown
  end

  (@name != :unknown) ? true : false
end

#platform_nameString

Gets a human-readable platform name.

Returns:

  • (String)

    A readable platform name.



538
539
540
541
# File 'lib/brauser/browser.rb', line 538

def platform_name
  self.parse_agent(@agent) if !@platform
  self.class.platforms.fetch(@platform, ["Unknown Platform"]).last.ensure_string
end

#readable_nameString

Gets a human-readable browser name.

Returns:

  • (String)

    A human-readable browser name.



530
531
532
533
# File 'lib/brauser/browser.rb', line 530

def readable_name
  self.parse_agent(@agent) if !@name
  self.class.browsers.fetch(@name, ["Unknown Browser"]).last.ensure_string
end

#to_sString

Returns the current browser as a string.

Returns:

  • (String)

    A string representation of the current browser.

See Also:



790
791
792
# File 'lib/brauser/browser.rb', line 790

def to_s
  self.classes
end

#v(versions = {}) ⇒ Query

Checks if the brower is a specific version.

Parameters:

  • versions (String|Hash) (defaults to: {})

    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.

Returns:

  • (Query)

    A query which can evaluated for concatenation or result.



600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
# File 'lib/brauser/browser.rb', line 600

def v(versions = {})
  self.parse_agent(@agent) if !@version
  rv = true

  if versions.is_a?(String) then
    versions_s = versions
    versions = {}

    versions_s.split(/\s*&&\s*/).each do |token|
      next if token.strip.empty?
      tokens = token.strip.split(/\s+/).collect {|t| t.strip}
      operator = case tokens[0]
        when "<" then :lt
        when "<=" then :lte
        when "=" then :eq
        when "==" then :eq
        when ">=" then :gte
        when ">" then :gt
        else tokens[0].downcase.to_sym
      end

      versions[operator] = tokens[1]
    end
  else
    versions = {} if !versions.is_a?(::Hash)
  end

  versions.each do |operator, value|
    value = value.ensure_string
    rv = rv && Brauser::Browser.compare_versions(@version, operator, value)
    break if !rv
  end

  ::Brauser::Query.new(self, rv)
end

#v?(versions = {}) ⇒ Boolean

Checks if the brower is a specific version.

Parameters:

  • versions (String|Hash) (defaults to: {})

    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.

Returns:

  • (Boolean)

    true if current browser matches, false otherwise.



640
641
642
# File 'lib/brauser/browser.rb', line 640

def v?(versions = {})
  self.v(versions).result
end