browserino 4.3.0 → 4.4.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/browserino.gemspec CHANGED
@@ -5,18 +5,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'browserino/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "browserino"
9
- spec.version = Browserino.version.full
10
- spec.authors = ["Sidney Liebrand"]
11
- spec.email = ["sidneyliebrand@gmail.com"]
12
- spec.summary = %q{A browser identification gem with command line and Rails (>= 3.2.0) integration}
13
- spec.homepage = "https://github.com/sidofc/browserino"
14
- spec.license = "MIT"
8
+ spec.required_ruby_version = '>= 2.0'
9
+ spec.name = "browserino"
10
+ spec.version = Browserino.version.full
11
+ spec.authors = ["Sidney Liebrand"]
12
+ spec.email = ["sidneyliebrand@gmail.com"]
13
+ spec.summary = %q{A browser identification gem with command line and Rails (>= 3.2.0) integration}
14
+ spec.homepage = "https://github.com/sidofc/browserino"
15
+ spec.license = "MIT"
15
16
 
16
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
- spec.bindir = "bin"
18
- spec.executables = ['browserino']
19
- spec.require_paths = ["lib"]
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "bin"
19
+ spec.executables = ['browserino']
20
+ spec.require_paths = ["lib"]
20
21
 
21
22
  spec.add_development_dependency "bundler"
22
23
  spec.add_development_dependency "rake"
@@ -50,6 +50,7 @@ module Browserino
50
50
 
51
51
  def is?(sym, opt = {})
52
52
  return invertable send("#{sym}?", opt[:version]) if opt && opt[:version]
53
+
53
54
  invertable send("#{sym}?")
54
55
  end
55
56
 
@@ -125,7 +126,7 @@ module Browserino
125
126
  # if you wish for a method to respond to the #not method,
126
127
  # you'll have to return the result of a function using the `invertable`
127
128
  # method as seen in `method_missing` - this will apply the state of the
128
- # instance variable and invert the state aswell as the result if set,
129
+ # instance variable and invert the state as well as the result if set,
129
130
  # otherwise it will just return the value without touching it
130
131
  def not
131
132
  @not = true && self
@@ -139,16 +140,19 @@ module Browserino
139
140
 
140
141
  def label_for(sym, from = properties)
141
142
  return from[:label] if %i[version label name].include? sym
143
+
142
144
  from["#{sym}_label".to_sym]
143
145
  end
144
146
 
145
147
  def name_for(sym, from = properties)
146
148
  return from[:name] if %i[version label name].include? sym
149
+
147
150
  from["#{sym}_name".to_sym]
148
151
  end
149
152
 
150
153
  def version_for(sym, from = properties)
151
154
  return from[:version] if %i[version label name].include? sym
155
+
152
156
  from["#{sym}_version".to_sym]
153
157
  end
154
158
 
@@ -196,11 +200,5 @@ module Browserino
196
200
  end
197
201
  end
198
202
  end
199
-
200
- def get_answer(mtd, res, ver = nil, val = nil)
201
- return res.is_a?(Version) ? res > '0.0.0' : res && true unless val
202
- incl = res == val
203
- ver && incl ? version_for(mtd) == ver : incl
204
- end
205
203
  end
206
204
  end
@@ -9,8 +9,13 @@ module Browserino
9
9
  end
10
10
  end
11
11
 
12
+ def prop_missing(name, &block)
13
+ missing_props[name] = block
14
+ end
15
+
12
16
  def label(name, **opts)
13
17
  return false unless opts[:for]
18
+
14
19
  opts[:name] ||= name
15
20
  labels[opts[:for]] << opts
16
21
  end
@@ -16,4 +16,8 @@ Browserino.config.define do
16
16
  alias_for :chromeos, :cros
17
17
  alias_for :nintendobrowser, :netfrontbrowser
18
18
  alias_for :ipd, :alertsite
19
+ alias_for :qupzilla, :falkon
20
+
21
+ # backwards compat with android_(p..z) labels
22
+ alias_for :pie, :android_p
19
23
  end
@@ -9,8 +9,8 @@ Browserino.config.define do
9
9
  # the returned result will be used as the user agent to parse so make
10
10
  # sure to return the final ua at the end
