browser 3.0.2 → 5.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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +1 -1
- data/.prettierignore +1 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +3 -3
- data/CHANGELOG.md +81 -18
- data/FUNDING.yml +3 -0
- data/README.md +113 -88
- data/bots.yml +300 -294
- data/browser.gemspec +3 -1
- data/lib/browser/base.rb +63 -7
- data/lib/browser/browser.rb +27 -26
- data/lib/browser/chrome.rb +12 -2
- data/lib/browser/device.rb +2 -2
- data/lib/browser/device/unknown.rb +1 -1
- data/lib/browser/duck_duck_go.rb +22 -0
- data/lib/browser/edge.rb +2 -2
- data/lib/browser/google_search_app.rb +21 -0
- data/lib/browser/huawei_browser.rb +21 -0
- data/lib/browser/maxthon.rb +21 -0
- data/lib/browser/meta.rb +0 -1
- data/lib/browser/meta/base.rb +0 -1
- data/lib/browser/miui_browser.rb +21 -0
- data/lib/browser/platform.rb +5 -5
- data/lib/browser/platform/base.rb +3 -2
- data/lib/browser/platform/ios.rb +1 -1
- data/lib/browser/platform/mac.rb +4 -2
- data/lib/browser/platform/{other.rb → unknown.rb} +3 -3
- data/lib/browser/platform/windows.rb +1 -1
- data/lib/browser/safari.rb +16 -1
- data/lib/browser/samsung_browser.rb +21 -0
- data/lib/browser/sougou_browser.rb +24 -0
- data/lib/browser/{generic.rb → unknown.rb} +3 -3
- data/lib/browser/version.rb +1 -1
- data/test/browser_test.rb +23 -6
- data/test/test_helper.rb +8 -0
- data/test/ua.yml +17 -1
- data/test/ua_bots.yml +8 -2
- data/test/unit/adobe_air_test.rb +1 -1
- data/test/unit/alipay_test.rb +6 -0
- data/test/unit/console_test.rb +2 -2
- data/test/unit/device_test.rb +2 -2
- data/test/unit/duck_duck_go_test.rb +37 -0
- data/test/unit/edge_test.rb +34 -2
- data/test/unit/google_search_app_test.rb +54 -0
- data/test/unit/huawei_browser_test.rb +25 -0
- data/test/unit/maxthon_test.rb +25 -0
- data/test/unit/meta_test.rb +9 -0
- data/test/unit/micro_messenger_test.rb +21 -6
- data/test/unit/miui_browser_test.rb +25 -0
- data/test/unit/opera_test.rb +1 -0
- data/test/unit/platform_test.rb +12 -7
- data/test/unit/qq_test.rb +12 -0
- data/test/unit/safari_test.rb +12 -7
- data/test/unit/samsung_browser_test.rb +23 -0
- data/test/unit/sougou_browser_test.rb +41 -0
- metadata +33 -10
- data/lib/browser/meta/modern.rb +0 -11
data/browser.gemspec
CHANGED
@@ -8,11 +8,13 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Nando Vieira"]
|
10
10
|
s.email = ["fnando.vieira@gmail.com"]
|
11
|
-
s.homepage = "
|
11
|
+
s.homepage = "https://github.com/fnando/browser"
|
12
12
|
s.summary = "Do some browser detection with Ruby."
|
13
13
|
s.description = s.summary
|
14
14
|
s.license = "MIT"
|
15
15
|
|
16
|
+
s.metadata["changelog_uri"] = "https://github.com/fnando/browser/blob/master/CHANGELOG.md"
|
17
|
+
|
16
18
|
s.files = `git ls-files`.split("\n")
|
17
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
20
|
s.executables = `git ls-files -- exe/*`
|
data/lib/browser/base.rb
CHANGED
@@ -10,6 +10,9 @@ module Browser
|
|
10
10
|
attr_reader :accept_language
|
11
11
|
|
12
12
|
def initialize(ua, accept_language: nil)
|
13
|
+
validate_size(:user_agent, ua.to_s)
|
14
|
+
validate_size(:accept_language, accept_language.to_s)
|
15
|
+
|
13
16
|
@ua = ua
|
14
17
|
@accept_language = AcceptLanguage.parse(accept_language)
|
15
18
|
end
|
@@ -50,11 +53,6 @@ module Browser
|
|
50
53
|
@device ||= Device.new(ua)
|
51
54
|
end
|
52
55
|
|
53
|
-
# Return true if browser is modern (Webkit, Firefox 17+, IE9+, Opera 12+).
|
54
|
-
def modern?
|
55
|
-
Browser.modern_rules.any? {|rule| rule === self } # rubocop:disable Style/CaseEquality
|
56
|
-
end
|
57
|
-
|
58
56
|
# Detect if browser is Microsoft Internet Explorer.
|
59
57
|
def ie?(expected_version = nil)
|
60
58
|
InternetExplorer.new(ua).match? &&
|
@@ -127,7 +125,7 @@ module Browser
|
|
127
125
|
|
128
126
|
# Detect if browser is Safari.
|
129
127
|
def safari?(expected_version = nil)
|
130
|
-
Safari.new(ua).match? && detect_version?(
|
128
|
+
Safari.new(ua).match? && detect_version?(full_version, expected_version)
|
131
129
|
end
|
132
130
|
|
133
131
|
def safari_webapp_mode?
|
@@ -192,12 +190,59 @@ module Browser
|
|
192
190
|
ua =~ /Opera Mini/ && detect_version?(full_version, expected_version)
|
193
191
|
end
|
194
192
|
|
193
|
+
# Detect if browser is DuckDuckGo.
|
194
|
+
def duck_duck_go?(expected_version = nil)
|
195
|
+
ua =~ /DuckDuckGo/ && detect_version?(full_version, expected_version)
|
196
|
+
end
|
197
|
+
|
198
|
+
# Detect if browser is Samsung.
|
199
|
+
def samsung_browser?(expected_version = nil)
|
200
|
+
ua =~ /SamsungBrowser/ && detect_version?(full_version, expected_version)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Detect if browser is Huawei.
|
204
|
+
def huawei_browser?(expected_version = nil)
|
205
|
+
HuaweiBrowser.new(ua).match? &&
|
206
|
+
detect_version?(full_version, expected_version)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Detect if browser is Xiaomi Miui.
|
210
|
+
def miui_browser?(expected_version = nil)
|
211
|
+
MiuiBrowser.new(ua).match? &&
|
212
|
+
detect_version?(full_version, expected_version)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Detect if browser is Maxthon.
|
216
|
+
def maxthon?(expected_version = nil)
|
217
|
+
Maxthon.new(ua).match? && detect_version?(full_version, expected_version)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Detect if browser is QQ.
|
221
|
+
def qq?(expected_version = nil)
|
222
|
+
QQ.new(ua).match? && detect_version?(full_version, expected_version)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Detect if browser is Sougou.
|
226
|
+
def sougou_browser?(expected_version = nil)
|
227
|
+
SougouBrowser.new(ua).match? &&
|
228
|
+
detect_version?(full_version, expected_version)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Detect if browser is Google Search App
|
232
|
+
def google_search_app?(expected_version = nil)
|
233
|
+
ua =~ /GSA/ && detect_version?(full_version, expected_version)
|
234
|
+
end
|
235
|
+
|
195
236
|
def webkit_full_version
|
196
237
|
ua[%r{AppleWebKit/([\d.]+)}, 1] || "0.0"
|
197
238
|
end
|
198
239
|
|
199
240
|
def known?
|
200
|
-
|
241
|
+
!unknown?
|
242
|
+
end
|
243
|
+
|
244
|
+
def unknown?
|
245
|
+
id == :unknown_browser
|
201
246
|
end
|
202
247
|
|
203
248
|
# Detect if browser is a proxy browser.
|
@@ -209,5 +254,16 @@ module Browser
|
|
209
254
|
def electron?(expected_version = nil)
|
210
255
|
Electron.new(ua).match? && detect_version?(full_version, expected_version)
|
211
256
|
end
|
257
|
+
|
258
|
+
private def validate_size(subject, input)
|
259
|
+
actual_bytesize = input.bytesize
|
260
|
+
size_limit = Browser.public_send("#{subject}_size_limit")
|
261
|
+
|
262
|
+
return if actual_bytesize < size_limit
|
263
|
+
|
264
|
+
raise Error,
|
265
|
+
"#{subject} cannot be larger than #{size_limit} bytes; " \
|
266
|
+
"actual size is #{actual_bytesize}"
|
267
|
+
end
|
212
268
|
end
|
213
269
|
end
|
data/lib/browser/browser.rb
CHANGED
@@ -15,7 +15,7 @@ require_relative "firefox"
|
|
15
15
|
require_relative "edge"
|
16
16
|
require_relative "opera"
|
17
17
|
require_relative "blackberry"
|
18
|
-
require_relative "
|
18
|
+
require_relative "unknown"
|
19
19
|
require_relative "phantom_js"
|
20
20
|
require_relative "uc_browser"
|
21
21
|
require_relative "nokia"
|
@@ -30,6 +30,13 @@ require_relative "instagram"
|
|
30
30
|
require_relative "yandex"
|
31
31
|
require_relative "sputnik"
|
32
32
|
require_relative "snapchat"
|
33
|
+
require_relative "duck_duck_go"
|
34
|
+
require_relative "samsung_browser"
|
35
|
+
require_relative "huawei_browser"
|
36
|
+
require_relative "miui_browser"
|
37
|
+
require_relative "maxthon"
|
38
|
+
require_relative "sougou_browser"
|
39
|
+
require_relative "google_search_app"
|
33
40
|
|
34
41
|
require_relative "bot"
|
35
42
|
require_relative "bot/empty_user_agent_matcher"
|
@@ -44,10 +51,20 @@ require_relative "meta"
|
|
44
51
|
module Browser
|
45
52
|
EMPTY_STRING = ""
|
46
53
|
|
54
|
+
Error = Class.new(StandardError)
|
55
|
+
|
47
56
|
def self.root
|
48
57
|
@root ||= Pathname.new(File.expand_path("../..", __dir__))
|
49
58
|
end
|
50
59
|
|
60
|
+
class << self
|
61
|
+
attr_accessor :user_agent_size_limit
|
62
|
+
attr_accessor :accept_language_size_limit
|
63
|
+
end
|
64
|
+
|
65
|
+
self.user_agent_size_limit = 512
|
66
|
+
self.accept_language_size_limit = 256
|
67
|
+
|
51
68
|
# Hold the list of browser matchers.
|
52
69
|
# Order is important.
|
53
70
|
def self.matchers
|
@@ -65,41 +82,25 @@ module Browser
|
|
65
82
|
Instagram, # must be placed before Chrome and Safari
|
66
83
|
Snapchat, # must be placed before Chrome and Safari
|
67
84
|
Weibo, # must be placed before Chrome and Safari
|
85
|
+
MicroMessenger, # must be placed before QQ
|
68
86
|
QQ, # must be placed before Chrome and Safari
|
69
87
|
Alipay, # must be placed before Chrome and Safari
|
70
88
|
Electron, # must be placed before Chrome and Safari
|
71
89
|
Yandex, # must be placed before Chrome and Safari
|
72
90
|
Sputnik, # must be placed before Chrome and Safari
|
91
|
+
DuckDuckGo, # must be placed before Chrome and Safari
|
92
|
+
SamsungBrowser, # must be placed before Chrome and Safari
|
93
|
+
HuaweiBrowser, # must be placed before Chrome and Safari
|
94
|
+
MiuiBrowser, # must be placed before Chrome and Safari
|
95
|
+
Maxthon, # must be placed before Chrome and Safari
|
96
|
+
SougouBrowser, # must be placed before Chrome and Safari
|
97
|
+
GoogleSearchApp, # must be placed before Chrome and Safari
|
73
98
|
Chrome,
|
74
99
|
Safari,
|
75
|
-
|
76
|
-
Generic
|
100
|
+
Unknown
|
77
101
|
]
|
78
102
|
end
|
79
103
|
|
80
|
-
# Define the rules which define a modern browser.
|
81
|
-
# A rule must be a proc/lambda or any object that implements the method
|
82
|
-
# === and accepts the browser object.
|
83
|
-
#
|
84
|
-
# To redefine all rules, clear the existing rules before adding your own.
|
85
|
-
#
|
86
|
-
# # Only Chrome Canary is considered modern.
|
87
|
-
# Browser.modern_rules.clear
|
88
|
-
# Browser.modern_rules << -> b { b.chrome? && b.version >= "37" }
|
89
|
-
#
|
90
|
-
def self.modern_rules
|
91
|
-
@modern_rules ||= []
|
92
|
-
end
|
93
|
-
|
94
|
-
modern_rules.tap do |rules|
|
95
|
-
rules << ->(b) { b.chrome? && b.version.to_i >= 65 }
|
96
|
-
rules << ->(b) { b.safari? && b.version.to_i >= 10 }
|
97
|
-
rules << ->(b) { b.firefox? && b.version.to_i >= 52 }
|
98
|
-
rules << ->(b) { b.ie? && b.version.to_i >= 11 && !b.compatibility_view? }
|
99
|
-
rules << ->(b) { b.edge? && b.version.to_i >= 15 }
|
100
|
-
rules << ->(b) { b.opera? && b.version.to_i >= 50 }
|
101
|
-
end
|
102
|
-
|
103
104
|
def self.new(user_agent, **kwargs)
|
104
105
|
matchers
|
105
106
|
.map {|klass| klass.new(user_agent || EMPTY_STRING, **kwargs) }
|
data/lib/browser/chrome.rb
CHANGED
@@ -21,9 +21,19 @@ module Browser
|
|
21
21
|
|
22
22
|
def match?
|
23
23
|
ua =~ /Chrome|CriOS/ &&
|
24
|
-
ua !~ /PhantomJS|FxiOS|
|
24
|
+
ua !~ /PhantomJS|FxiOS|ArchiveBot/ &&
|
25
25
|
!opera? &&
|
26
|
-
!edge?
|
26
|
+
!edge? &&
|
27
|
+
!duck_duck_go? &&
|
28
|
+
!yandex? &&
|
29
|
+
!sputnik? &&
|
30
|
+
!samsung_browser? &&
|
31
|
+
!huawei_browser? &&
|
32
|
+
!miui_browser? &&
|
33
|
+
!maxthon? &&
|
34
|
+
!qq? &&
|
35
|
+
!sougou_browser? &&
|
36
|
+
!google_search_app?
|
27
37
|
end
|
28
38
|
end
|
29
39
|
end
|
data/lib/browser/device.rb
CHANGED
@@ -88,7 +88,7 @@ module Browser
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def unknown?
|
91
|
-
id == :
|
91
|
+
id == :unknown_device
|
92
92
|
end
|
93
93
|
|
94
94
|
def ipod_touch?
|
@@ -197,7 +197,7 @@ module Browser
|
|
197
197
|
psp? ||
|
198
198
|
/zunewp7/i.match(ua) ||
|
199
199
|
%r{(android|bb\d+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino}i.match(ua) ||
|
200
|
-
%r{1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s
|
200
|
+
%r{1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-}i.match(ua[0..3])
|
201
201
|
end
|
202
202
|
# rubocop:enable Layout/LineLength
|
203
203
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Browser
|
4
|
+
class DuckDuckGo < Base
|
5
|
+
def id
|
6
|
+
:duckduckgo
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
"DuckDuckGo"
|
11
|
+
end
|
12
|
+
|
13
|
+
def full_version
|
14
|
+
ua[%r{DuckDuckGo/([\d.]+)}, 1] ||
|
15
|
+
"0.0"
|
16
|
+
end
|
17
|
+
|
18
|
+
def match?
|
19
|
+
ua =~ /DuckDuckGo/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/browser/edge.rb
CHANGED
@@ -11,11 +11,11 @@ module Browser
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def full_version
|
14
|
-
ua[%r{(?:Edge|Edg)/([\d.]+)}, 1] || super
|
14
|
+
ua[%r{(?:Edge|Edg|EdgiOS|EdgA)/([\d.]+)}, 1] || super
|
15
15
|
end
|
16
16
|
|
17
17
|
def match?
|
18
|
-
ua =~ %r{((?:Edge|Edg)/[\d.]+|Trident/8)}
|
18
|
+
ua =~ %r{((?:Edge|Edg|EdgiOS|EdgA)/[\d.]+|Trident/8)}
|
19
19
|
end
|
20
20
|
|
21
21
|
def chrome_based?
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Browser
|
4
|
+
class GoogleSearchApp < Chrome
|
5
|
+
def id
|
6
|
+
:google_search_app
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
"Google Search App"
|
11
|
+
end
|
12
|
+
|
13
|
+
def full_version
|
14
|
+
ua[%r{GSA/([\d.]+\d)}, 1] || super
|
15
|
+
end
|
16
|
+
|
17
|
+
def match?
|
18
|
+
ua =~ /GSA/
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Browser
|
4
|
+
class HuaweiBrowser < Base
|
5
|
+
def id
|
6
|
+
:huawei_browser
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
"Huawei Browser"
|
11
|
+
end
|
12
|
+
|
13
|
+
def full_version
|
14
|
+
ua[%r{(?:HuaweiBrowser)/([\d.]+)}i, 1] || "0.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
def match?
|
18
|
+
ua =~ /HuaweiBrowser/i
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Browser
|
4
|
+
class Maxthon < Base
|
5
|
+
def id
|
6
|
+
:maxthon
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
"Maxthon"
|
11
|
+
end
|
12
|
+
|
13
|
+
def full_version
|
14
|
+
ua[%r{(?:Maxthon)/([\d.]+)}i, 1] || "0.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
def match?
|
18
|
+
ua =~ /Maxthon/i
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/browser/meta.rb
CHANGED
data/lib/browser/meta/base.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Browser
|
4
|
+
class MiuiBrowser < Base
|
5
|
+
def id
|
6
|
+
:miui_browser
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
"Miui Browser"
|
11
|
+
end
|
12
|
+
|
13
|
+
def full_version
|
14
|
+
ua[%r{MiuiBrowser/([\d.]+)}, 1] || "0.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
def match?
|
18
|
+
ua =~ /MiuiBrowser/
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/browser/platform.rb
CHANGED
@@ -10,7 +10,7 @@ require_relative "platform/windows_mobile"
|
|
10
10
|
require_relative "platform/firefox_os"
|
11
11
|
require_relative "platform/blackberry"
|
12
12
|
require_relative "platform/android"
|
13
|
-
require_relative "platform/
|
13
|
+
require_relative "platform/unknown"
|
14
14
|
require_relative "platform/chrome_os"
|
15
15
|
require_relative "platform/adobe_air"
|
16
16
|
|
@@ -35,7 +35,7 @@ module Browser
|
|
35
35
|
FirefoxOS,
|
36
36
|
Windows,
|
37
37
|
Linux,
|
38
|
-
|
38
|
+
Unknown
|
39
39
|
]
|
40
40
|
end
|
41
41
|
|
@@ -45,7 +45,7 @@ module Browser
|
|
45
45
|
|
46
46
|
def subject
|
47
47
|
@subject ||= self.class.matchers
|
48
|
-
.map {|matcher| matcher.new(ua) }
|
48
|
+
.map {|matcher| matcher.new(ua, self) }
|
49
49
|
.find(&:match?)
|
50
50
|
end
|
51
51
|
|
@@ -61,8 +61,8 @@ module Browser
|
|
61
61
|
id == :android && detect_version?(version, expected_version)
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
65
|
-
id == :
|
64
|
+
def unknown?
|
65
|
+
id == :unknown_platform
|
66
66
|
end
|
67
67
|
|
68
68
|
def linux?
|