browser 2.7.1 → 5.3.1
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/.github/workflows/tests.yml +57 -0
- data/.gitignore +1 -0
- data/.prettierignore +1 -0
- data/.rubocop.yml +13 -1
- data/CHANGELOG.md +122 -13
- data/FUNDING.yml +3 -0
- data/README.md +134 -88
- data/Rakefile +8 -1
- data/bot_exceptions.yml +1 -0
- data/bots.yml +300 -293
- data/browser.gemspec +4 -1
- data/gemfiles/{rails5.gemfile → rails6_1.gemfile} +1 -1
- data/lib/browser/accept_language.rb +4 -4
- data/lib/browser/aliases.rb +1 -1
- data/lib/browser/alipay.rb +1 -1
- data/lib/browser/base.rb +82 -18
- data/lib/browser/blackberry.rb +1 -1
- data/lib/browser/bot/empty_user_agent_matcher.rb +11 -0
- data/lib/browser/bot/keyword_matcher.rb +11 -0
- data/lib/browser/bot/known_bots_matcher.rb +11 -0
- data/lib/browser/bot.rb +34 -26
- data/lib/browser/browser.rb +59 -56
- data/lib/browser/chrome.rb +13 -3
- data/lib/browser/device/android.rb +1 -1
- data/lib/browser/device/blackberry_playbook.rb +1 -1
- data/lib/browser/device/ipad.rb +1 -1
- data/lib/browser/device/iphone.rb +1 -1
- data/lib/browser/device/ipod_touch.rb +1 -1
- data/lib/browser/device/kindle.rb +1 -1
- data/lib/browser/device/kindle_fire.rb +1 -1
- data/lib/browser/device/playstation3.rb +1 -1
- data/lib/browser/device/playstation4.rb +1 -1
- data/lib/browser/device/psp.rb +1 -1
- data/lib/browser/device/psvita.rb +1 -1
- data/lib/browser/device/samsung.rb +33 -0
- data/lib/browser/device/surface.rb +1 -1
- data/lib/browser/device/switch.rb +1 -1
- data/lib/browser/device/tv.rb +1 -1
- data/lib/browser/device/unknown.rb +1 -1
- data/lib/browser/device/wii.rb +1 -1
- data/lib/browser/device/wiiu.rb +1 -1
- data/lib/browser/device/xbox_360.rb +1 -1
- data/lib/browser/device/xbox_one.rb +1 -1
- data/lib/browser/device.rb +37 -27
- data/lib/browser/duck_duck_go.rb +22 -0
- data/lib/browser/edge.rb +3 -3
- data/lib/browser/electron.rb +1 -1
- data/lib/browser/facebook.rb +1 -1
- data/lib/browser/firefox.rb +1 -1
- data/lib/browser/google_search_app.rb +21 -0
- data/lib/browser/huawei_browser.rb +21 -0
- data/lib/browser/instagram.rb +1 -1
- data/lib/browser/internet_explorer.rb +2 -2
- data/lib/browser/maxthon.rb +21 -0
- data/lib/browser/meta/base.rb +0 -1
- data/lib/browser/meta.rb +12 -13
- data/lib/browser/micro_messenger.rb +1 -1
- data/lib/browser/middleware/context/additions.rb +1 -1
- data/lib/browser/middleware.rb +1 -1
- data/lib/browser/miui_browser.rb +21 -0
- data/lib/browser/nokia.rb +1 -1
- data/lib/browser/opera.rb +1 -1
- data/lib/browser/otter.rb +1 -1
- data/lib/browser/phantom_js.rb +1 -1
- data/lib/browser/platform/adobe_air.rb +1 -1
- data/lib/browser/platform/android.rb +1 -1
- data/lib/browser/platform/base.rb +3 -2
- data/lib/browser/platform/blackberry.rb +1 -1
- data/lib/browser/platform/chrome_os.rb +1 -1
- data/lib/browser/platform/firefox_os.rb +1 -1
- data/lib/browser/platform/ios.rb +2 -2
- data/lib/browser/platform/kai_os.rb +23 -0
- data/lib/browser/platform/linux.rb +1 -1
- data/lib/browser/platform/mac.rb +5 -3
- data/lib/browser/platform/{other.rb → unknown.rb} +3 -3
- data/lib/browser/platform/windows.rb +2 -2
- data/lib/browser/platform/windows_mobile.rb +1 -1
- data/lib/browser/platform/windows_phone.rb +1 -1
- data/lib/browser/platform.rb +37 -28
- data/lib/browser/qq.rb +1 -1
- data/lib/browser/rails.rb +3 -3
- data/lib/browser/safari.rb +16 -1
- data/lib/browser/samsung_browser.rb +21 -0
- data/lib/browser/snapchat.rb +1 -1
- data/lib/browser/sougou_browser.rb +24 -0
- data/lib/browser/sputnik.rb +2 -5
- data/lib/browser/uc_browser.rb +1 -1
- data/lib/browser/{generic.rb → unknown.rb} +3 -3
- data/lib/browser/version.rb +1 -1
- data/lib/browser/weibo.rb +1 -1
- data/lib/browser/yandex.rb +1 -1
- data/lib/browser.rb +2 -2
- data/samsung.yml +138 -0
- data/test/browser_test.rb +37 -10
- data/test/test_helper.rb +8 -0
- data/test/ua.yml +26 -3
- data/test/ua_bots.yml +9 -2
- data/test/ua_search_engines.yml +1 -0
- data/test/unit/accept_language_test.rb +6 -0
- data/test/unit/adobe_air_test.rb +1 -1
- data/test/unit/alipay_test.rb +6 -0
- data/test/unit/blackberry_test.rb +0 -6
- data/test/unit/bots_test.rb +26 -39
- data/test/unit/chrome_test.rb +8 -3
- data/test/unit/console_test.rb +2 -2
- data/test/unit/device_test.rb +30 -3
- data/test/unit/duck_duck_go_test.rb +37 -0
- data/test/unit/edge_test.rb +34 -6
- data/test/unit/firefox_test.rb +0 -3
- data/test/unit/google_search_app_test.rb +54 -0
- data/test/unit/huawei_browser_test.rb +25 -0
- data/test/unit/internet_explorer_test.rb +0 -12
- data/test/unit/ios_test.rb +0 -5
- data/test/unit/kai_os_test.rb +31 -0
- data/test/unit/kindle_test.rb +0 -2
- data/test/unit/maxthon_test.rb +25 -0
- data/test/unit/meta_test.rb +10 -2
- 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 -2
- data/test/unit/platform_test.rb +13 -8
- 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
- data/test/unit/sputnik_test.rb +1 -0
- metadata +46 -16
- data/.bundle/config +0 -2
- data/.travis.yml +0 -23
- data/lib/browser/meta/modern.rb +0 -11
- /data/gemfiles/{rails6.gemfile → rails6_0.gemfile} +0 -0
data/lib/browser/aliases.rb
CHANGED
data/lib/browser/alipay.rb
CHANGED
data/lib/browser/base.rb
CHANGED
|
@@ -6,12 +6,11 @@ module Browser
|
|
|
6
6
|
|
|
7
7
|
attr_reader :ua
|
|
8
8
|
|
|
9
|
-
# Return an array with all preferred languages that this browser accepts.
|
|
10
|
-
attr_reader :accept_language
|
|
11
|
-
|
|
12
9
|
def initialize(ua, accept_language: nil)
|
|
10
|
+
validate_size(:user_agent, ua.to_s)
|
|
11
|
+
|
|
13
12
|
@ua = ua
|
|
14
|
-
@
|
|
13
|
+
@accept_language_raw = accept_language.to_s
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
# Return a meta info about this browser.
|
|
@@ -19,6 +18,14 @@ module Browser
|
|
|
19
18
|
Meta.get(self)
|
|
20
19
|
end
|
|
21
20
|
|
|
21
|
+
# Return an array with all preferred languages that this browser accepts.
|
|
22
|
+
def accept_language
|
|
23
|
+
@accept_language ||= begin
|
|
24
|
+
validate_size(:accept_language, @accept_language_raw)
|
|
25
|
+
AcceptLanguage.parse(@accept_language_raw)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
22
29
|
alias_method :to_a, :meta
|
|
23
30
|
|
|
24
31
|
# Return meta representation as string.
|
|
@@ -50,11 +57,6 @@ module Browser
|
|
|
50
57
|
@device ||= Device.new(ua)
|
|
51
58
|
end
|
|
52
59
|
|
|
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
60
|
# Detect if browser is Microsoft Internet Explorer.
|
|
59
61
|
def ie?(expected_version = nil)
|
|
60
62
|
InternetExplorer.new(ua).match? &&
|
|
@@ -104,19 +106,20 @@ module Browser
|
|
|
104
106
|
|
|
105
107
|
# Detect if browser is WebKit-based.
|
|
106
108
|
def webkit?(expected_version = nil)
|
|
107
|
-
ua
|
|
109
|
+
ua.match?(/AppleWebKit/i) &&
|
|
108
110
|
(!edge? || Edge.new(ua).chrome_based?) &&
|
|
109
111
|
detect_version?(webkit_full_version, expected_version)
|
|
110
112
|
end
|
|
111
113
|
|
|
112
114
|
# Detect if browser is QuickTime
|
|
113
115
|
def quicktime?(expected_version = nil)
|
|
114
|
-
ua
|
|
116
|
+
ua.match?(/QuickTime/i) && detect_version?(full_version, expected_version)
|
|
115
117
|
end
|
|
116
118
|
|
|
117
119
|
# Detect if browser is Apple CoreMedia.
|
|
118
120
|
def core_media?(expected_version = nil)
|
|
119
|
-
ua
|
|
121
|
+
ua.include?("CoreMedia") && detect_version?(full_version,
|
|
122
|
+
expected_version)
|
|
120
123
|
end
|
|
121
124
|
|
|
122
125
|
# Detect if browser is PhantomJS
|
|
@@ -127,11 +130,11 @@ module Browser
|
|
|
127
130
|
|
|
128
131
|
# Detect if browser is Safari.
|
|
129
132
|
def safari?(expected_version = nil)
|
|
130
|
-
Safari.new(ua).match? && detect_version?(
|
|
133
|
+
Safari.new(ua).match? && detect_version?(full_version, expected_version)
|
|
131
134
|
end
|
|
132
135
|
|
|
133
136
|
def safari_webapp_mode?
|
|
134
|
-
(device.ipad? || device.iphone?) && ua
|
|
137
|
+
(device.ipad? || device.iphone?) && ua.include?("AppleWebKit")
|
|
135
138
|
end
|
|
136
139
|
|
|
137
140
|
# Detect if browser is Firefox.
|
|
@@ -151,12 +154,12 @@ module Browser
|
|
|
151
154
|
|
|
152
155
|
# Detect if browser is Sputnik.
|
|
153
156
|
def sputnik?(expected_version = nil)
|
|
154
|
-
Sputnik.new(ua) && detect_version?(full_version, expected_version)
|
|
157
|
+
Sputnik.new(ua).match? && detect_version?(full_version, expected_version)
|
|
155
158
|
end
|
|
156
159
|
|
|
157
160
|
# Detect if browser is Yandex.
|
|
158
161
|
def yandex?(expected_version = nil)
|
|
159
|
-
Yandex.new(ua) && detect_version?(full_version, expected_version)
|
|
162
|
+
Yandex.new(ua).match? && detect_version?(full_version, expected_version)
|
|
160
163
|
end
|
|
161
164
|
alias_method :yandex_browser?, :yandex?
|
|
162
165
|
|
|
@@ -189,7 +192,53 @@ module Browser
|
|
|
189
192
|
|
|
190
193
|
# Detect if browser is Opera Mini.
|
|
191
194
|
def opera_mini?(expected_version = nil)
|
|
192
|
-
ua
|
|
195
|
+
ua.include?("Opera Mini") && detect_version?(full_version,
|
|
196
|
+
expected_version)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Detect if browser is DuckDuckGo.
|
|
200
|
+
def duck_duck_go?(expected_version = nil)
|
|
201
|
+
ua.include?("DuckDuckGo") && detect_version?(full_version,
|
|
202
|
+
expected_version)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Detect if browser is Samsung.
|
|
206
|
+
def samsung_browser?(expected_version = nil)
|
|
207
|
+
ua.include?("SamsungBrowser") && detect_version?(full_version,
|
|
208
|
+
expected_version)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Detect if browser is Huawei.
|
|
212
|
+
def huawei_browser?(expected_version = nil)
|
|
213
|
+
HuaweiBrowser.new(ua).match? &&
|
|
214
|
+
detect_version?(full_version, expected_version)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Detect if browser is Xiaomi Miui.
|
|
218
|
+
def miui_browser?(expected_version = nil)
|
|
219
|
+
MiuiBrowser.new(ua).match? &&
|
|
220
|
+
detect_version?(full_version, expected_version)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Detect if browser is Maxthon.
|
|
224
|
+
def maxthon?(expected_version = nil)
|
|
225
|
+
Maxthon.new(ua).match? && detect_version?(full_version, expected_version)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Detect if browser is QQ.
|
|
229
|
+
def qq?(expected_version = nil)
|
|
230
|
+
QQ.new(ua).match? && detect_version?(full_version, expected_version)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Detect if browser is Sougou.
|
|
234
|
+
def sougou_browser?(expected_version = nil)
|
|
235
|
+
SougouBrowser.new(ua).match? &&
|
|
236
|
+
detect_version?(full_version, expected_version)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Detect if browser is Google Search App
|
|
240
|
+
def google_search_app?(expected_version = nil)
|
|
241
|
+
ua.include?("GSA") && detect_version?(full_version, expected_version)
|
|
193
242
|
end
|
|
194
243
|
|
|
195
244
|
def webkit_full_version
|
|
@@ -197,7 +246,11 @@ module Browser
|
|
|
197
246
|
end
|
|
198
247
|
|
|
199
248
|
def known?
|
|
200
|
-
|
|
249
|
+
!unknown?
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def unknown?
|
|
253
|
+
id == :unknown_browser
|
|
201
254
|
end
|
|
202
255
|
|
|
203
256
|
# Detect if browser is a proxy browser.
|
|
@@ -209,5 +262,16 @@ module Browser
|
|
|
209
262
|
def electron?(expected_version = nil)
|
|
210
263
|
Electron.new(ua).match? && detect_version?(full_version, expected_version)
|
|
211
264
|
end
|
|
265
|
+
|
|
266
|
+
private def validate_size(subject, input)
|
|
267
|
+
actual_bytesize = input.bytesize
|
|
268
|
+
size_limit = Browser.public_send("#{subject}_size_limit")
|
|
269
|
+
|
|
270
|
+
return if actual_bytesize < size_limit
|
|
271
|
+
|
|
272
|
+
raise Error,
|
|
273
|
+
"#{subject} cannot be larger than #{size_limit} bytes; " \
|
|
274
|
+
"actual size is #{actual_bytesize} bytes"
|
|
275
|
+
end
|
|
212
276
|
end
|
|
213
277
|
end
|
data/lib/browser/blackberry.rb
CHANGED
data/lib/browser/bot.rb
CHANGED
|
@@ -2,68 +2,76 @@
|
|
|
2
2
|
|
|
3
3
|
module Browser
|
|
4
4
|
class Bot
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
GENERIC_NAME = "Generic Bot"
|
|
6
|
+
|
|
7
|
+
def self.matchers
|
|
8
|
+
@matchers ||= default_matchers
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.default_matchers
|
|
12
|
+
[
|
|
13
|
+
EmptyUserAgentMatcher,
|
|
14
|
+
KnownBotsMatcher,
|
|
15
|
+
KeywordMatcher
|
|
16
|
+
]
|
|
7
17
|
end
|
|
8
18
|
|
|
9
|
-
def self.
|
|
10
|
-
|
|
19
|
+
def self.load_yaml(path)
|
|
20
|
+
YAML.load_file(Browser.root.join(path))
|
|
11
21
|
end
|
|
12
22
|
|
|
13
23
|
def self.bots
|
|
14
|
-
@bots ||=
|
|
24
|
+
@bots ||= load_yaml("bots.yml")
|
|
15
25
|
end
|
|
16
26
|
|
|
17
27
|
def self.bot_exceptions
|
|
18
|
-
@bot_exceptions ||=
|
|
19
|
-
.load_file(Browser.root.join("bot_exceptions.yml"))
|
|
28
|
+
@bot_exceptions ||= load_yaml("bot_exceptions.yml")
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
def self.search_engines
|
|
23
|
-
@search_engines ||=
|
|
24
|
-
.load_file(Browser.root.join("search_engines.yml"))
|
|
32
|
+
@search_engines ||= load_yaml("search_engines.yml")
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
def self.why?(ua)
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
ua = ua.downcase.strip
|
|
37
|
+
browser = Browser.new(ua)
|
|
38
|
+
matchers.find {|matcher| matcher.call(ua, browser) }
|
|
30
39
|
end
|
|
31
40
|
|
|
32
|
-
attr_reader :ua
|
|
41
|
+
attr_reader :ua, :browser
|
|
33
42
|
|
|
34
43
|
def initialize(ua)
|
|
35
|
-
@ua = ua
|
|
44
|
+
@ua = ua.downcase.strip
|
|
45
|
+
@browser = Browser.new(@ua)
|
|
36
46
|
end
|
|
37
47
|
|
|
38
48
|
def bot?
|
|
39
|
-
|
|
49
|
+
!bot_exception? && detect_bot?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def why?
|
|
53
|
+
self.class.matchers.find {|matcher| matcher.call(ua, self) }
|
|
40
54
|
end
|
|
41
55
|
|
|
42
56
|
def search_engine?
|
|
43
|
-
self.class.search_engines.any? {|key, _|
|
|
57
|
+
self.class.search_engines.any? {|key, _| ua.include?(key) }
|
|
44
58
|
end
|
|
45
59
|
|
|
46
60
|
def name
|
|
47
61
|
return unless bot?
|
|
48
|
-
return "Generic Bot" if bot_with_empty_ua?
|
|
49
|
-
|
|
50
|
-
self.class.bots.find {|key, _| downcased_ua.include?(key) }.last
|
|
51
|
-
end
|
|
52
62
|
|
|
53
|
-
|
|
54
|
-
self.class.detect_empty_ua? && ua.strip == ""
|
|
63
|
+
self.class.bots.find {|key, _| ua.include?(key) }&.last || GENERIC_NAME
|
|
55
64
|
end
|
|
56
65
|
|
|
57
66
|
private def bot_exception?
|
|
58
|
-
self.class.bot_exceptions.any? {|key|
|
|
67
|
+
self.class.bot_exceptions.any? {|key| ua.include?(key) }
|
|
59
68
|
end
|
|
60
69
|
|
|
61
70
|
private def detect_bot?
|
|
62
|
-
self.class.
|
|
71
|
+
self.class.matchers.any? {|matcher| matcher.call(ua, browser) }
|
|
63
72
|
end
|
|
64
73
|
|
|
65
|
-
private
|
|
66
|
-
|
|
67
|
-
end
|
|
74
|
+
private :ua
|
|
75
|
+
private :browser
|
|
68
76
|
end
|
|
69
77
|
end
|
data/lib/browser/browser.rb
CHANGED
|
@@ -4,47 +4,66 @@ require "set"
|
|
|
4
4
|
require "yaml"
|
|
5
5
|
require "pathname"
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
require_relative "version"
|
|
8
|
+
require_relative "detect_version"
|
|
9
|
+
require_relative "accept_language"
|
|
10
|
+
require_relative "base"
|
|
11
|
+
require_relative "safari"
|
|
12
|
+
require_relative "chrome"
|
|
13
|
+
require_relative "internet_explorer"
|
|
14
|
+
require_relative "firefox"
|
|
15
|
+
require_relative "edge"
|
|
16
|
+
require_relative "opera"
|
|
17
|
+
require_relative "blackberry"
|
|
18
|
+
require_relative "unknown"
|
|
19
|
+
require_relative "phantom_js"
|
|
20
|
+
require_relative "uc_browser"
|
|
21
|
+
require_relative "nokia"
|
|
22
|
+
require_relative "micro_messenger"
|
|
23
|
+
require_relative "weibo"
|
|
24
|
+
require_relative "qq"
|
|
25
|
+
require_relative "alipay"
|
|
26
|
+
require_relative "electron"
|
|
27
|
+
require_relative "facebook"
|
|
28
|
+
require_relative "otter"
|
|
29
|
+
require_relative "instagram"
|
|
30
|
+
require_relative "yandex"
|
|
31
|
+
require_relative "sputnik"
|
|
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
|
-
|
|
35
|
-
|
|
41
|
+
require_relative "bot"
|
|
42
|
+
require_relative "bot/empty_user_agent_matcher"
|
|
43
|
+
require_relative "bot/keyword_matcher"
|
|
44
|
+
require_relative "bot/known_bots_matcher"
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
require_relative "middleware"
|
|
47
|
+
require_relative "platform"
|
|
48
|
+
require_relative "device"
|
|
49
|
+
require_relative "meta"
|
|
40
50
|
|
|
41
51
|
module Browser
|
|
42
52
|
EMPTY_STRING = ""
|
|
43
53
|
|
|
54
|
+
Error = Class.new(StandardError)
|
|
55
|
+
|
|
44
56
|
def self.root
|
|
45
57
|
@root ||= Pathname.new(File.expand_path("../..", __dir__))
|
|
46
58
|
end
|
|
47
59
|
|
|
60
|
+
class << self
|
|
61
|
+
attr_accessor :user_agent_size_limit, :accept_language_size_limit
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
self.user_agent_size_limit = 2048
|
|
65
|
+
self.accept_language_size_limit = 2048
|
|
66
|
+
|
|
48
67
|
# Hold the list of browser matchers.
|
|
49
68
|
# Order is important.
|
|
50
69
|
def self.matchers
|
|
@@ -62,41 +81,25 @@ module Browser
|
|
|
62
81
|
Instagram, # must be placed before Chrome and Safari
|
|
63
82
|
Snapchat, # must be placed before Chrome and Safari
|
|
64
83
|
Weibo, # must be placed before Chrome and Safari
|
|
84
|
+
MicroMessenger, # must be placed before QQ
|
|
65
85
|
QQ, # must be placed before Chrome and Safari
|
|
66
86
|
Alipay, # must be placed before Chrome and Safari
|
|
67
87
|
Electron, # must be placed before Chrome and Safari
|
|
68
88
|
Yandex, # must be placed before Chrome and Safari
|
|
69
89
|
Sputnik, # must be placed before Chrome and Safari
|
|
90
|
+
DuckDuckGo, # must be placed before Chrome and Safari
|
|
91
|
+
SamsungBrowser, # must be placed before Chrome and Safari
|
|
92
|
+
HuaweiBrowser, # must be placed before Chrome and Safari
|
|
93
|
+
MiuiBrowser, # must be placed before Chrome and Safari
|
|
94
|
+
Maxthon, # must be placed before Chrome and Safari
|
|
95
|
+
SougouBrowser, # must be placed before Chrome and Safari
|
|
96
|
+
GoogleSearchApp, # must be placed before Chrome and Safari
|
|
70
97
|
Chrome,
|
|
71
98
|
Safari,
|
|
72
|
-
|
|
73
|
-
Generic
|
|
99
|
+
Unknown
|
|
74
100
|
]
|
|
75
101
|
end
|
|
76
102
|
|
|
77
|
-
# Define the rules which define a modern browser.
|
|
78
|
-
# A rule must be a proc/lambda or any object that implements the method
|
|
79
|
-
# === and accepts the browser object.
|
|
80
|
-
#
|
|
81
|
-
# To redefine all rules, clear the existing rules before adding your own.
|
|
82
|
-
#
|
|
83
|
-
# # Only Chrome Canary is considered modern.
|
|
84
|
-
# Browser.modern_rules.clear
|
|
85
|
-
# Browser.modern_rules << -> b { b.chrome? && b.version >= "37" }
|
|
86
|
-
#
|
|
87
|
-
def self.modern_rules
|
|
88
|
-
@modern_rules ||= []
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
modern_rules.tap do |rules|
|
|
92
|
-
rules << ->(b) { b.webkit? }
|
|
93
|
-
rules << ->(b) { b.firefox? && b.version.to_i >= 17 }
|
|
94
|
-
rules << ->(b) { b.ie? && b.version.to_i >= 9 && !b.compatibility_view? }
|
|
95
|
-
rules << ->(b) { b.edge? && !b.compatibility_view? }
|
|
96
|
-
rules << ->(b) { b.opera? && b.version.to_i >= 12 }
|
|
97
|
-
rules << ->(b) { b.firefox? && b.device.tablet? && b.platform.android? && b.version.to_i >= 14 } # rubocop:disable Metrics/LineLength
|
|
98
|
-
end
|
|
99
|
-
|
|
100
103
|
def self.new(user_agent, **kwargs)
|
|
101
104
|
matchers
|
|
102
105
|
.map {|klass| klass.new(user_agent || EMPTY_STRING, **kwargs) }
|
data/lib/browser/chrome.rb
CHANGED
|
@@ -20,10 +20,20 @@ module Browser
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def match?
|
|
23
|
-
ua
|
|
24
|
-
ua
|
|
23
|
+
ua.match?(/Chrome|CriOS/) &&
|
|
24
|
+
!ua.match?(/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/ipad.rb
CHANGED
data/lib/browser/device/psp.rb
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Device
|
|
5
|
+
class Samsung < Base
|
|
6
|
+
REGEX = /\(Linux.*?; Android.*?; (SAMSUNG )?(SM-[A-Z0-9]+).*?\)/i.freeze
|
|
7
|
+
|
|
8
|
+
def self.names
|
|
9
|
+
@names ||= YAML.load_file(Browser.root.join("samsung.yml").to_s)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def id
|
|
13
|
+
:samsung
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def name
|
|
17
|
+
"Samsung #{self.class.names[code] || code}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def code
|
|
21
|
+
matches && matches[2]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def matches
|
|
25
|
+
@matches ||= ua.match(REGEX)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def match?
|
|
29
|
+
!!matches
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|