11
11
  before_parse do |ua|
12
- subs = [[%r{applewebkit}i, 'webkit'], [%r{(Mozilla/[\d\.]+)}i, ''],
13
- [%r{\sAdr\s}, 'Android '], ['X11', '']]
12
+ subs = [[%r{applewebkit}i, 'webkit'], [%r{\sAdr\s}, 'Android '],
13
+ [%r{(Mozilla/[\d\.]+|X11|PVR DL)}i, '']]
14
14
  subs << [%r{Chrome|Safari}, ''] if ua =~ %r{nichrome|digg\sfeed|quiterss}i
15
15
  subs << [%r{9\.80}, ''] if ua =~ %r{opera}i
16
16
  subs << [%r{webkit/}i, ''] if ua =~ %r{presto}i
@@ -42,41 +42,49 @@ Browserino.config.define do
42
42
  # before any named filters
43
43
  filter do |val|
44
44
  case val
45
- when TrueClass, FalseClass, NilClass, Proc then val
46
- when %r{\A[\d_\.]+\z}i then val.to_s.strip.tr '_', '.'
45
+ when TrueClass, FalseClass, NilClass, Proc, Array then val
46
+ when %r{\A[\d_\.]+\z}i then val.to_s.strip.tr '_', '.'
47
47
  else val.to_s.downcase.strip.gsub(%r{[\s-]+}i, '_').to_sym
48
48
  end
49
49
  end
50
50
 
51
51
  # this is a named filter, it defines the same filter for 3 properties
52
- # multiple name filters for the same property can be created, they will be
53
- # executed in order of addition
52
+ # multiple name filters for the same property can be created, they
53
+ # will be executed in order of definition
54
54
  filter :version, :engine_version, :platform_version do |val|
55
55
  Browserino::Version.new val
56
56
  end
57
57
 
58
+ filter :locales do |locales|
59
+ locales.map do |(locale, _quality)|
60
+ locale.downcase.strip.tr('-', '_').to_sym
61
+ end
62
+ end
63
+
58
64
  filter :platform do |val|
59
- if %r{ip(?:[ao]d|hone)}i =~ val then :ios
60
- elsif %r{^symbian$}i =~ val then :symbianos
61
- elsif %r{w(?:eb)?os}i =~ val then :webos
62
- elsif %r{ubuntu|debian}i =~ val then :linux
63
- elsif %r{mac_os_x}i =~ val then :macintosh
64
- elsif %r{s(?:unos|olaris)}i =~ val then :solaris
65
- elsif %r{cros}i =~ val then :chromeos
66
- elsif %r{kindle|kf\w+}i =~ val then :fire_os
67
- elsif %r{fxos}i =~ val then :firefox_os
65
+ case val
66
+ when %r{ip(?:[ao]d|hone)}i then :ios
67
+ when %r{^symbian$}i then :symbianos
68
+ when %r{w(?:eb)?os}i then :webos
69
+ when %r{ubuntu|debian}i then :linux
70
+ when %r{mac_os_x}i then :macintosh
71
+ when %r{s(?:unos|olaris)}i then :solaris
72
+ when %r{cros}i then :chromeos
73
+ when %r{kindle|kf\w+}i then :fire_os
74
+ when %r{fxos}i then :firefox_os
68
75
  else val
69
76
  end
70
77
  end
71
78
 
72
79
  filter :device do |val|
73
- if %r{kf\w*}i =~ val then :kindle
74
- elsif %r{lg[-l_]}i =~ val then :lg
75
- elsif %r{\w+tab}i =~ val then :lenovo
76
- elsif %r{lumia}i =~ val then :nokia
77
- elsif %r{^moto}i =~ val then :motorola
78
- elsif %r{\d+dl|venue}i =~ val then :dell
79
- elsif %r{me\d+x|a\df;|transformer|slider}i =~ val then :asus
80
+ case val
81
+ when %r{kf\w*}i then :kindle
82
+ when %r{lg[-l_]}i then :lg
83
+ when %r{\w+tab}i then :lenovo
84
+ when %r{lumia}i then :nokia
85
+ when %r{^moto}i then :motorola
86
+ when %r{\d+dl|venue}i then :dell
87
+ when %r{me\d+x|a\df;|transformer|slider}i then :asus
80
88
  else val
