browser 4.1.0 → 5.3.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/workflows/tests.yml +57 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +46 -3
- data/FUNDING.yml +3 -0
- data/README.md +101 -50
- data/bots.yml +299 -298
- data/browser.gemspec +5 -4
- data/lib/browser/accept_language.rb +4 -4
- data/lib/browser/alipay.rb +1 -1
- data/lib/browser/base.rb +72 -13
- data/lib/browser/blackberry.rb +1 -1
- data/lib/browser/bot/keyword_matcher.rb +1 -1
- data/lib/browser/browser.rb +21 -2
- data/lib/browser/chrome.rb +9 -3
- data/lib/browser/device.rb +12 -5
- 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/duck_duck_go.rb +1 -1
- data/lib/browser/edge.rb +2 -2
- 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/micro_messenger.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.rb +21 -15
- data/lib/browser/platform/adobe_air.rb +1 -1
- data/lib/browser/platform/android.rb +1 -1
- 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 +2 -2
- 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/qq.rb +1 -1
- data/lib/browser/safari.rb +12 -3
- data/lib/browser/samsung_browser.rb +1 -1
- data/lib/browser/snapchat.rb +1 -1
- data/lib/browser/sougou_browser.rb +24 -0
- data/lib/browser/sputnik.rb +1 -1
- 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/samsung.yml +138 -0
- data/test/browser_test.rb +37 -6
- data/test/ua.yml +18 -4
- data/test/ua_bots.yml +3 -2
- data/test/unit/adobe_air_test.rb +1 -1
- data/test/unit/alipay_test.rb +6 -0
- data/test/unit/bots_test.rb +1 -1
- data/test/unit/console_test.rb +2 -2
- data/test/unit/device_test.rb +30 -3
- data/test/unit/duck_duck_go_test.rb +2 -0
- data/test/unit/google_search_app_test.rb +54 -0
- data/test/unit/huawei_browser_test.rb +25 -0
- data/test/unit/kai_os_test.rb +31 -0
- data/test/unit/maxthon_test.rb +25 -0
- data/test/unit/meta_test.rb +10 -1
- data/test/unit/miui_browser_test.rb +25 -0
- data/test/unit/opera_test.rb +1 -0
- data/test/unit/platform_test.rb +7 -7
- data/test/unit/qq_test.rb +12 -0
- data/test/unit/safari_test.rb +12 -7
- data/test/unit/samsung_browser_test.rb +1 -0
- data/test/unit/sougou_browser_test.rb +41 -0
- metadata +37 -16
- data/.travis.yml +0 -23
data/browser.gemspec
CHANGED
@@ -8,13 +8,14 @@ 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
|
+
s.required_ruby_version = ">= 2.5.0"
|
16
|
+
|
17
|
+
s.metadata["changelog_uri"] = "https://github.com/fnando/browser/blob/main/CHANGELOG.md"
|
15
18
|
|
16
|
-
s.metadata["changelog_uri"] = "https://github.com/fnando/browser/blob/master/CHANGELOG.md"
|
17
|
-
|
18
19
|
s.files = `git ls-files`.split("\n")
|
19
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
21
|
s.executables = `git ls-files -- exe/*`
|
@@ -31,6 +32,6 @@ Gem::Specification.new do |s|
|
|
31
32
|
s.add_development_dependency "rails"
|
32
33
|
s.add_development_dependency "rake"
|
33
34
|
s.add_development_dependency "rubocop"
|
34
|
-
s.add_development_dependency "rubocop-fnando"
|
35
|
+
s.add_development_dependency "rubocop-fnando"
|
35
36
|
s.add_development_dependency "simplecov"
|
36
37
|
end
|
@@ -48,15 +48,15 @@ module Browser
|
|
48
48
|
def quality
|
49
49
|
@quality ||= begin
|
50
50
|
Float(quality_value || 1.0)
|
51
|
-
|
52
|
-
|
51
|
+
rescue ArgumentError
|
52
|
+
0.1
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
private def quality_value
|
57
57
|
qvalue = part[/;q=([\d.]+)/, 1]
|
58
|
-
qvalue =
|
59
|
-
qvalue = qvalue.
|
58
|
+
qvalue = /\A0\.0?\z/.match?(qvalue) ? "0.0" : qvalue
|
59
|
+
qvalue = qvalue.squeeze(".") if qvalue
|
60
60
|
qvalue
|
61
61
|
end
|
62
62
|
end
|
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.
|
@@ -99,19 +106,20 @@ module Browser
|
|
99
106
|
|
100
107
|
# Detect if browser is WebKit-based.
|
101
108
|
def webkit?(expected_version = nil)
|
102
|
-
ua
|
109
|
+
ua.match?(/AppleWebKit/i) &&
|
103
110
|
(!edge? || Edge.new(ua).chrome_based?) &&
|
104
111
|
detect_version?(webkit_full_version, expected_version)
|
105
112
|
end
|
106
113
|
|
107
114
|
# Detect if browser is QuickTime
|
108
115
|
def quicktime?(expected_version = nil)
|
109
|
-
ua
|
116
|
+
ua.match?(/QuickTime/i) && detect_version?(full_version, expected_version)
|
110
117
|
end
|
111
118
|
|
112
119
|
# Detect if browser is Apple CoreMedia.
|
113
120
|
def core_media?(expected_version = nil)
|
114
|
-
ua
|
121
|
+
ua.include?("CoreMedia") && detect_version?(full_version,
|
122
|
+
expected_version)
|
115
123
|
end
|
116
124
|
|
117
125
|
# Detect if browser is PhantomJS
|
@@ -122,11 +130,11 @@ module Browser
|
|
122
130
|
|
123
131
|
# Detect if browser is Safari.
|
124
132
|
def safari?(expected_version = nil)
|
125
|
-
Safari.new(ua).match? && detect_version?(
|
133
|
+
Safari.new(ua).match? && detect_version?(full_version, expected_version)
|
126
134
|
end
|
127
135
|
|
128
136
|
def safari_webapp_mode?
|
129
|
-
(device.ipad? || device.iphone?) && ua
|
137
|
+
(device.ipad? || device.iphone?) && ua.include?("AppleWebKit")
|
130
138
|
end
|
131
139
|
|
132
140
|
# Detect if browser is Firefox.
|
@@ -184,17 +192,53 @@ module Browser
|
|
184
192
|
|
185
193
|
# Detect if browser is Opera Mini.
|
186
194
|
def opera_mini?(expected_version = nil)
|
187
|
-
ua
|
195
|
+
ua.include?("Opera Mini") && detect_version?(full_version,
|
196
|
+
expected_version)
|
188
197
|
end
|
189
198
|
|
190
199
|
# Detect if browser is DuckDuckGo.
|
191
200
|
def duck_duck_go?(expected_version = nil)
|
192
|
-
ua
|
201
|
+
ua.include?("DuckDuckGo") && detect_version?(full_version,
|
202
|
+
expected_version)
|
193
203
|
end
|
194
204
|
|
195
205
|
# Detect if browser is Samsung.
|
196
206
|
def samsung_browser?(expected_version = nil)
|
197
|
-
ua
|
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)
|
198
242
|
end
|
199
243
|
|
200
244
|
def webkit_full_version
|
@@ -202,7 +246,11 @@ module Browser
|
|
202
246
|
end
|
203
247
|
|
204
248
|
def known?
|
205
|
-
|
249
|
+
!unknown?
|
250
|
+
end
|
251
|
+
|
252
|
+
def unknown?
|
253
|
+
id == :unknown_browser
|
206
254
|
end
|
207
255
|
|
208
256
|
# Detect if browser is a proxy browser.
|
@@ -214,5 +262,16 @@ module Browser
|
|
214
262
|
def electron?(expected_version = nil)
|
215
263
|
Electron.new(ua).match? && detect_version?(full_version, expected_version)
|
216
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
|
217
276
|
end
|
218
277
|
end
|
data/lib/browser/blackberry.rb
CHANGED
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"
|
@@ -32,6 +32,11 @@ require_relative "sputnik"
|
|
32
32
|
require_relative "snapchat"
|
33
33
|
require_relative "duck_duck_go"
|
34
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"
|
35
40
|
|
36
41
|
require_relative "bot"
|
37
42
|
require_relative "bot/empty_user_agent_matcher"
|
@@ -46,10 +51,19 @@ require_relative "meta"
|
|
46
51
|
module Browser
|
47
52
|
EMPTY_STRING = ""
|
48
53
|
|
54
|
+
Error = Class.new(StandardError)
|
55
|
+
|
49
56
|
def self.root
|
50
57
|
@root ||= Pathname.new(File.expand_path("../..", __dir__))
|
51
58
|
end
|
52
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
|
+
|
53
67
|
# Hold the list of browser matchers.
|
54
68
|
# Order is important.
|
55
69
|
def self.matchers
|
@@ -75,9 +89,14 @@ module Browser
|
|
75
89
|
Sputnik, # must be placed before Chrome and Safari
|
76
90
|
DuckDuckGo, # must be placed before Chrome and Safari
|
77
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
|
78
97
|
Chrome,
|
79
98
|
Safari,
|
80
|
-
|
99
|
+
Unknown
|
81
100
|
]
|
82
101
|
end
|
83
102
|
|
data/lib/browser/chrome.rb
CHANGED
@@ -20,14 +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
26
|
!edge? &&
|
27
27
|
!duck_duck_go? &&
|
28
28
|
!yandex? &&
|
29
29
|
!sputnik? &&
|
30
|
-
!samsung_browser?
|
30
|
+
!samsung_browser? &&
|
31
|
+
!huawei_browser? &&
|
32
|
+
!miui_browser? &&
|
33
|
+
!maxthon? &&
|
34
|
+
!qq? &&
|
35
|
+
!sougou_browser? &&
|
36
|
+
!google_search_app?
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|
data/lib/browser/device.rb
CHANGED
@@ -20,6 +20,7 @@ require_relative "device/switch"
|
|
20
20
|
require_relative "device/tv"
|
21
21
|
require_relative "device/xbox_one"
|
22
22
|
require_relative "device/xbox_360"
|
23
|
+
require_relative "device/samsung"
|
23
24
|
|
24
25
|
module Browser
|
25
26
|
class Device
|
@@ -29,6 +30,7 @@ module Browser
|
|
29
30
|
# Order is important.
|
30
31
|
def self.matchers
|
31
32
|
@matchers ||= [
|
33
|
+
Samsung,
|
32
34
|
XboxOne,
|
33
35
|
Xbox360,
|
34
36
|
Surface,
|
@@ -88,7 +90,7 @@ module Browser
|
|
88
90
|
end
|
89
91
|
|
90
92
|
def unknown?
|
91
|
-
id == :
|
93
|
+
id == :unknown_device
|
92
94
|
end
|
93
95
|
|
94
96
|
def ipod_touch?
|
@@ -158,12 +160,12 @@ module Browser
|
|
158
160
|
|
159
161
|
# Detect if browser is Silk.
|
160
162
|
def silk?
|
161
|
-
ua
|
163
|
+
ua.include?("Silk")
|
162
164
|
end
|
163
165
|
|
164
166
|
# Detect if browser is running under Xbox.
|
165
167
|
def xbox?
|
166
|
-
ua
|
168
|
+
ua.include?("Xbox")
|
167
169
|
end
|
168
170
|
|
169
171
|
# Detect if browser is running under Xbox 360.
|
@@ -191,13 +193,18 @@ module Browser
|
|
191
193
|
xbox? || playstation? || nintendo?
|
192
194
|
end
|
193
195
|
|
196
|
+
# Detect if device is a Samsung.
|
197
|
+
def samsung?
|
198
|
+
id == :samsung
|
199
|
+
end
|
200
|
+
|
194
201
|
# Regex taken from http://detectmobilebrowsers.com
|
195
202
|
# rubocop:disable Layout/LineLength
|
196
203
|
private def detect_mobile?
|
197
204
|
psp? ||
|
198
|
-
/zunewp7/i.match(ua) ||
|
205
|
+
/zunewp7/i.match?(ua) ||
|
199
206
|
%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
|
207
|
+
%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
208
|
end
|
202
209
|
# rubocop:enable Layout/LineLength
|
203
210
|
|
data/lib/browser/device/ipad.rb
CHANGED