browser 0.4.1 → 0.5.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/.hound.yml +90 -0
- data/.travis.yml +2 -1
- data/README.md +18 -0
- data/Rakefile +6 -7
- data/bots.yml +2 -0
- data/browser.gemspec +1 -2
- data/languages.yml +114 -0
- data/lib/browser.rb +47 -46
- data/lib/browser/action_controller.rb +1 -0
- data/lib/browser/meta/generic_browser.rb +7 -1
- data/lib/browser/methods/bots.rb +1 -1
- data/lib/browser/methods/devices.rb +1 -1
- data/lib/browser/methods/ie.rb +3 -1
- data/lib/browser/methods/language.rb +2 -117
- data/lib/browser/methods/mobile.rb +1 -0
- data/lib/browser/middleware.rb +2 -2
- data/lib/browser/version.rb +2 -2
- data/test/{browser_test.rb → browser_spec.rb} +171 -239
- data/test/{middleware_test.rb → middleware_spec.rb} +8 -8
- data/test/spec_helper.rb +8 -0
- data/test/ua.yml +67 -0
- metadata +15 -21
- data/test/test_helper.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8da651ebe15cf30e9eccffd7e45c2b2659785776
|
4
|
+
data.tar.gz: 08e9184e851b07fff6b2ff4efda0a820e042df50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1af5f14bd4c40f26773c2aecebf58802e3cc4f037481bfec8240c5cb54c52673a23249909d7280d13a1a7a0094942f2384ccf4e1e8a835c703bf6b9d5149dd22
|
7
|
+
data.tar.gz: b910d7e7b92cbc5456747369c27a1f955a1d33329b61caa2f50590aca90f20c80f13d75f6f8bab56b5e595b5ebaebe3437639f7dc8df0870090f33e67daad50b
|
data/.hound.yml
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
ClassLength:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
CyclomaticComplexity:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Documentation:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Encoding:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
FileName:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
IfUnlessModifier:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
MethodLength:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
ModuleFunction:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
OneLineConditional:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
ParameterLists:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Proc:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
SingleLineBlockParams:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
VariableInterpolation:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
TrailingComma:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
WhileUntilModifier:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
PredicateName:
|
47
|
+
NamePrefixBlacklist:
|
48
|
+
- is_
|
49
|
+
|
50
|
+
StringLiterals:
|
51
|
+
EnforcedStyle: double_quotes
|
52
|
+
SupportedStyles:
|
53
|
+
- single_quotes
|
54
|
+
- double_quotes
|
55
|
+
|
56
|
+
DotPosition:
|
57
|
+
EnforcedStyle: leading
|
58
|
+
|
59
|
+
SpaceBeforeBlockBraces:
|
60
|
+
EnforcedStyle: space
|
61
|
+
|
62
|
+
SpaceInsideBlockBraces:
|
63
|
+
EnforcedStyle: no_space
|
64
|
+
|
65
|
+
DoubleNegation:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
SpaceInsideBlockBraces:
|
69
|
+
SpaceBeforeBlockParameters: false
|
70
|
+
|
71
|
+
LineLength:
|
72
|
+
Max: 130
|
73
|
+
|
74
|
+
RegexpLiteral:
|
75
|
+
MaxSlashes: 0
|
76
|
+
|
77
|
+
SpaceInsideHashLiteralBraces:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
PercentLiteralDelimiters:
|
81
|
+
PreferredDelimiters:
|
82
|
+
'%': '[]'
|
83
|
+
'%i': '[]'
|
84
|
+
'%q': '[]'
|
85
|
+
'%Q': '[]'
|
86
|
+
'%r': '[]'
|
87
|
+
'%s': '[]'
|
88
|
+
'%w': '[]'
|
89
|
+
'%W': '[]'
|
90
|
+
'%x': '[]'
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -44,6 +44,24 @@ browser.to_s # the meta info joined by space
|
|
44
44
|
|
45
45
|
See the [tests](https://github.com/fnando/browser/blob/master/test/browser_test.rb) and [implementation](https://github.com/fnando/browser/blob/master/lib/browser.rb) for more examples.
|
46
46
|
|
47
|
+
### What defines a modern browser?
|
48
|
+
|
49
|
+
The current rules that define a modern browser are pretty loose:
|
50
|
+
|
51
|
+
* Webkit
|
52
|
+
* IE9+
|
53
|
+
* Firefox 17+
|
54
|
+
* Firefox Tablet 14+
|
55
|
+
* Opera 12+
|
56
|
+
|
57
|
+
You can define your your rules. A rule must be a proc/lambda or any object that implements the method === and accepts the browser object. To redefine all rules, clear the existing rules before adding your own.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# Only Chrome Canary is considered modern.
|
61
|
+
Browser.modern_rules.clear
|
62
|
+
Browser.modern_rules << -> b { b.chrome? && b.version >= '37' }
|
63
|
+
```
|
64
|
+
|
47
65
|
### Rails integration
|
48
66
|
|
49
67
|
Just add it to the Gemfile.
|
data/Rakefile
CHANGED
@@ -1,26 +1,25 @@
|
|
1
1
|
require "bundler"
|
2
|
+
require "bundler/setup"
|
2
3
|
Bundler::GemHelper.install_tasks
|
3
4
|
|
4
5
|
require "rake/testtask"
|
5
|
-
Rake::TestTask.new do |t|
|
6
|
+
Rake::TestTask.new(:spec) do |t|
|
6
7
|
t.libs << "lib"
|
7
8
|
t.libs << "test"
|
8
|
-
t.test_files = FileList["test/**/*
|
9
|
+
t.test_files = FileList["test/**/*_spec.rb"]
|
9
10
|
t.verbose = true
|
10
11
|
t.ruby_opts = %w[-rubygems]
|
11
12
|
end
|
12
13
|
|
13
14
|
desc "Run specs against all gemfiles"
|
14
|
-
task "
|
15
|
+
task "spec:all" do
|
15
16
|
%w[
|
16
17
|
Gemfile
|
17
18
|
gemfiles/rails3.gemfile
|
18
19
|
].each do |gemfile|
|
19
|
-
ENV["BUNDLE_GEMFILE"] = gemfile
|
20
20
|
puts "=> Running with Gemfile: #{gemfile}"
|
21
|
-
|
22
|
-
Rake::Task["test"].invoke
|
21
|
+
system "BUNDLE_GEMFILE=#{gemfile} rake spec"
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
task :default => "
|
25
|
+
task :default => "spec"
|
data/bots.yml
CHANGED
@@ -63,6 +63,7 @@ Laconica: "Laconica"
|
|
63
63
|
libwww-perl: "Perl client-server library loved by script kids"
|
64
64
|
LinkedInBot: "LinkedIn"
|
65
65
|
LinksCrawler: "LinksCrawler"
|
66
|
+
Livelapbot: "Livelapbot"
|
66
67
|
Lipperhey: "Lipperhey"
|
67
68
|
LongURL: "URL expander service"
|
68
69
|
Lumibot: "Lumibot"
|
@@ -107,6 +108,7 @@ Slurp: "Yahoo spider"
|
|
107
108
|
Sogou: "Chinese search engine"
|
108
109
|
spider: "generic web spider"
|
109
110
|
Test Certificate Info: "C http library?"
|
111
|
+
trendictionbot: "trendiction search"
|
110
112
|
TweetmemeBot: "TweetMeMe Crawler"
|
111
113
|
Twikle: "Social web search bot"
|
112
114
|
TwitJobSearch: "TwitJobSearch"
|
data/browser.gemspec
CHANGED
@@ -21,6 +21,5 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_development_dependency "rake"
|
22
22
|
s.add_development_dependency "rails"
|
23
23
|
s.add_development_dependency "rack-test"
|
24
|
-
s.add_development_dependency "
|
25
|
-
s.add_development_dependency "turn"
|
24
|
+
s.add_development_dependency "minitest"
|
26
25
|
end
|
data/languages.yml
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
"af": "Afrikaans"
|
2
|
+
"sq": "Albanian"
|
3
|
+
"eu": "Basque"
|
4
|
+
"bg": "Bulgarian"
|
5
|
+
"be": "Byelorussian"
|
6
|
+
"ca": "Catalan"
|
7
|
+
"zh": "Chinese"
|
8
|
+
"zh-cn": "Chinese/China"
|
9
|
+
"zh-tw": "Chinese/Taiwan"
|
10
|
+
"zh-hk": "Chinese/Hong Kong"
|
11
|
+
"zh-sg": "Chinese/singapore"
|
12
|
+
"hr": "Croatian"
|
13
|
+
"cs": "Czech"
|
14
|
+
"da": "Danish"
|
15
|
+
"nl": "Dutch"
|
16
|
+
"nl-nl": "Dutch/Netherlands"
|
17
|
+
"nl-be": "Dutch/Belgium"
|
18
|
+
"en": "English"
|
19
|
+
"en-gb": "English/United Kingdom"
|
20
|
+
"en-us": "English/United States"
|
21
|
+
"en-au": "English/Australian"
|
22
|
+
"en-ca": "English/Canada"
|
23
|
+
"en-nz": "English/New Zealand"
|
24
|
+
"en-ie": "English/Ireland"
|
25
|
+
"en-za": "English/South Africa"
|
26
|
+
"en-jm": "English/Jamaica"
|
27
|
+
"en-bz": "English/Belize"
|
28
|
+
"en-tt": "English/Trinidad"
|
29
|
+
"et": "Estonian"
|
30
|
+
"fo": "Faeroese"
|
31
|
+
"fa": "Farsi"
|
32
|
+
"fi": "Finnish"
|
33
|
+
"fr": "French"
|
34
|
+
"fr-be": "French/Belgium"
|
35
|
+
"fr-fr": "French/France"
|
36
|
+
"fr-ch": "French/Switzerland"
|
37
|
+
"fr-ca": "French/Canada"
|
38
|
+
"fr-lu": "French/Luxembourg"
|
39
|
+
"gd": "Gaelic"
|
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"
|
data/lib/browser.rb
CHANGED
@@ -37,38 +37,60 @@ class Browser
|
|
37
37
|
|
38
38
|
# Set browser's UA string.
|
39
39
|
attr_accessor :user_agent
|
40
|
-
|
41
|
-
|
40
|
+
alias_method :ua, :user_agent
|
41
|
+
alias_method :ua=, :user_agent=
|
42
42
|
|
43
43
|
NAMES = {
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
44
|
+
android: "Android",
|
45
|
+
blackberry: "BlackBerry",
|
46
|
+
chrome: "Chrome",
|
47
|
+
core_media: "Apple CoreMedia",
|
48
|
+
firefox: "Firefox",
|
49
|
+
ie: "Internet Explorer",
|
50
|
+
ipad: "iPad",
|
51
|
+
iphone: "iPhone",
|
52
|
+
ipod: "iPod Touch",
|
53
|
+
nintendo: "Nintendo",
|
54
|
+
opera: "Opera",
|
55
|
+
phantom_js: "PhantomJS",
|
56
|
+
psp: "PlayStation Portable",
|
57
|
+
playstation: "PlayStation",
|
58
|
+
quicktime: "QuickTime",
|
59
|
+
safari: "Safari",
|
60
|
+
xbox: "Xbox",
|
61
61
|
|
62
62
|
# This must be last item, since Ruby 1.9+ has ordered keys.
|
63
|
-
:
|
63
|
+
other: "Other",
|
64
64
|
}
|
65
65
|
|
66
66
|
VERSIONS = {
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
67
|
+
default: %r[(?:Version|MSIE|Firefox|Chrome|CriOS|QuickTime|BlackBerry[^/]+|CoreMedia v|PhantomJS)[/ ]?([a-z0-9.]+)]i,
|
68
|
+
opera: %r[(?:Opera/.*? Version/([\d.]+)|Chrome/([\d.]+).*?OPR)],
|
69
|
+
ie: %r[(?:MSIE |Trident/.*?; rv:)([\d.]+)]
|
70
70
|
}
|
71
71
|
|
72
|
+
# Define the rules which define a modern browser.
|
73
|
+
# A rule must be a proc/lambda or any object that implements the method
|
74
|
+
# === and accepts the browser object.
|
75
|
+
#
|
76
|
+
# To redefine all rules, clear the existing rules before adding your own.
|
77
|
+
#
|
78
|
+
# # Only Chrome Canary is considered modern.
|
79
|
+
# Browser.modern_rules.clear
|
80
|
+
# Browser.modern_rules << -> b { b.chrome? && b.version >= '37' }
|
81
|
+
#
|
82
|
+
def self.modern_rules
|
83
|
+
@modern_rules ||= []
|
84
|
+
end
|
85
|
+
|
86
|
+
self.modern_rules.tap do |rules|
|
87
|
+
rules << -> b { b.webkit? }
|
88
|
+
rules << -> b { b.firefox? && b.version.to_i >= 17 }
|
89
|
+
rules << -> b { b.ie? && b.version.to_i >= 9 }
|
90
|
+
rules << -> b { b.opera? && b.version.to_i >= 12 }
|
91
|
+
rules << -> b { b.firefox? && b.tablet? && b.android? && b.version.to_i >= 14 }
|
92
|
+
end
|
93
|
+
|
72
94
|
# Create a new browser instance and set
|
73
95
|
# the UA and Accept-Language headers.
|
74
96
|
#
|
@@ -81,7 +103,7 @@ class Browser
|
|
81
103
|
self.user_agent = (options[:user_agent] || options[:ua]).to_s
|
82
104
|
self.accept_language = options[:accept_language].to_s
|
83
105
|
|
84
|
-
yield self if
|
106
|
+
yield self if block
|
85
107
|
end
|
86
108
|
|
87
109
|
# Get readable browser name.
|
@@ -108,11 +130,7 @@ class Browser
|
|
108
130
|
|
109
131
|
# Return true if browser is modern (Webkit, Firefox 17+, IE9+, Opera 12+).
|
110
132
|
def modern?
|
111
|
-
|
112
|
-
newer_firefox? ||
|
113
|
-
newer_ie? ||
|
114
|
-
newer_opera? ||
|
115
|
-
newer_firefox_tablet?
|
133
|
+
self.class.modern_rules.any? {|rule| rule === self }
|
116
134
|
end
|
117
135
|
|
118
136
|
# Detect if browser is WebKit-based.
|
@@ -174,21 +192,4 @@ class Browser
|
|
174
192
|
def to_s
|
175
193
|
meta.to_a.join(" ")
|
176
194
|
end
|
177
|
-
|
178
|
-
private
|
179
|
-
def newer_firefox?
|
180
|
-
firefox? && version.to_i >= 17
|
181
|
-
end
|
182
|
-
|
183
|
-
def newer_ie?
|
184
|
-
ie? && version.to_i >= 9
|
185
|
-
end
|
186
|
-
|
187
|
-
def newer_opera?
|
188
|
-
opera? && version.to_i >= 12
|
189
|
-
end
|
190
|
-
|
191
|
-
def newer_firefox_tablet?
|
192
|
-
firefox? && tablet? && android? && version.to_i >= 14
|
193
|
-
end
|
194
195
|
end
|