81
89
  end
82
90
  end
@@ -25,6 +25,7 @@ Browserino.config.define do
25
25
  label :marshmallow, for: :android, range: '6'..'6.9.9'
26
26
  label :nougat, for: :android, range: '7'..'7.9.9'
27
27
  label :oreo, for: :android, range: '8'..'8.9.9'
28
+ label :pie, for: :android, range: '9'..'9.9.9'
28
29
 
29
30
  # support android up to the letter Z by following their version scheme which
30
31
  # uses versions X.0.0 up to X.9.9. the callable methods will be named like
@@ -161,6 +161,7 @@ Browserino.config.bots text: true, good: proc { !bad },
161
161
  match %r{nutch}i, name: :nutch
162
162
  match %r{ia_archiver}i, name: :alexa
163
163
  match %r{atomz}i, name: :atomz
164
+ match %r{ntent}i, name: :ntent
164
165
  match %r{htdig}i, name: :htdig
165
166
  match %r{peew}i, name: :peew
166
167
  match %r{yeti}i, name: :yeti
@@ -173,6 +174,9 @@ Browserino.config.bots text: true, good: proc { !bad },
173
174
  match %r{ipd/}i, name: :ipd
174
175
  match %r{zao}i, name: :zao
175
176
 
177
+ match %r{sheenbot}i, name: :sheenbot,
178
+ version: %r{sheenbot\-([\d\.]+)}i
179
+
176
180
  match %r{furlbot}i, name: :furlbot,
177
181
  version: %r{rl\ssearch\s([\d\.]+)}i
178
182
 
@@ -40,8 +40,9 @@ Browserino.config.browsers do
40
40
  engine %r{(presto|webkit)}i
41
41
  end
42
42
 
43
- # escape has to come before IE
44
- match %r{escape}i, name: :escape
43
+ # these come before IE
44
+ match %r{escape}i, name: :escape
45
+ match %r{juzi(?:browser)}i, name: :orange_browser, engine: :trident
45
46
 
46
47
  match %r{flock}i, name: :flock, engine: %r{(webkit|gecko|servo)}i,
47
48
  engine_version: %r{(?:webkit|rv:|servo)[\s/]?([\d\.]+)}i
@@ -56,14 +57,31 @@ Browserino.config.browsers do
56
57
  modern { version >= 10 }
57
58
  end
58
59
 
60
+ match %r{alohabrowser}i, name: :alohabrowser, engine: :webkit
59
61
  match %r{origyn\sweb\sbrowser}i, name: :origyn, engine: :webkit
60
62
  match %r{webpositive}i, name: :webpositive, engine: :webkit
61
63
  match %r{nintendobrowser}i, name: :nintendobrowser, engine: :webkit
62
64
  match %r{deskbrowse}i, name: :deskbrowse, engine: :webkit
63
- match %r{qupzilla}i, name: :qupzilla, engine: :webkit
64
65
  match %r{midori}i, name: :midori, engine: :webkit
65
66
  match %r{shiira}i, name: :shiira, engine: :webkit
66
67
  match %r{element\sbrowser}i, name: :element_browser, engine: :webkit
68
+ match %r{iris}i, name: :iris, engine: :webkit
69
+ match %r{otter}i, name: :otter, engine: :webkit
70
+ match %r{chedot}i, name: :chedot, engine: :webkit
71
+ match %r{acheetahi}i, name: :cm_browser, engine: :webkit
72
+ match %r{diglo}i, name: :diglo, engine: :webkit
73
+ match %r{diigo(?:browser)}i, name: :diigo_browser, engine: :webkit
74
+ match %r{flyflow}i, name: :flyflow, engine: :webkit
75
+ match %r{freebox}i, name: :freebox, engine: :webkit
76
+ match %r{kuaiso}i, name: :kuaiso, engine: :webkit
77
+ match %r{lovense}i, name: :lovense, engine: :webkit
78
+ match %r{slimjet}i, name: :slimjet, engine: :webkit
79
+ match %r{zetakey}i, name: :zetakey, engine: :webkit
80
+ match %r{wkbrowser}i, name: :wkbrowser, engine: :webkit
81
+ match %r{yolobrowser}i, name: :yolobrowser, engine: :webkit
82
+ match %r{whale}i, name: :whale, engine: :webkit
83
+ match %r{vivo}i, name: :vivo, engine: :webkit
84
+ match %r{jasmine}i, name: :jasmine
67
85
  match %r{amigavoyager}i, name: :amigavoyager
