browser 0.1.6 → 0.2.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 +2 -1
- data/.travis.yml +8 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +70 -38
- data/README.md +114 -0
- data/Rakefile +12 -10
- data/browser.gemspec +2 -4
- data/config.ru +2 -0
- data/gemfiles/rails3.gemfile +4 -0
- data/gemfiles/rails3.gemfile.lock +111 -0
- data/lib/browser.rb +57 -283
- data/lib/browser/action_controller.rb +9 -7
- data/lib/browser/meta/base.rb +20 -0
- data/lib/browser/meta/generic_browser.rb +9 -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/devices.rb +33 -0
- data/lib/browser/methods/ie.rb +40 -0
- data/lib/browser/methods/language.rb +131 -0
- data/lib/browser/methods/mobile.rb +23 -0
- data/lib/browser/methods/platform.rb +54 -0
- data/lib/browser/middleware.rb +43 -0
- data/lib/browser/middleware/context.rb +20 -0
- data/lib/browser/middleware/context/additions.rb +16 -0
- data/lib/browser/middleware/context/url_methods.rb +13 -0
- data/lib/browser/rails.rb +14 -0
- data/lib/browser/version.rb +2 -2
- data/test/browser_test.rb +220 -74
- data/test/middleware_test.rb +32 -0
- data/test/sample_app.rb +27 -0
- data/test/test_helper.rb +2 -1
- metadata +43 -57
- data/README.rdoc +0 -75
@@ -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,33 @@
|
|
1
|
+
class Browser
|
2
|
+
module Devices
|
3
|
+
# Detect if browser is iPhone.
|
4
|
+
def iphone?
|
5
|
+
!!(ua =~ /iPhone/)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Detect if browser is iPad.
|
9
|
+
def ipad?
|
10
|
+
!!(ua =~ /iPad/)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Detect if browser is iPod.
|
14
|
+
def ipod?
|
15
|
+
!!(ua =~ /iPod/)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Detect if browser is tablet (currently just iPad or Android).
|
19
|
+
def tablet?
|
20
|
+
!!(ipad? || (android? && !detect_mobile?))
|
21
|
+
end
|
22
|
+
|
23
|
+
# Detect if browser is Kindle.
|
24
|
+
def kindle?
|
25
|
+
!!(ua =~ /Kindle/)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Detect if browser is running from PSP.
|
29
|
+
def psp?
|
30
|
+
!!(ua =~ /PSP/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Browser
|
2
|
+
module IE
|
3
|
+
TRIDENT_VERSION_REGEX = /Trident\/([0-9.]+)/
|
4
|
+
|
5
|
+
# Detect if browser is Internet Explorer.
|
6
|
+
def ie?
|
7
|
+
!!(ua =~ /MSIE/ && ua !~ /Opera/)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Detect if browser is Internet Explorer 6.
|
11
|
+
def ie6?
|
12
|
+
ie? && version == "6"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Detect if browser is Internet Explorer 7.
|
16
|
+
def ie7?
|
17
|
+
ie? && version == "7"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Detect if browser is Internet Explorer 8.
|
21
|
+
def ie8?
|
22
|
+
ie? && version == "8"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Detect if browser is Internet Explorer 9.
|
26
|
+
def ie9?
|
27
|
+
ie? && version == "9"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Detect if browser is Internet Explorer 10.
|
31
|
+
def ie10?
|
32
|
+
ie? && version == "10"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Detect if IE is running in compatibility mode.
|
36
|
+
def compatibility_view?
|
37
|
+
ie? && ua.match(TRIDENT_VERSION_REGEX) && version.to_i < ($1.to_i + 4)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
class Browser
|
2
|
+
module Language
|
3
|
+
LANGUAGES = {
|
4
|
+
"af" => "Afrikaans",
|
5
|
+
"sq" => "Albanian",
|
6
|
+
"eu" => "Basque",
|
7
|
+
"bg" => "Bulgarian",
|
8
|
+
"be" => "Byelorussian",
|
9
|
+
"ca" => "Catalan",
|
10
|
+
"zh" => "Chinese",
|
11
|
+
"zh-cn" => "Chinese/China",
|
12
|
+
"zh-tw" => "Chinese/Taiwan",
|
13
|
+
"zh-hk" => "Chinese/Hong Kong",
|
14
|
+
"zh-sg" => "Chinese/singapore",
|
15
|
+
"hr" => "Croatian",
|
16
|
+
"cs" => "Czech",
|
17
|
+
"da" => "Danish",
|
18
|
+
"nl" => "Dutch",
|
19
|
+
"nl-nl" => "Dutch/Netherlands",
|
20
|
+
"nl-be" => "Dutch/Belgium",
|
21
|
+
"en" => "English",
|
22
|
+
"en-gb" => "English/United Kingdom",
|
23
|
+
"en-us" => "English/United States",
|
24
|
+
"en-au" => "English/Australian",
|
25
|
+
"en-ca" => "English/Canada",
|
26
|
+
"en-nz" => "English/New Zealand",
|
27
|
+
"en-ie" => "English/Ireland",
|
28
|
+
"en-za" => "English/South Africa",
|
29
|
+
"en-jm" => "English/Jamaica",
|
30
|
+
"en-bz" => "English/Belize",
|
31
|
+
"en-tt" => "English/Trinidad",
|
32
|
+
"et" => "Estonian",
|
33
|
+
"fo" => "Faeroese",
|
34
|
+
"fa" => "Farsi",
|
35
|
+
"fi" => "Finnish",
|
36
|
+
"fr" => "French",
|
37
|
+
"fr-be" => "French/Belgium",
|
38
|
+
"fr-fr" => "French/France",
|
39
|
+
"fr-ch" => "French/Switzerland",
|
40
|
+
"fr-ca" => "French/Canada",
|
41
|
+
"fr-lu" => "French/Luxembourg",
|
42
|
+
"gd" => "Gaelic",
|
43
|
+
"gl" => "Galician",
|
44
|
+
"de" => "German",
|
45
|
+
"de-at" => "German/Austria",
|
46
|
+
"de-de" => "German/Germany",
|
47
|
+
"de-ch" => "German/Switzerland",
|
48
|
+
"de-lu" => "German/Luxembourg",
|
49
|
+
"de-li" => "German/Liechtenstein",
|
50
|
+
"el" => "Greek",
|
51
|
+
"he" => "Hebrew",
|
52
|
+
"he-il" => "Hebrew/Israel",
|
53
|
+
"hi" => "Hindi",
|
54
|
+
"hu" => "Hungarian",
|
55
|
+
"ie-ee" => "Internet Explorer/Easter Egg",
|
56
|
+
"is" => "Icelandic",
|
57
|
+
"id" => "Indonesian",
|
58
|
+
"in" => "Indonesian",
|
59
|
+
"ga" => "Irish",
|
60
|
+
"it" => "Italian",
|
61
|
+
"it-ch" => "Italian/ Switzerland",
|
62
|
+
"ja" => "Japanese",
|
63
|
+
"km" => "Khmer",
|
64
|
+
"km-kh" => "Khmer/Cambodia",
|
65
|
+
"ko" => "Korean",
|
66
|
+
"lv" => "Latvian",
|
67
|
+
"lt" => "Lithuanian",
|
68
|
+
"mk" => "Macedonian",
|
69
|
+
"ms" => "Malaysian",
|
70
|
+
"mt" => "Maltese",
|
71
|
+
"no" => "Norwegian",
|
72
|
+
"pl" => "Polish",
|
73
|
+
"pt" => "Portuguese",
|
74
|
+
"pt-br" => "Portuguese/Brazil",
|
75
|
+
"rm" => "Rhaeto-Romanic",
|
76
|
+
"ro" => "Romanian",
|
77
|
+
"ro-mo" => "Romanian/Moldavia",
|
78
|
+
"ru" => "Russian",
|
79
|
+
"ru-mo" => "Russian /Moldavia",
|
80
|
+
"gd" => "Scots Gaelic",
|
81
|
+
"sr" => "Serbian",
|
82
|
+
"sk" => "Slovack",
|
83
|
+
"sl" => "Slovenian",
|
84
|
+
"sb" => "Sorbian",
|
85
|
+
"es" => "Spanish",
|
86
|
+
"es-do" => "Spanish",
|
87
|
+
"es-ar" => "Spanish/Argentina",
|
88
|
+
"es-co" => "Spanish/Colombia",
|
89
|
+
"es-mx" => "Spanish/Mexico",
|
90
|
+
"es-es" => "Spanish/Spain",
|
91
|
+
"es-gt" => "Spanish/Guatemala",
|
92
|
+
"es-cr" => "Spanish/Costa Rica",
|
93
|
+
"es-pa" => "Spanish/Panama",
|
94
|
+
"es-ve" => "Spanish/Venezuela",
|
95
|
+
"es-pe" => "Spanish/Peru",
|
96
|
+
"es-ec" => "Spanish/Ecuador",
|
97
|
+
"es-cl" => "Spanish/Chile",
|
98
|
+
"es-uy" => "Spanish/Uruguay",
|
99
|
+
"es-py" => "Spanish/Paraguay",
|
100
|
+
"es-bo" => "Spanish/Bolivia",
|
101
|
+
"es-sv" => "Spanish/El salvador",
|
102
|
+
"es-hn" => "Spanish/Honduras",
|
103
|
+
"es-ni" => "Spanish/Nicaragua",
|
104
|
+
"es-pr" => "Spanish/Puerto Rico",
|
105
|
+
"sx" => "Sutu",
|
106
|
+
"sv" => "Swedish",
|
107
|
+
"sv-se" => "Swedish/Sweden",
|
108
|
+
"sv-fi" => "Swedish/Finland",
|
109
|
+
"ts" => "Thai",
|
110
|
+
"tn" => "Tswana",
|
111
|
+
"tr" => "Turkish",
|
112
|
+
"uk" => "Ukrainian",
|
113
|
+
"ur" => "Urdu",
|
114
|
+
"vi" => "Vietnamese",
|
115
|
+
"xh" => "Xshosa",
|
116
|
+
"ji" => "Yiddish",
|
117
|
+
"zu" => "Zulu"
|
118
|
+
}
|
119
|
+
|
120
|
+
# Set browser's preferred language
|
121
|
+
attr_writer :accept_language
|
122
|
+
|
123
|
+
# Return an array with all preferred languages that this browser accepts.
|
124
|
+
def accept_language
|
125
|
+
@accept_language
|
126
|
+
.gsub(/;q=[\d.]+/, "")
|
127
|
+
.split(",")
|
128
|
+
.collect {|l| l.downcase.gsub(/\s/m, "")}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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 BlackBerry
|
14
|
+
def blackberry?
|
15
|
+
!!(ua =~ /BlackBerry/)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def detect_mobile?
|
20
|
+
ua =~ /(Mobi(le)?|Symbian|MIDP|Windows CE)/ || blackberry? || psp? || opera_mini?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Browser
|
2
|
+
module Platform
|
3
|
+
# Detect if browser is Android.
|
4
|
+
def android?
|
5
|
+
!!(ua =~ /Android/ && !opera?)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Detect if browser is ios?.
|
9
|
+
def ios?
|
10
|
+
ipod? || ipad? || iphone?
|
11
|
+
end
|
12
|
+
|
13
|
+
# Detect if is iOS5.
|
14
|
+
def ios4?
|
15
|
+
ios? && !!(ua =~ /OS (4)/)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Detect if is iOS5.
|
19
|
+
def ios5?
|
20
|
+
ios? && !!(ua =~ /OS (5)/)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Detect if is iOS6.
|
24
|
+
def ios6?
|
25
|
+
ios? && !!(ua =~ /OS (6)/)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Detect if current platform is Macintosh.
|
29
|
+
def mac?
|
30
|
+
!!(ua =~ /Mac OS X/)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Detect if current platform is Windows.
|
34
|
+
def windows?
|
35
|
+
!!(ua =~ /Windows/)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Detect if current platform is Linux flavor.
|
39
|
+
def linux?
|
40
|
+
!!(ua =~ /Linux/)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return the platform.
|
44
|
+
def platform
|
45
|
+
case
|
46
|
+
when linux? then :linux
|
47
|
+
when mac? then :mac
|
48
|
+
when windows? then :windows
|
49
|
+
else
|
50
|
+
:other
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "uri"
|
2
|
+
|
3
|
+
class Browser
|
4
|
+
class Middleware
|
5
|
+
attr_reader :env, :request
|
6
|
+
|
7
|
+
def initialize(app, &block)
|
8
|
+
raise ArgumentError, "Browser::Middleware requires a block" unless block
|
9
|
+
|
10
|
+
@app = app
|
11
|
+
@block = block
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
@env = env
|
16
|
+
@request = Rack::Request.new(env)
|
17
|
+
|
18
|
+
path = catch(:redirected) do
|
19
|
+
Context.new(request).instance_eval(&@block)
|
20
|
+
end
|
21
|
+
|
22
|
+
path ? resolve_redirection(path) : run_app!
|
23
|
+
end
|
24
|
+
|
25
|
+
def resolve_redirection(path)
|
26
|
+
uri = URI.parse(path)
|
27
|
+
|
28
|
+
if uri.path == request.path
|
29
|
+
run_app!
|
30
|
+
else
|
31
|
+
redirect(path)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def redirect(path)
|
36
|
+
[301, {"Content-Type" => "text/html", "Location" => path}, []]
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_app!
|
40
|
+
@app.call(env)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|