agentry 3.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 +7 -0
- data/CHANGELOG.md +93 -0
- data/LICENSE.md +21 -0
- data/README.md +552 -0
- data/data/bot_categories.json +1 -0
- data/data/bot_exceptions.json +1 -0
- data/data/bot_ip_ranges.json +1 -0
- data/data/bots.json +1 -0
- data/data/languages.json +1 -0
- data/data/samsung.json +1 -0
- data/data/search_engines.json +1 -0
- data/lib/agentry.rb +3 -0
- data/lib/browser/accept_language.rb +55 -0
- data/lib/browser/action_controller.rb +21 -0
- data/lib/browser/aliases.rb +33 -0
- data/lib/browser/alipay.rb +21 -0
- data/lib/browser/base.rb +307 -0
- data/lib/browser/blackberry.rb +23 -0
- data/lib/browser/bot/empty_user_agent_matcher.rb +11 -0
- data/lib/browser/bot/ip_ranges.rb +194 -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 +221 -0
- data/lib/browser/browser.rb +200 -0
- data/lib/browser/cache.rb +92 -0
- data/lib/browser/chrome.rb +43 -0
- data/lib/browser/client_hints.rb +73 -0
- data/lib/browser/cloudflare.rb +65 -0
- data/lib/browser/detect_version.rb +22 -0
- data/lib/browser/detection.rb +25 -0
- data/lib/browser/device/android.rb +20 -0
- data/lib/browser/device/base.rb +13 -0
- data/lib/browser/device/blackberry_playbook.rb +19 -0
- data/lib/browser/device/ipad.rb +19 -0
- data/lib/browser/device/iphone.rb +19 -0
- data/lib/browser/device/ipod_touch.rb +19 -0
- data/lib/browser/device/kindle.rb +19 -0
- data/lib/browser/device/kindle_fire.rb +19 -0
- data/lib/browser/device/playstation3.rb +19 -0
- data/lib/browser/device/playstation4.rb +19 -0
- data/lib/browser/device/psp.rb +19 -0
- data/lib/browser/device/psvita.rb +19 -0
- data/lib/browser/device/samsung.rb +33 -0
- data/lib/browser/device/surface.rb +23 -0
- data/lib/browser/device/switch.rb +19 -0
- data/lib/browser/device/tv.rb +19 -0
- data/lib/browser/device/unknown.rb +19 -0
- data/lib/browser/device/wii.rb +19 -0
- data/lib/browser/device/wiiu.rb +19 -0
- data/lib/browser/device/xbox_360.rb +19 -0
- data/lib/browser/device/xbox_one.rb +19 -0
- data/lib/browser/device.rb +246 -0
- data/lib/browser/duck_duck_go.rb +22 -0
- data/lib/browser/edge.rb +25 -0
- data/lib/browser/electron.rb +22 -0
- data/lib/browser/epiphany.rb +21 -0
- data/lib/browser/facebook.rb +23 -0
- data/lib/browser/firefox.rb +21 -0
- data/lib/browser/google_search_app.rb +21 -0
- data/lib/browser/huawei_browser.rb +21 -0
- data/lib/browser/instagram.rb +21 -0
- data/lib/browser/internet_explorer.rb +63 -0
- data/lib/browser/maxthon.rb +21 -0
- data/lib/browser/meta/base.rb +42 -0
- data/lib/browser/meta/device.rb +11 -0
- data/lib/browser/meta/generic_browser.rb +15 -0
- data/lib/browser/meta/id.rb +11 -0
- data/lib/browser/meta/ie.rb +20 -0
- data/lib/browser/meta/ios.rb +11 -0
- data/lib/browser/meta/mobile.rb +11 -0
- data/lib/browser/meta/platform.rb +11 -0
- data/lib/browser/meta/proxy.rb +11 -0
- data/lib/browser/meta/safari.rb +11 -0
- data/lib/browser/meta/tablet.rb +11 -0
- data/lib/browser/meta/webkit.rb +11 -0
- data/lib/browser/meta.rb +14 -0
- data/lib/browser/micro_messenger.rb +21 -0
- data/lib/browser/middleware/context/additions.rb +18 -0
- data/lib/browser/middleware/context/url_methods.rb +15 -0
- data/lib/browser/middleware/context.rb +23 -0
- data/lib/browser/middleware.rb +70 -0
- data/lib/browser/miui_browser.rb +21 -0
- data/lib/browser/nokia.rb +21 -0
- data/lib/browser/opera.rb +21 -0
- data/lib/browser/otter.rb +21 -0
- data/lib/browser/phantom_js.rb +21 -0
- data/lib/browser/platform/adobe_air.rb +23 -0
- data/lib/browser/platform/android.rb +23 -0
- data/lib/browser/platform/base.rb +18 -0
- data/lib/browser/platform/blackberry.rb +23 -0
- data/lib/browser/platform/chrome_os.rb +23 -0
- data/lib/browser/platform/firefox_os.rb +23 -0
- data/lib/browser/platform/ios.rb +36 -0
- data/lib/browser/platform/kai_os.rb +23 -0
- data/lib/browser/platform/linux.rb +23 -0
- data/lib/browser/platform/mac.rb +25 -0
- data/lib/browser/platform/unknown.rb +23 -0
- data/lib/browser/platform/windows.rb +23 -0
- data/lib/browser/platform/windows_mobile.rb +23 -0
- data/lib/browser/platform/windows_phone.rb +23 -0
- data/lib/browser/platform.rb +220 -0
- data/lib/browser/qq.rb +25 -0
- data/lib/browser/rails.rb +24 -0
- data/lib/browser/safari.rb +40 -0
- data/lib/browser/samsung_browser.rb +21 -0
- data/lib/browser/snapchat.rb +21 -0
- data/lib/browser/sougou_browser.rb +24 -0
- data/lib/browser/sputnik.rb +21 -0
- data/lib/browser/testing.rb +29 -0
- data/lib/browser/uc_browser.rb +21 -0
- data/lib/browser/unknown.rb +32 -0
- data/lib/browser/version.rb +5 -0
- data/lib/browser/weibo.rb +21 -0
- data/lib/browser/yandex.rb +21 -0
- data/lib/browser.rb +4 -0
- data/test/ua.yml +181 -0
- data/test/ua_bots.yml +121 -0
- data/test/ua_search_engines.yml +7 -0
- metadata +274 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "device/base"
|
|
4
|
+
require_relative "device/android"
|
|
5
|
+
require_relative "device/unknown"
|
|
6
|
+
require_relative "device/ipad"
|
|
7
|
+
require_relative "device/ipod_touch"
|
|
8
|
+
require_relative "device/iphone"
|
|
9
|
+
require_relative "device/playstation3"
|
|
10
|
+
require_relative "device/playstation4"
|
|
11
|
+
require_relative "device/psp"
|
|
12
|
+
require_relative "device/psvita"
|
|
13
|
+
require_relative "device/kindle"
|
|
14
|
+
require_relative "device/kindle_fire"
|
|
15
|
+
require_relative "device/wii"
|
|
16
|
+
require_relative "device/wiiu"
|
|
17
|
+
require_relative "device/blackberry_playbook"
|
|
18
|
+
require_relative "device/surface"
|
|
19
|
+
require_relative "device/switch"
|
|
20
|
+
require_relative "device/tv"
|
|
21
|
+
require_relative "device/xbox_one"
|
|
22
|
+
require_relative "device/xbox_360"
|
|
23
|
+
require_relative "device/samsung"
|
|
24
|
+
|
|
25
|
+
module Browser
|
|
26
|
+
class Device
|
|
27
|
+
attr_reader :ua
|
|
28
|
+
|
|
29
|
+
# Hold the list of device matchers.
|
|
30
|
+
# Order is important.
|
|
31
|
+
def self.matchers
|
|
32
|
+
@matchers ||= [
|
|
33
|
+
Samsung,
|
|
34
|
+
XboxOne,
|
|
35
|
+
Xbox360,
|
|
36
|
+
Surface,
|
|
37
|
+
TV,
|
|
38
|
+
BlackBerryPlaybook,
|
|
39
|
+
WiiU,
|
|
40
|
+
Wii,
|
|
41
|
+
Switch,
|
|
42
|
+
KindleFire,
|
|
43
|
+
Kindle,
|
|
44
|
+
PlayStation4,
|
|
45
|
+
PlayStation3,
|
|
46
|
+
PSVita,
|
|
47
|
+
PSP,
|
|
48
|
+
Ipad,
|
|
49
|
+
Iphone,
|
|
50
|
+
IpodTouch,
|
|
51
|
+
Android,
|
|
52
|
+
Unknown
|
|
53
|
+
]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def initialize(ua, platform: nil, client_hints: nil)
|
|
57
|
+
@ua = ua
|
|
58
|
+
@platform = platform
|
|
59
|
+
@client_hints = client_hints
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# This device, or one built with the client hints when Sec-CH-UA-Mobile or
|
|
63
|
+
# the platform they gave change its answers.
|
|
64
|
+
def with_client_hints(client_hints, platform:)
|
|
65
|
+
mobile = client_hints.mobile?
|
|
66
|
+
return self if platform.equal?(self.platform) && (mobile.nil? || mobile == detect_mobile?)
|
|
67
|
+
|
|
68
|
+
self.class.new(ua, platform:, client_hints:)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def subject
|
|
72
|
+
@subject ||= self.class.matchers.each do |matcher|
|
|
73
|
+
candidate = matcher.new(ua)
|
|
74
|
+
break candidate if candidate.match?
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def id
|
|
79
|
+
subject.id
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def name
|
|
83
|
+
subject.name
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Detect if browser is tablet (currently iPad, Android, Surface or
|
|
87
|
+
# Playbook).
|
|
88
|
+
def tablet?
|
|
89
|
+
ipad? ||
|
|
90
|
+
(platform.android? && !detect_mobile?) ||
|
|
91
|
+
surface? ||
|
|
92
|
+
playbook?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Detect if browser is mobile.
|
|
96
|
+
def mobile?
|
|
97
|
+
detect_mobile? && !tablet?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def ipad?
|
|
101
|
+
id == :ipad
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def unknown?
|
|
105
|
+
id == :unknown_device
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def ipod_touch?
|
|
109
|
+
id == :ipod_touch
|
|
110
|
+
end
|
|
111
|
+
alias_method :ipod?, :ipod_touch?
|
|
112
|
+
|
|
113
|
+
def iphone?
|
|
114
|
+
id == :iphone
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def ps3?
|
|
118
|
+
id == :ps3
|
|
119
|
+
end
|
|
120
|
+
alias_method :playstation3?, :ps3?
|
|
121
|
+
|
|
122
|
+
def ps4?
|
|
123
|
+
id == :ps4
|
|
124
|
+
end
|
|
125
|
+
alias_method :playstation4?, :ps4?
|
|
126
|
+
|
|
127
|
+
def psp?
|
|
128
|
+
id == :psp
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def playstation_vita?
|
|
132
|
+
id == :psvita
|
|
133
|
+
end
|
|
134
|
+
alias_method :vita?, :playstation_vita?
|
|
135
|
+
alias_method :psp_vita?, :playstation_vita?
|
|
136
|
+
|
|
137
|
+
def kindle?
|
|
138
|
+
id == :kindle || kindle_fire?
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def kindle_fire?
|
|
142
|
+
id == :kindle_fire
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def nintendo_wii?
|
|
146
|
+
id == :wii
|
|
147
|
+
end
|
|
148
|
+
alias_method :wii?, :nintendo_wii?
|
|
149
|
+
|
|
150
|
+
def nintendo_wiiu?
|
|
151
|
+
id == :wiiu
|
|
152
|
+
end
|
|
153
|
+
alias_method :wiiu?, :nintendo_wiiu?
|
|
154
|
+
|
|
155
|
+
def nintendo_switch?
|
|
156
|
+
id == :switch
|
|
157
|
+
end
|
|
158
|
+
alias_method :switch?, :nintendo_switch?
|
|
159
|
+
|
|
160
|
+
def blackberry_playbook?
|
|
161
|
+
id == :playbook
|
|
162
|
+
end
|
|
163
|
+
alias_method :playbook?, :blackberry_playbook?
|
|
164
|
+
|
|
165
|
+
def surface?
|
|
166
|
+
id == :surface
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def tv?
|
|
170
|
+
id == :tv
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Detect if browser is Silk.
|
|
174
|
+
def silk?
|
|
175
|
+
ua.include?("Silk")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Detect if browser is running under Xbox.
|
|
179
|
+
def xbox?
|
|
180
|
+
ua.include?("Xbox")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Detect if browser is running under Xbox 360.
|
|
184
|
+
def xbox_360?
|
|
185
|
+
id == :xbox_360
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Detect if browser is running under Xbox One.
|
|
189
|
+
def xbox_one?
|
|
190
|
+
id == :xbox_one
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Detect if browser is running under PlayStation.
|
|
194
|
+
def playstation?
|
|
195
|
+
ps3? || ps4?
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Detect if browser is Nintendo.
|
|
199
|
+
def nintendo?
|
|
200
|
+
wii? || wiiu? || switch?
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Detect if browser is console (currently Xbox, PlayStation, or Nintendo).
|
|
204
|
+
def console?
|
|
205
|
+
xbox? || playstation? || nintendo?
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Detect if device is a Samsung.
|
|
209
|
+
def samsung?
|
|
210
|
+
id == :samsung
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Regex taken from http://detectmobilebrowsers.com
|
|
214
|
+
MOBILE_REGEX = %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
|
|
215
|
+
MOBILE_PREFIX_REGEX = %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
|
|
216
|
+
# Both are lowercase: on an ASCII user agent, matching its downcased copy
|
|
217
|
+
# without /i gives the same answer several times faster. Every prefix is 4
|
|
218
|
+
# characters long, so anchoring it tests the first 4 without copying them.
|
|
219
|
+
MOBILE_LOWERCASE_REGEX = Regexp.new(MOBILE_REGEX.source)
|
|
220
|
+
MOBILE_PREFIX_LOWERCASE_REGEX = Regexp.new("\\A(?:#{MOBILE_PREFIX_REGEX.source})")
|
|
221
|
+
private_constant :MOBILE_REGEX, :MOBILE_PREFIX_REGEX, :MOBILE_LOWERCASE_REGEX,
|
|
222
|
+
:MOBILE_PREFIX_LOWERCASE_REGEX
|
|
223
|
+
|
|
224
|
+
private def detect_mobile?
|
|
225
|
+
return @detect_mobile if defined?(@detect_mobile)
|
|
226
|
+
|
|
227
|
+
mobile = @client_hints&.mobile?
|
|
228
|
+
@detect_mobile = mobile.nil? ? psp? || /zunewp7|crios/i.match?(ua) || mobile_user_agent? : mobile
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
private def mobile_user_agent?
|
|
232
|
+
return MOBILE_REGEX.match?(ua) || MOBILE_PREFIX_REGEX.match?(ua[0..3]) unless ua.ascii_only?
|
|
233
|
+
|
|
234
|
+
lowercase_ua = ua.downcase
|
|
235
|
+
MOBILE_LOWERCASE_REGEX.match?(lowercase_ua) ||
|
|
236
|
+
MOBILE_PREFIX_LOWERCASE_REGEX.match?(lowercase_ua)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
private def platform
|
|
240
|
+
@platform ||= Platform.new(ua)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
private :subject
|
|
244
|
+
private :ua
|
|
245
|
+
end
|
|
246
|
+
end
|
|
@@ -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.include?("DuckDuckGo")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/browser/edge.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Edge < InternetExplorer
|
|
5
|
+
def id
|
|
6
|
+
:edge
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Microsoft Edge"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{(?:Edge|Edg|EdgiOS|EdgA)/([\d.]+)}, 1] || super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.match?(%r{((?:Edge|Edg|EdgiOS|EdgA)/[\d.]+|Trident/8)})
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def chromium_based?
|
|
22
|
+
match? && ua.match?(/\bEdg\b/)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Electron < Base
|
|
5
|
+
def id
|
|
6
|
+
:electron
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Electron"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{Electron/([\d.]+)}, 1] ||
|
|
15
|
+
"0.0"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def match?
|
|
19
|
+
ua.include?("Electron")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Epiphany < Base
|
|
5
|
+
def id
|
|
6
|
+
:epiphany
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Epiphany"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{Epiphany/([\d.]+)}, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("Epiphany")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Facebook < Base
|
|
5
|
+
def id
|
|
6
|
+
:facebook
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Facebook"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{FBAV/([\d.]+)}, 1] ||
|
|
15
|
+
ua[%r{AppleWebKit/([\d.]+)}, 0] ||
|
|
16
|
+
"0.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def match?
|
|
20
|
+
ua.match?(/FBAV|FBAN/)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Firefox < Base
|
|
5
|
+
def id
|
|
6
|
+
:firefox
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Firefox"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{(?:Firefox|FxiOS)/([\d.]+)}, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.match?(/Firefox|FxiOS/)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -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.include?("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.match?(/HuaweiBrowser/i)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Instagram < Base
|
|
5
|
+
def id
|
|
6
|
+
:instagram
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Instagram"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{Instagram[ /]([\d.]+)}, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("Instagram")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class InternetExplorer < Base
|
|
5
|
+
# https://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx#TriToken
|
|
6
|
+
TRIDENT_MAPPING = {
|
|
7
|
+
"4.0" => "8",
|
|
8
|
+
"5.0" => "9",
|
|
9
|
+
"6.0" => "10",
|
|
10
|
+
"7.0" => "11",
|
|
11
|
+
"8.0" => "12"
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
def id
|
|
15
|
+
:ie
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def name
|
|
19
|
+
"Internet Explorer"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def full_version
|
|
23
|
+
"#{ie_version}.0"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def msie_full_version
|
|
27
|
+
case ua.match(%r{MSIE ([\d.]+)|Trident/.*?; rv:([\d.]+)})
|
|
28
|
+
in [msie, trident_rv] then msie || trident_rv
|
|
29
|
+
else "0.0"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def msie_version
|
|
34
|
+
msie_full_version.split(".").first
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def match?
|
|
38
|
+
msie? || modern_ie?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Detect if IE is running in compatibility mode.
|
|
42
|
+
def compatibility_view?
|
|
43
|
+
trident_version && msie_version.to_i < (trident_version.to_i + 4)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private def ie_version
|
|
47
|
+
TRIDENT_MAPPING[trident_version] || msie_version
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Return the trident version.
|
|
51
|
+
private def trident_version
|
|
52
|
+
ua[%r{Trident/([0-9.]+)}, 1]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private def msie?
|
|
56
|
+
ua.include?("MSIE") && !ua.include?("Opera")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private def modern_ie?
|
|
60
|
+
ua.match?(%r{Trident/.*?; rv:(.*?)})
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
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.match?(/Maxthon/i)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
module Meta
|
|
5
|
+
def self.rules
|
|
6
|
+
@rules ||= [
|
|
7
|
+
Device,
|
|
8
|
+
GenericBrowser,
|
|
9
|
+
Id,
|
|
10
|
+
IE,
|
|
11
|
+
IOS,
|
|
12
|
+
Mobile,
|
|
13
|
+
Platform,
|
|
14
|
+
Proxy,
|
|
15
|
+
Safari,
|
|
16
|
+
Tablet,
|
|
17
|
+
Webkit
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.get(browser)
|
|
22
|
+
rules.flat_map { |rule| rule.new(browser).to_a }.uniq
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class Base
|
|
26
|
+
# Set the browser instance.
|
|
27
|
+
attr_reader :browser
|
|
28
|
+
|
|
29
|
+
def initialize(browser)
|
|
30
|
+
@browser = browser
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def meta
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_a
|
|
38
|
+
meta.to_s.squeeze(" ").split
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
module Meta
|
|
5
|
+
class GenericBrowser < Base
|
|
6
|
+
def meta
|
|
7
|
+
"#{browser.id} #{browser.id}#{browser.version}" if generic?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private def generic?
|
|
11
|
+
!browser.safari? && !browser.chrome?
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
module Meta
|
|
5
|
+
class IE < Base
|
|
6
|
+
def version
|
|
7
|
+
@version ||= browser.version.to_i
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def meta
|
|
11
|
+
return unless browser.ie?
|
|
12
|
+
|
|
13
|
+
meta = []
|
|
14
|
+
meta << "oldie lt-ie8 lt-ie9" if version < 8
|
|
15
|
+
meta << "lt-ie9" if version == 8
|
|
16
|
+
meta.join(" ")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|