68
86
  match %r{acorn\sbrowse}i, name: :browse
69
87
  match %r{mothra}i, name: :mothra
@@ -71,6 +89,24 @@ Browserino.config.browsers do
71
89
  match %r{spray\-can}i, name: :spray_can
72
90
  match %r{bunjalloo}i, name: :bunjalloo
73
91
 
92
+ match %r{sraf}i, name: :seraphic_sraf,
93
+ version: %r{sraf/([\d\.]+)}i
94
+
95
+ match %r{phantomjs}i, name: :phantomjs,
96
+ engine: %r{(webkit|gecko|servo|trident|blink)}i
97
+
98
+ match %r{slimerjs}i, name: :slimerjs,
99
+ engine: %r{(webkit|gecko|servo|trident|blink)}i,
100
+ engine_version: %r{(?:webkit|gecko|servo|
101
+ trident|blink|rv)
102
+ [:/]([\d\.]+)}xi
103
+
104
+ match %r{liebao}i, name: :liebao, engine: :webkit,
105
+ version: %r{liebao(?:fast)/([\d\.]+)}i
106
+
107
+ match %r{qupzilla|falkon}i, name: :qupzilla, engine: :webkit,
108
+ version: %r{(?:qupzilla|falkon)/([\d\.]+)}i
109
+
74
110
  match %r{inet\sbrowser}i, name: :inet_browser,
75
111
  platform: :star_blade_os
76
112
 
@@ -119,6 +155,7 @@ Browserino.config.browsers do
119
155
  match %r{osb\-browser}i, name: :osb_browser, engine: :webkit
120
156
  match %r{edbrowse}i, name: :edbrowse, text: true
121
157
  match %r{amaya}i, name: :amaya, text: true
158
+ match %r{w3m}i, name: :w3m, text: true
122
159
  match %r{lynx}i, name: :lynx, text: true
123
160
  match %r{linemode}i, name: :linemode, text: true
124
161
  match %r{elinks}i, name: :elinks, text: true
@@ -129,14 +166,18 @@ Browserino.config.browsers do
129
166
  match %r{konqueror}i, name: :konqueror
130
167
  match %r{cyberdog}i, name: :cyberdog
131
168
  match %r{offbyone}i, name: :offbyone
132
- match %r{hotjava}i, name: :hotjava
133
169
  match %r{netsurf}i, name: :netsurf
134
170
  match %r{contiki}i, name: :contiki
135
171
  match %r{mosaic|ibrowse[^r]}i, name: :mosaic
136
172
  match %r{netbox}i, name: :netbox
173
+ match %r{charon}i, name: :charon
137
174
  match %r{dillo}i, name: :dillo
138
175
  match %r{ice\sbrowser}i, name: :ice_browser
139
176
 
177
+ match %r{hotjava|webrunner}i, name: :hotjava, engine: %r{(gecko)}i,
178
+ version: %r{(?:hotjava|webrunner)/([\d\.]+)}i,
179
+ engine_version: %r{rv:\s?([\d\.]+)}i
180
+
140
181
  match %r{emacs}i, name: :emacs, text: true,
141
182
  version: %r{emacs(?:\-\w+)?/([\d\.]+)}i
142
183
 
@@ -201,6 +242,7 @@ Browserino.config.browsers do
201
242
  match %r{perk}i, name: :perk
202
243
  match %r{hana}i, name: :hana
203
244
  match %r{(?<!env)iron}i, name: :iron
245
+ match %r{cent\b}i, name: :cent, engine: :blink
204
246
 
205
247
  match %r{nichrome}i, name: :nichrome, engine: :webkit,
206
248
  version: %r{chrome[\s/]\w+[\s/]([\d\.]+)}i
@@ -346,11 +388,16 @@ Browserino.config.browsers do
346
388
 
347
389
  # below are special cases where we need to manually
348
390
  # supply the version pattern
