browser2 1.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/.gitignore +5 -0
- data/.hound.yml +90 -0
- data/.rubocop.yml +90 -0
- data/.travis.yml +14 -0
- data/CONTRIBUTING.md +44 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.md +125 -0
- data/Rakefile +33 -0
- data/browser2.gemspec +42 -0
- data/config.ru +2 -0
- data/data/bots.json +176 -0
- data/data/languages.json +115 -0
- data/gemfiles/rails3.gemfile +4 -0
- data/lib/browser/action_controller.rb +20 -0
- data/lib/browser/data/bots.rb +5 -0
- data/lib/browser/data/languages.rb +5 -0
- data/lib/browser/data/search_engines.rb +14 -0
- data/lib/browser/meta/base.rb +20 -0
- data/lib/browser/meta/generic_browser.rb +15 -0
- data/lib/browser/meta/id.rb +9 -0
- data/lib/browser/meta/ie.rb +18 -0
- data/lib/browser/meta/ios.rb +9 -0
- data/lib/browser/meta/mobile.rb +9 -0
- data/lib/browser/meta/modern.rb +9 -0
- data/lib/browser/meta/platform.rb +9 -0
- data/lib/browser/meta/safari.rb +9 -0
- data/lib/browser/meta/webkit.rb +9 -0
- data/lib/browser/methods/blackberry.rb +51 -0
- data/lib/browser/methods/bots.rb +37 -0
- data/lib/browser/methods/consoles.rb +43 -0
- data/lib/browser/methods/devices.rb +41 -0
- data/lib/browser/methods/ie.rb +104 -0
- data/lib/browser/methods/language.rb +16 -0
- data/lib/browser/methods/mobile.rb +30 -0
- data/lib/browser/methods/platform.rb +142 -0
- data/lib/browser/methods/tv.rb +8 -0
- data/lib/browser/middleware/context/additions.rb +16 -0
- data/lib/browser/middleware/context/url_methods.rb +13 -0
- data/lib/browser/middleware/context.rb +20 -0
- data/lib/browser/middleware.rb +66 -0
- data/lib/browser/rails.rb +14 -0
- data/lib/browser/version.rb +8 -0
- data/lib/browser.rb +255 -0
- data/test/benchmark_test.rb +83 -0
- data/test/browser_test.rb +248 -0
- data/test/middleware_test.rb +50 -0
- data/test/sample_app.rb +31 -0
- data/test/test_helper.rb +20 -0
- data/test/ua.yml +122 -0
- data/test/unit/adobe_air_test.rb +13 -0
- data/test/unit/android_test.rb +93 -0
- data/test/unit/blackberry_test.rb +104 -0
- data/test/unit/bots_test.rb +116 -0
- data/test/unit/chrome_test.rb +56 -0
- data/test/unit/console_test.rb +67 -0
- data/test/unit/firefox_test.rb +37 -0
- data/test/unit/ie_test.rb +377 -0
- data/test/unit/ios_test.rb +139 -0
- data/test/unit/kindle_test.rb +37 -0
- data/test/unit/opera_test.rb +42 -0
- data/test/unit/windows_phone_test.rb +50 -0
- data/test/unit/windows_test.rb +60 -0
- metadata +240 -0
data/data/languages.json
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"af": "Afrikaans",
|
|
3
|
+
"sq": "Albanian",
|
|
4
|
+
"eu": "Basque",
|
|
5
|
+
"bg": "Bulgarian",
|
|
6
|
+
"be": "Byelorussian",
|
|
7
|
+
"ca": "Catalan",
|
|
8
|
+
"zh": "Chinese",
|
|
9
|
+
"zh-cn": "Chinese/China",
|
|
10
|
+
"zh-tw": "Chinese/Taiwan",
|
|
11
|
+
"zh-hk": "Chinese/Hong Kong",
|
|
12
|
+
"zh-sg": "Chinese/singapore",
|
|
13
|
+
"hr": "Croatian",
|
|
14
|
+
"cs": "Czech",
|
|
15
|
+
"da": "Danish",
|
|
16
|
+
"nl": "Dutch",
|
|
17
|
+
"nl-nl": "Dutch/Netherlands",
|
|
18
|
+
"nl-be": "Dutch/Belgium",
|
|
19
|
+
"en": "English",
|
|
20
|
+
"en-gb": "English/United Kingdom",
|
|
21
|
+
"en-us": "English/United States",
|
|
22
|
+
"en-au": "English/Australian",
|
|
23
|
+
"en-ca": "English/Canada",
|
|
24
|
+
"en-nz": "English/New Zealand",
|
|
25
|
+
"en-ie": "English/Ireland",
|
|
26
|
+
"en-za": "English/South Africa",
|
|
27
|
+
"en-jm": "English/Jamaica",
|
|
28
|
+
"en-bz": "English/Belize",
|
|
29
|
+
"en-tt": "English/Trinidad",
|
|
30
|
+
"et": "Estonian",
|
|
31
|
+
"fo": "Faeroese",
|
|
32
|
+
"fa": "Farsi",
|
|
33
|
+
"fi": "Finnish",
|
|
34
|
+
"fr": "French",
|
|
35
|
+
"fr-be": "French/Belgium",
|
|
36
|
+
"fr-fr": "French/France",
|
|
37
|
+
"fr-ch": "French/Switzerland",
|
|
38
|
+
"fr-ca": "French/Canada",
|
|
39
|
+
"fr-lu": "French/Luxembourg",
|
|
40
|
+
"gl": "Galician",
|
|
41
|
+
"de": "German",
|
|
42
|
+
"de-at": "German/Austria",
|
|
43
|
+
"de-de": "German/Germany",
|
|
44
|
+
"de-ch": "German/Switzerland",
|
|
45
|
+
"de-lu": "German/Luxembourg",
|
|
46
|
+
"de-li": "German/Liechtenstein",
|
|
47
|
+
"el": "Greek",
|
|
48
|
+
"he": "Hebrew",
|
|
49
|
+
"he-il": "Hebrew/Israel",
|
|
50
|
+
"hi": "Hindi",
|
|
51
|
+
"hu": "Hungarian",
|
|
52
|
+
"ie-ee": "Internet Explorer/Easter Egg",
|
|
53
|
+
"is": "Icelandic",
|
|
54
|
+
"id": "Indonesian",
|
|
55
|
+
"in": "Indonesian",
|
|
56
|
+
"ga": "Irish",
|
|
57
|
+
"it": "Italian",
|
|
58
|
+
"it-ch": "Italian/ Switzerland",
|
|
59
|
+
"ja": "Japanese",
|
|
60
|
+
"km": "Khmer",
|
|
61
|
+
"km-kh": "Khmer/Cambodia",
|
|
62
|
+
"ko": "Korean",
|
|
63
|
+
"lv": "Latvian",
|
|
64
|
+
"lt": "Lithuanian",
|
|
65
|
+
"mk": "Macedonian",
|
|
66
|
+
"ms": "Malaysian",
|
|
67
|
+
"mt": "Maltese",
|
|
68
|
+
"no": "Norwegian",
|
|
69
|
+
"pl": "Polish",
|
|
70
|
+
"pt": "Portuguese",
|
|
71
|
+
"pt-br": "Portuguese/Brazil",
|
|
72
|
+
"rm": "Rhaeto-Romanic",
|
|
73
|
+
"ro": "Romanian",
|
|
74
|
+
"ro-mo": "Romanian/Moldavia",
|
|
75
|
+
"ru": "Russian",
|
|
76
|
+
"ru-mo": "Russian /Moldavia",
|
|
77
|
+
"gd": "Scots Gaelic",
|
|
78
|
+
"sr": "Serbian",
|
|
79
|
+
"sk": "Slovack",
|
|
80
|
+
"sl": "Slovenian",
|
|
81
|
+
"sb": "Sorbian",
|
|
82
|
+
"es": "Spanish",
|
|
83
|
+
"es-do": "Spanish",
|
|
84
|
+
"es-ar": "Spanish/Argentina",
|
|
85
|
+
"es-co": "Spanish/Colombia",
|
|
86
|
+
"es-mx": "Spanish/Mexico",
|
|
87
|
+
"es-es": "Spanish/Spain",
|
|
88
|
+
"es-gt": "Spanish/Guatemala",
|
|
89
|
+
"es-cr": "Spanish/Costa Rica",
|
|
90
|
+
"es-pa": "Spanish/Panama",
|
|
91
|
+
"es-ve": "Spanish/Venezuela",
|
|
92
|
+
"es-pe": "Spanish/Peru",
|
|
93
|
+
"es-ec": "Spanish/Ecuador",
|
|
94
|
+
"es-cl": "Spanish/Chile",
|
|
95
|
+
"es-uy": "Spanish/Uruguay",
|
|
96
|
+
"es-py": "Spanish/Paraguay",
|
|
97
|
+
"es-bo": "Spanish/Bolivia",
|
|
98
|
+
"es-sv": "Spanish/El salvador",
|
|
99
|
+
"es-hn": "Spanish/Honduras",
|
|
100
|
+
"es-ni": "Spanish/Nicaragua",
|
|
101
|
+
"es-pr": "Spanish/Puerto Rico",
|
|
102
|
+
"sx": "Sutu",
|
|
103
|
+
"sv": "Swedish",
|
|
104
|
+
"sv-se": "Swedish/Sweden",
|
|
105
|
+
"sv-fi": "Swedish/Finland",
|
|
106
|
+
"ts": "Thai",
|
|
107
|
+
"tn": "Tswana",
|
|
108
|
+
"tr": "Turkish",
|
|
109
|
+
"uk": "Ukrainian",
|
|
110
|
+
"ur": "Urdu",
|
|
111
|
+
"vi": "Vietnamese",
|
|
112
|
+
"xh": "Xshosa",
|
|
113
|
+
"ji": "Yiddish",
|
|
114
|
+
"zu": "Zulu"
|
|
115
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "action_controller/railtie"
|
|
2
|
+
|
|
3
|
+
class Browser
|
|
4
|
+
module ActionController
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
helper_method :browser
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def browser
|
|
14
|
+
@browser ||= Browser.new(
|
|
15
|
+
accept_language: request.headers["Accept-Language"],
|
|
16
|
+
ua: request.headers["User-Agent"]
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Browser
|
|
4
|
+
module Data
|
|
5
|
+
SEARCH_ENGINES = {
|
|
6
|
+
'Baidu' => 'Chinese search engine',
|
|
7
|
+
'bingbot' => 'Microsoft bing bot',
|
|
8
|
+
'Googlebot' => 'Google spider',
|
|
9
|
+
'Slurp' => 'Yahoo spider',
|
|
10
|
+
'DuckDuckBot' => 'Duck Duck Go',
|
|
11
|
+
'Ask Jeeves' => 'Ask Jeeves'
|
|
12
|
+
}.freeze
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module Meta
|
|
3
|
+
class Base
|
|
4
|
+
# Set the browser instance.
|
|
5
|
+
attr_reader :browser
|
|
6
|
+
|
|
7
|
+
def initialize(browser)
|
|
8
|
+
@browser = browser
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def meta
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_a
|
|
16
|
+
meta.to_s.squeeze(" ").split(" ")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module Meta
|
|
3
|
+
class IE < Base
|
|
4
|
+
def version
|
|
5
|
+
@version ||= browser.version.to_i
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def meta
|
|
9
|
+
return unless browser.ie?
|
|
10
|
+
|
|
11
|
+
meta = ""
|
|
12
|
+
meta << "oldie lt-ie8 lt-ie9" if version < 8
|
|
13
|
+
meta << "lt-ie9" if version == 8
|
|
14
|
+
meta
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module BlackBerry
|
|
3
|
+
# Return BlackBerry version.
|
|
4
|
+
def blackberry_version
|
|
5
|
+
ua[/BB(10)/, 1] ||
|
|
6
|
+
ua[/BlackBerry\d+\/(\d+)/, 1] ||
|
|
7
|
+
ua[/BlackBerry.*?Version\/(\d+)/, 1]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Detect if browser is BlackBerry
|
|
11
|
+
def blackberry?(version = nil)
|
|
12
|
+
!!(ua =~ /(BlackBerry|BB10)/) && detect_version?(blackberry_version, version)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Detect if is BlackBerry 4.
|
|
16
|
+
def blackberry4?
|
|
17
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
18
|
+
blackberry?(4)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Detect if is BlackBerry 5.
|
|
22
|
+
def blackberry5?
|
|
23
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
24
|
+
blackberry?(5)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Detect if is BlackBerry 6.
|
|
28
|
+
def blackberry6?
|
|
29
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
30
|
+
blackberry?(6)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Detect if is BlackBerry 7.
|
|
34
|
+
def blackberry7?
|
|
35
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
36
|
+
blackberry?(7)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Detect if is BlackBerry 10.
|
|
40
|
+
def blackberry10?
|
|
41
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#blackberry?(version) instead"
|
|
42
|
+
blackberry?(10)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def blackberry_running_safari?
|
|
48
|
+
blackberry? && safari?
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Browser
|
|
4
|
+
module Bots
|
|
5
|
+
BOTS = Browser::Data::BOTS
|
|
6
|
+
SEARCH_ENGINES = Browser::Data::SEARCH_ENGINES
|
|
7
|
+
|
|
8
|
+
def self.detect_empty_ua!
|
|
9
|
+
@detect_empty_ua = true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.detect_empty_ua?
|
|
13
|
+
!!@detect_empty_ua
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def bot?
|
|
17
|
+
bot_with_empty_ua? || BOTS.any? {|key, _| ua.include?(key) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def bot_name
|
|
21
|
+
return 'Generic Bot' if bot_with_empty_ua?
|
|
22
|
+
|
|
23
|
+
pair = BOTS.find {|key, _| ua.include?(key) }
|
|
24
|
+
return pair ? pair.first : nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def search_engine?
|
|
28
|
+
SEARCH_ENGINES.any? {|key, _| ua.include?(key) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def bot_with_empty_ua?
|
|
34
|
+
Browser::Bots.detect_empty_ua? && ua.strip == ''
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module Consoles
|
|
3
|
+
# Detect if browser is running under Xbox.
|
|
4
|
+
def xbox?
|
|
5
|
+
!!(ua =~ /xbox/i)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Detect if browser is running under Xbox One.
|
|
9
|
+
def xbox_one?
|
|
10
|
+
!!(ua =~ /xbox one/i)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Detect if browser is running under PlayStation.
|
|
14
|
+
def playstation?
|
|
15
|
+
!!(ua =~ /playstation/i)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Detect if browser is running under PlayStation 4.
|
|
19
|
+
def playstation4?
|
|
20
|
+
!!(ua =~ /playstation 4/i)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Detect if browser is Nintendo.
|
|
24
|
+
def nintendo?
|
|
25
|
+
!!(ua =~ /nintendo/i)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Detect if browser is console (currently Xbox, PlayStation, or Nintendo).
|
|
29
|
+
def console?
|
|
30
|
+
xbox? || playstation? || nintendo?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Detect if browser is running from PSP.
|
|
34
|
+
def psp?
|
|
35
|
+
!!(ua =~ /(PSP)/ || psp_vita?)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Detect if browser is running from PSP Vita.
|
|
39
|
+
def psp_vita?
|
|
40
|
+
!!(ua =~ /Playstation Vita/)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module Devices
|
|
3
|
+
# Detect if browser is iPhone.
|
|
4
|
+
def iphone?
|
|
5
|
+
in_ua? 'iPhone'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Detect if browser is iPad.
|
|
9
|
+
def ipad?
|
|
10
|
+
in_ua? 'iPad'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Detect if browser is iPod.
|
|
14
|
+
def ipod?
|
|
15
|
+
in_ua? 'Pod'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def surface?
|
|
19
|
+
windows_rt? && in_ua?('Touch')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Detect if browser is tablet (currently iPad, Android, Surface or Playbook).
|
|
23
|
+
def tablet?
|
|
24
|
+
!!(ipad? || (android? && !detect_mobile?) || surface? || playbook?)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Detect if browser is Kindle.
|
|
28
|
+
def kindle?
|
|
29
|
+
in_ua?('Kindle') || silk?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Detect if browser if a Blackberry Playbook tablet
|
|
33
|
+
def playbook?
|
|
34
|
+
!!(ua =~ /PlayBook/ && ua =~ /RIM Tablet/)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def windows_touchscreen_desktop?
|
|
38
|
+
windows? && !!(ua =~ /Touch/)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Browser
|
|
4
|
+
module IE
|
|
5
|
+
TRIDENT_VERSION_REGEX = %r[Trident/([0-9.]+)]
|
|
6
|
+
MODERN_IE = %r[Trident/.*?; rv:(.*?)]
|
|
7
|
+
MSIE = %r{MSIE ([\d.]+)|Trident/.*?; rv:([\d.]+)}
|
|
8
|
+
EDGE = %r{(Edge/[\d.]+|Trident/8)}
|
|
9
|
+
|
|
10
|
+
# https://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx#TriToken
|
|
11
|
+
TRIDENT_MAPPING = {
|
|
12
|
+
"4.0" => "8",
|
|
13
|
+
"5.0" => "9",
|
|
14
|
+
"6.0" => "10",
|
|
15
|
+
"7.0" => "11",
|
|
16
|
+
"8.0" => "12"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def ie_version
|
|
20
|
+
TRIDENT_MAPPING[trident_version] || msie_version
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def ie_full_version
|
|
24
|
+
"#{ie_version}.0"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def msie_full_version
|
|
28
|
+
(ua.match(MSIE) && ($1 || $2)) || "0.0"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def msie_version
|
|
32
|
+
msie_full_version.to_s.split(".").first || "0"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Return the trident version.
|
|
36
|
+
def trident_version
|
|
37
|
+
ua.match(TRIDENT_VERSION_REGEX) && $1
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Detect if browser is Internet Explorer.
|
|
41
|
+
def ie?(version = nil)
|
|
42
|
+
(msie? || modern_ie?) && detect_version?(ie_version, version)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Detect if browser is Internet Explorer 6.
|
|
46
|
+
def ie6?
|
|
47
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
48
|
+
ie?(6)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Detect if browser is Internet Explorer 7.
|
|
52
|
+
def ie7?
|
|
53
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
54
|
+
ie?(7)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Detect if browser is Internet Explorer 8.
|
|
58
|
+
def ie8?
|
|
59
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
60
|
+
ie?(8)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Detect if browser is Internet Explorer 9.
|
|
64
|
+
def ie9?
|
|
65
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
66
|
+
ie?(9)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Detect if browser is Internet Explorer 10.
|
|
70
|
+
def ie10?
|
|
71
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
72
|
+
ie?(10)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Detect if browser is Internet Explorer 11.
|
|
76
|
+
def ie11?
|
|
77
|
+
deprecate "Browser##{__method__} is deprecated; use Browser#ie?(version) instead"
|
|
78
|
+
ie?(11)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Detect if browser is Microsoft Edge.
|
|
82
|
+
def edge?
|
|
83
|
+
in_ua?('Edge/') || in_ua?('Trident/8')
|
|
84
|
+
|
|
85
|
+
# Old regex approach:
|
|
86
|
+
# !!(ua =~ EDGE)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Detect if IE is running in compatibility mode.
|
|
90
|
+
def compatibility_view?
|
|
91
|
+
ie? && trident_version && msie_version.to_i < (trident_version.to_i + 4)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def msie?
|
|
97
|
+
!!(ua =~ /MSIE/ && ua !~ /Opera/)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def modern_ie?
|
|
101
|
+
!!(ua =~ MODERN_IE)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module Language
|
|
3
|
+
LANGUAGES = Browser::Data::LANGUAGES
|
|
4
|
+
|
|
5
|
+
# Set browser's preferred language
|
|
6
|
+
attr_writer :accept_language
|
|
7
|
+
|
|
8
|
+
# Return an array with all preferred languages that this browser accepts.
|
|
9
|
+
def accept_language
|
|
10
|
+
@accept_language
|
|
11
|
+
.gsub(/;q=[\d.]+/, "")
|
|
12
|
+
.split(",")
|
|
13
|
+
.map {|l| l.downcase.gsub(/\s/m, "") }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Browser
|
|
2
|
+
module Mobile
|
|
3
|
+
# Detect if browser is mobile.
|
|
4
|
+
def mobile?
|
|
5
|
+
detect_mobile? && !tablet?
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Detect if browser is Opera Mini.
|
|
9
|
+
def opera_mini?
|
|
10
|
+
!!(ua =~ /Opera Mini/)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Detect if browser is Adobe AIR.
|
|
14
|
+
def adobe_air?
|
|
15
|
+
!!(ua =~ /adobeair/i)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# Regex taken from http://detectmobilebrowsers.com
|
|
21
|
+
def detect_mobile?
|
|
22
|
+
!!(
|
|
23
|
+
psp? ||
|
|
24
|
+
/zunewp7/i.match(ua) ||
|
|
25
|
+
/(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) ||
|
|
26
|
+
/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])
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|