349
- match %r{flexnetdesktopclient}i, name: :netflix_desktop,
350
- version: %r{pclient_([\d\.\_]+)}i
391
+ match %r{flexnetdesktopclient}i, name: :netflix_desktop,
392
+ version: %r{pclient_([\d\.\_]+)}i
393
+
394
+ match %r{MetaSr}, name: :sogou_browser,
395
+ version: %r{metasr\s([\d\.\_]+)}i
351
396
 
352
- match %r{MetaSr}, name: :sogou_browser,
353
- version: %r{metasr\s([\d\.\_]+)}i
397
+ match %r{jig(?:\sbrowser\sweb)}i, name: :jig_browser_web,
398
+ engine: %r{webkit|trident|gecko},
399
+ version: %r{jig(?:\sbrowser\sweb);
400
+ \s?([\d\.]+)}xi
354
401
 
355
402
  # we can exclude the default version which will then be replaced by
356
403
  # the smart_matcher for :version which uses the :name token automatically
@@ -367,6 +414,7 @@ Browserino.config.browsers do
367
414
  match %r{netcaptor}i, name: :netcaptor
368
415
  match %r{sleipnir}i, name: :sleipnir
369
416
  match %r{irider}i, name: :irider
417
+ match %r{blazer}i, name: :blazer
370
418
  match %r{kkman}i, name: :kkman
371
419
  match %r{lobo}i, name: :lobo
372
420
  match %r{foxy}i, name: :foxy
@@ -18,5 +18,6 @@ Browserino.config.emails do
18
18
  match %r{thunderbird}i, name: :thunderbird
19
19
  match %r{spicebird}i, name: :spicebird
20
20
  match %r{postbox}i, name: :postbox
21
+ match %r{icedove}i, name: :icedove
21
22
  end
22
23
  end
@@ -17,9 +17,19 @@ Browserino.config.define do
17
17
  # a simple set of global matchers that will be merged and scanned
18
18
  # with a specific matcher when the final client object is created
19
19
  match do
20
- locale %r{(?<!nintendo)[;\s(]([a-z]{2}(?:[-_][a-z]{2})?)\-?[;)]}i
20
+ locale %r{(?<!nintendo)[;\s(](?!nt)([a-z]{2}(?:[-_][a-z]{2})?)
21
+ \-?[;)/](?!\d)}xi
21
22
  architecture %r{((?:(?:x|x86_|amd|wow|win)64)|i[36]86|arm)}i
22
23
 
24
+ # set locales prop which will be populated with accept-language header
25
+ # locales sorted by quality when Browserino.parse receives
26
+ # a hash of http headers as second argument
27
+ locales []
28
+
29
+ # overwrite client-generated locales? method
30
+ # to make the correct comparison for arrays
31
+ locales? { locales.any? }
32
+
23
33
  smarttv %r{(?:smart[\-\s]|hbb|apple\s|google|g)(tv)}i
24
34
 
25
35
  tablet %r{(ipad|transformer|slider|a\d+f;|tablet|lenovo
@@ -35,7 +45,8 @@ Browserino.config.define do
35
45
  |blackberry|linux|ubuntu|beos|unix|bsd|s(?:unos|olaris)
36
46
  |tizen|xbox|amigaos|w(?:eb)?os|(?<!mi)cros|bada|palmos
37
47
  |kindle|symbiano?s?|sailfish|meego|darwin|syllable|fxos
38
- |(?<!en)risc|rim\stablet\sos|haiku|morphos|debian)}xi
48
+ |(?<!en)risc|rim\stablet\sos|haiku|morphos|debian
49
+ |inferno)}xi
39
50
 
40
51
  platform_version %r{(?:windows(?:\sphone(?:\sos)?)?|nt|android|linux/?|fxos
41
52
  |mac\sos\sx(?:\s\w+\s)?|(?:cpu\s|ip(?:[ao]d|hone)\s)os
@@ -46,7 +57,7 @@ Browserino.config.define do
46
57
  device %r{(alcatel|all(?:tell|view)|htc|kindle|kf\w\w|apple\s?tv
47
58
  |iphone|ipad|a\d+f;|archos|transformer|slider|me\d+x|zte
48
59
  |blackberry|\d+dl|venue|desire|oneplus|lenovo|lumia|moto
49
- |huawei\b|motorola|nokia|nexus|\b\w+tab\b|lg[-l]
50
- |(?<!p)hp)}xi
60
+ |huawei\b|motorola|nokia|nexus|\b\w+tab\b|lg[-l]|oppo
61
+ |\b(?<!p)hp)}xi
51
62
  end
52
63
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ Browserino.config.define do
4
+ # when a property like :locale cannot be found and
5
+ # Browserino.parse is called with a headers hash in addition to the ua,
6
+ # prop_missing method allows you to define a fallback block which
7
+ # receives all gathered props so far and the headers as arguments.
8
+ # the return value of this block will then be used as value for that property.
9
+
10
+ # prop_missing calls are executed in order of definition,
11
+ # this allows you to leverage properties found in prior prop_missing calls
12
+ # as seen with :locales and :locale below
13
+ prop_missing :locales do |http_headers|
14
+ http_headers[:accept_language]
15
+ .to_s.scan(/(\w{2}(?:[_\-]\w{2})?)(?:;q=([\d.]+))?/i)
16
+ .map { |(locale, quality)| [locale, (quality || 1).to_f] }
17
+ .sort_by { |a| -a[1] }
18
+ .map(&:first)
19
+ end
20
+
21
+ prop_missing :locale do |_http_headers, props|
22
+ props[:locales].first
23
+ end
24
+ end
@@ -6,7 +6,10 @@ module Browserino
6
6
  class ActionController
7
7
  module Base
8
8
  def client
9
- @client ||= Browserino.parse request.headers['User-Agent']
9
+ @client ||= Browserino.parse(
10
+ request.headers['User-Agent'],
11
+ request.headers.env.reject { |k| k.include? '.' }
12
+ )
10
13
  end
11
14
  end
12
15
  end
@@ -1,17 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Browserino
4
- def self.analyze(uas, matcher = nil)
4
+ def self.analyze(uas, matcher = nil, headers = nil)
5
5
  @defaults ||= config.global_matchers.map(&:properties).reduce(&:merge)
6
6
 
7
7
  props = @defaults.merge(matcher && matcher.properties || {})
8
8
  like = props.delete :like
9
9
  props = mass_collect props, uas
10
- like = Client.new props.merge(like_attrs(props, like, uas)) if like
10
+
11
+ if headers.is_a? Hash
12
+ headers = normalize_header_keys headers
13
+ props = fill_missing_with_headers headers, props
14
+ end
15
+
16
+ props = fix_inconsistent_props props
17
+
18
+ like = Client.new props.merge(like_attrs(props, like, uas)) if like
11
19
 
12
20
  Client.new props, like
13
21
  end
14
22
 
23
+ def self.fix_inconsistent_props(hsh)
24
+ # patch locale and locales props
25
+ if hsh[:locales].any?
26
+ # when locale is not present in locales, append it
27
+ hsh[:locales] << hsh[:locale] unless hsh[:locales].include? hsh[:locale]
28
+
29
+ # ensure locales.first == locale when locale present in locales
30
+ hsh[:locale] = hsh[:locales].first
31
+ elsif hsh[:locale]
32
+ # no locales from header but locale is found in UA, append locale
33
+ # to locales to ensure expected output
34
+ hsh[:locales] << hsh[:locale]
35
+ end
36
+
37
+ hsh
38
+ end
39
+
40
+ def self.normalize_header_keys(headers)
41
+ headers.each_with_object({}) do |(header, value), normalized|
42
+ header = header.gsub(/^HTTP_/i, '').tr('-', '_').downcase.to_sym
43
+ normalized[header] = value
44
+ end
45
+ end
46
+
47
+ def self.fill_missing_with_headers(headers, props)
48
+ config.missing_props.each_with_object props do |(prop, blk), res|
49
+ if props.key?(prop) && (!props[prop] ||
50
+ (props[prop].respond_to?(:empty?) && props[prop].empty?))
51
+ res[prop] = convert blk.call(headers, res), format: prop
52
+ end
53
+ end
54
+ end
55
+
15
56
  def self.like_attrs(props, like, user_agent)
16
57
  version = config.matchers.select { |m| m == like }
17
58
  .first.properties[:version]
@@ -23,22 +64,25 @@ module Browserino
23
64
  end
24
65
 
25
66
  def self.config
26
- @config ||= Config.new(before_parse: [],
67
+ @config ||= Config.new before_parse: [],
27
68
  global_matchers: [],
28
- properties: [],
29
- types: [:unknown],
30
- names: [],
31
- smart_matchers: {},
32
- matchers: [],
33
- labels: Hash.new { |h, k| h[k] = [] },
34
- filters: Hash.new { |h, k| h[k] = [] },
35
- aliasses: Hash.new { |h, k| h[k] = [] })
69
+ properties: [],
70
+ types: [:unknown],
71
+ names: [],
72
+ smart_matchers: {},
73
+ missing_props: {},
74
+ matchers: [],
75
+ labels: Hash.new { |h, k| h[k] = [] },
76
+ filters: Hash.new { |h, k| h[k] = [] },
77
+ aliasses: Hash.new { |h, k| h[k] = [] }
36
78
  end
37
79
 
38
80
  def self.label_for(target_name, version = nil)
39
81
  return unless config.labels.key?(target_name) && version
82
+
40
83
  version = Version.new version unless version.is_a? Version
41
84
  return unless version > 0
85
+
42
86
  config.labels[target_name].each do |candidate|
43
87
  return candidate[:name] if version.between? candidate[:range]
44
88
  end
@@ -62,6 +106,7 @@ module Browserino
62
106
  def self.smart_matchers(properties)
63
107
  config.smart_matchers.each_with_object({}) do |(prop, detector), props|
64
108
  next if properties.key? prop
109
+
65
110
  props[prop] = parse_detector detector, properties
66
111
  end
67
112
  end
@@ -8,6 +8,7 @@ module Browserino
8
8
 
9
9
  def method_missing(sym, *args)
10
10
  return @options[opt(sym)] == args.first if args.any?
11
+
11
12
  @options[opt(sym)]
12
13
  end
13
14
 
@@ -47,7 +48,7 @@ module Browserino
47
48
  end
48
49
 
49
50
  def option?(sym)
50
- @options.keys.include? opt(sym)
51
+ @options.key? opt(sym)
51
52
  end
52
53
  end
53
54
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Browserino
4
- def self.version(current = '4.3.0')
4
+ def self.version(current = '4.4.0')
5
5
  @version ||= Version.new current
6
6
  end
7
7
 
data/lib/browserino.rb CHANGED
@@ -13,13 +13,14 @@ require_relative 'browserino/definitions/matchers'
13
13
  require_relative 'browserino/definitions/aliasses'
14
14
  require_relative 'browserino/definitions/filters'
15
15
  require_relative 'browserino/definitions/labels'
16
+ require_relative 'browserino/definitions/missing_props'
16
17
 
17
18
  module Browserino
18
- def self.parse(uas)
19
- config.before_parse.each { |b| uas = b.call uas }
19
+ def self.parse(uas, headers = nil)
20
+ uas = config.before_parse.reduce(uas) { |u, b| b.call u }
20
21
  config.matchers.each do |matcher|
21
- return analyze uas, matcher if matcher.matches? uas
22
+ return analyze uas, matcher, headers if matcher.matches? uas
22
23
  end
23
- analyze uas
24
+ analyze uas, nil, headers
24
25
  end
25
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browserino
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sidney Liebrand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-23 00:00:00.000000000 Z
11
+ date: 2018-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -147,6 +147,7 @@ files:
147
147
  - lib/browserino/definitions/matchers/mediaplayers.rb
148
148
  - lib/browserino/definitions/matchers/rss.rb
149
149
  - lib/browserino/definitions/matchers/validators.rb
150
+ - lib/browserino/definitions/missing_props.rb
150
151
  - lib/browserino/integrate/action_controller.rb
151
152
  - lib/browserino/integrate/rails.rb
152
153
  - lib/browserino/matcher.rb
@@ -165,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
166
  requirements:
166
167
  - - ">="
167
168
  - !ruby/object:Gem::Version
168
- version: '0'
169
+ version: '2.0'
169
170
  required_rubygems_version: !ruby/object:Gem::Requirement
170
171
  requirements:
171
172
  - - ">="