simple-useragent 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +46 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/lib/simple-useragent.rb +48 -0
- data/simple-useragent.gemspec +61 -0
- data/spec/simple-useragent_spec.rb +69 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- metadata +76 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Gal Steinitz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
= simple-useragent
|
2
|
+
|
3
|
+
The useragent gem provides a few utilities related to browser detection. It has two main uses, described below:
|
4
|
+
|
5
|
+
1. The "somewhat less hacky CSS browser targetting"
|
6
|
+
2. Mobile / Desktop / iPhone / Blackberry detection
|
7
|
+
|
8
|
+
Details:
|
9
|
+
|
10
|
+
1. The "somewhat less hacky CSS browser targetting"
|
11
|
+
|
12
|
+
Admittedly targeting CSS to a specific browser is a bad practice that should generally be avoided. For more details about why browser detection in general is a bad idea, see http://www.quirksmode.org/js/support.html. However sometimes there is no choice - especially under time constraints.
|
13
|
+
|
14
|
+
Add to your body tag:
|
15
|
+
|
16
|
+
<body class='<%=UserAgent::browser(request)%>'>
|
17
|
+
|
18
|
+
This will add one of (ie6 | ie7 | ie8 | firefox | safari | chrome) as a class to your body tag. Then, instead of using the classic browser specific CSS hacks such as:
|
19
|
+
|
20
|
+
/* IE7 */
|
21
|
+
*:first-child+html #content {
|
22
|
+
height: 500px;
|
23
|
+
}
|
24
|
+
|
25
|
+
now you can do this:
|
26
|
+
|
27
|
+
.ie7 #content {
|
28
|
+
height: 500px;
|
29
|
+
}
|
30
|
+
|
31
|
+
Which is both cleaner, and self documenting.
|
32
|
+
|
33
|
+
2. Mobile / Desktop / iPhone / Blackberry detection
|
34
|
+
|
35
|
+
The following new methods are available to you:
|
36
|
+
|
37
|
+
UserAgent::is_desktop?
|
38
|
+
UserAgent::is_mobile?
|
39
|
+
UserAgent::is_blackberry?
|
40
|
+
UserAgent::is_iphone?
|
41
|
+
|
42
|
+
The is_mobile? and is_desktop? methods are using a minimalistic approach, converted from the python script here: http://gist.github.com/88057
|
43
|
+
|
44
|
+
The theory is that since there are a lot more mobile user agents than there are desktop user agents (hundreds or even thousands) - we detect the known list of desktop user agents, and if its not one of those we assume that it is mobile. It works surprisingly well in the vast majority of cases. So far I've only seen it fail with spoofed or malformed user agents.
|
45
|
+
|
46
|
+
Copyright (c) 2009 Gal Steinitz. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "simple-useragent"
|
8
|
+
gem.summary = "provides a few utilities related to browser detection"
|
9
|
+
gem.description = %%
|
10
|
+
|
11
|
+
The useragent gem provides a few utilities related to browser detection. It has two main uses, described below:
|
12
|
+
|
13
|
+
1. The "somewhat less hacky CSS browser targetting"
|
14
|
+
2. Mobile / Desktop / iPhone / Blackberry detection
|
15
|
+
%
|
16
|
+
gem.email = "gal@steinitz.com"
|
17
|
+
gem.homepage = "http://thespottyblog.wordpress.com"
|
18
|
+
gem.authors = ["Gal Steinitz"]
|
19
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
20
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
34
|
+
spec.libs << 'lib' << 'spec'
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :spec => :check_dependencies
|
40
|
+
|
41
|
+
task :default => :spec
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'rcov/rcovtask'
|
45
|
+
Rcov::RcovTask.new do |test|
|
46
|
+
test.libs << 'test'
|
47
|
+
test.pattern = 'test/**/test_*.rb'
|
48
|
+
test.verbose = true
|
49
|
+
end
|
50
|
+
rescue LoadError
|
51
|
+
task :rcov do
|
52
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
task :test => :check_dependencies
|
57
|
+
|
58
|
+
task :default => :test
|
59
|
+
|
60
|
+
require 'rake/rdoctask'
|
61
|
+
Rake::RDocTask.new do |rdoc|
|
62
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
63
|
+
|
64
|
+
rdoc.rdoc_dir = 'rdoc'
|
65
|
+
rdoc.title = "useragent #{version}"
|
66
|
+
rdoc.rdoc_files.include('README*')
|
67
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
68
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#converted from the python script here: http://gist.github.com/88057
|
2
|
+
class SimpleUserAgent
|
3
|
+
|
4
|
+
# Some mobile browsers which look like desktop browsers.
|
5
|
+
MOBILE = /(iphone|ipod|blackberry|android|palm|windows\s+ce)/i
|
6
|
+
DESKTOP = /(windows|linux|os\s+[x9]|solaris|bsd)/i
|
7
|
+
BOT = /(spider|crawl|slurp|bot)/i
|
8
|
+
|
9
|
+
#Anything that looks like a phone isn't a desktop.
|
10
|
+
#Anything that looks like a desktop probably is.
|
11
|
+
#Anything that looks like a bot should default to desktop.
|
12
|
+
def self.is_desktop?(request_or_user_agent)
|
13
|
+
user_agent = get_user_agent(request_or_user_agent)
|
14
|
+
!(user_agent =~ MOBILE) && !!(user_agent =~ DESKTOP) || !!(user_agent =~ BOT)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.is_mobile?(request_or_user_agent)
|
18
|
+
!is_desktop?(request_or_user_agent)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.is_iphone?(request_or_user_agent)
|
22
|
+
user_agent = get_user_agent(request_or_user_agent)
|
23
|
+
!!(user_agent =~ /(Mobile\/.+Safari)/)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.is_blackberry?(request_or_user_agent)
|
27
|
+
user_agent = get_user_agent(request_or_user_agent)
|
28
|
+
!!(user_agent =~ /BlackBerry/)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Some mobile browsers put the User-Agent in a HTTP-X header
|
32
|
+
def self.get_user_agent(request_or_user_agent)
|
33
|
+
return request_or_user_agent if request_or_user_agent.kind_of? String
|
34
|
+
request_or_user_agent.env['HTTP_X_OPERAMINI_PHONE_UA'] ||
|
35
|
+
request_or_user_agent.env['HTTP_X_SKYFIRE_PHONE'] ||
|
36
|
+
request_or_user_agent.env['HTTP_USER_AGENT']
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.browser(request_or_user_agent)
|
40
|
+
user_agent = get_user_agent(request_or_user_agent)
|
41
|
+
return 'firefox' if user_agent =~ /Firefox/
|
42
|
+
return 'chrome' if user_agent =~ /Chrome/
|
43
|
+
return 'safari' if user_agent =~ /Safari/
|
44
|
+
return 'ie8' if user_agent =~ /MSIE 8/
|
45
|
+
return 'ie7' if user_agent =~ /MSIE 7/
|
46
|
+
return 'ie6' if user_agent =~ /MSIE 6/
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{simple-useragent}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Gal Steinitz"]
|
12
|
+
s.date = %q{2009-12-13}
|
13
|
+
s.description = %q{
|
14
|
+
|
15
|
+
The useragent gem provides a few utilities related to browser detection. It has two main uses, described below:
|
16
|
+
|
17
|
+
1. The "somewhat less hacky CSS browser targetting"
|
18
|
+
2. Mobile / Desktop / iPhone / Blackberry detection
|
19
|
+
}
|
20
|
+
s.email = %q{gal@steinitz.com}
|
21
|
+
s.extra_rdoc_files = [
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc"
|
24
|
+
]
|
25
|
+
s.files = [
|
26
|
+
".document",
|
27
|
+
".gitignore",
|
28
|
+
"LICENSE",
|
29
|
+
"README.rdoc",
|
30
|
+
"Rakefile",
|
31
|
+
"VERSION",
|
32
|
+
"lib/simple-useragent.rb",
|
33
|
+
"simple-useragent.gemspec",
|
34
|
+
"spec/simple-useragent_spec.rb",
|
35
|
+
"spec/spec.opts",
|
36
|
+
"spec/spec_helper.rb"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://thespottyblog.wordpress.com}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.5}
|
42
|
+
s.summary = %q{provides a few utilities related to browser detection}
|
43
|
+
s.test_files = [
|
44
|
+
"spec/simple-useragent_spec.rb",
|
45
|
+
"spec/spec_helper.rb"
|
46
|
+
]
|
47
|
+
|
48
|
+
if s.respond_to? :specification_version then
|
49
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
50
|
+
s.specification_version = 3
|
51
|
+
|
52
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
53
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
56
|
+
end
|
57
|
+
else
|
58
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
SAMPLE_BLACKBERRY_USER_AGENT_STRING = "BlackBerry9630/4.7.1.40 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/105"
|
4
|
+
|
5
|
+
describe "SimpleUserAgent" do
|
6
|
+
it "correctly detects an iphone user agent" do
|
7
|
+
iphone =
|
8
|
+
%%
|
9
|
+
Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)
|
10
|
+
AppleWebKit/420+ (KHTML, like Gecko) Version/3.0
|
11
|
+
Mobile/1A543a Safari/419.3
|
12
|
+
%
|
13
|
+
SimpleUserAgent::is_iphone?(iphone).should == true
|
14
|
+
SimpleUserAgent::is_blackberry?(iphone).should == false
|
15
|
+
SimpleUserAgent::is_mobile?(iphone).should == true
|
16
|
+
SimpleUserAgent::is_desktop?(iphone).should == false
|
17
|
+
end
|
18
|
+
|
19
|
+
it "correctly detects a blackberry user agent" do
|
20
|
+
blackberry = "BlackBerry9630/4.7.1.40 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/105"
|
21
|
+
SimpleUserAgent::is_blackberry?(blackberry).should == true
|
22
|
+
SimpleUserAgent::is_iphone?(blackberry).should == false
|
23
|
+
SimpleUserAgent::is_mobile?(blackberry).should == true
|
24
|
+
SimpleUserAgent::is_desktop?(blackberry).should == false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "correctly detects chrome user agent" do
|
28
|
+
chrome = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.30 Safari/532.5"
|
29
|
+
SimpleUserAgent::is_desktop?(chrome).should == true
|
30
|
+
SimpleUserAgent::is_mobile?(chrome).should == false
|
31
|
+
SimpleUserAgent::browser(chrome).should == 'chrome'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "correctly detects firefox 3.5 user agent" do
|
35
|
+
firefox_3_5 = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 "
|
36
|
+
SimpleUserAgent::is_desktop?(firefox_3_5).should == true
|
37
|
+
SimpleUserAgent::is_mobile?(firefox_3_5).should == false
|
38
|
+
SimpleUserAgent::browser(firefox_3_5).should == 'firefox'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "correctly detects safari 4 user agent" do
|
42
|
+
safari_4 = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_1; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
|
43
|
+
SimpleUserAgent::is_desktop?(safari_4).should == true
|
44
|
+
SimpleUserAgent::is_mobile?(safari_4).should == false
|
45
|
+
SimpleUserAgent::browser(safari_4).should == 'safari'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "correctly detects ie 6 user agent" do
|
49
|
+
ie6 = "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"
|
50
|
+
SimpleUserAgent::is_desktop?(ie6).should == true
|
51
|
+
SimpleUserAgent::is_mobile?(ie6).should == false
|
52
|
+
SimpleUserAgent::browser(ie6).should == 'ie6'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "correctly detects ie 7 user agent" do
|
56
|
+
ie7 = "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; el-GR)"
|
57
|
+
SimpleUserAgent::is_desktop?(ie7).should == true
|
58
|
+
SimpleUserAgent::is_mobile?(ie7).should == false
|
59
|
+
SimpleUserAgent::browser(ie7).should == 'ie7'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "correctly detects ie 8 user agent" do
|
63
|
+
ie8 = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3)"
|
64
|
+
SimpleUserAgent::is_desktop?(ie8).should == true
|
65
|
+
SimpleUserAgent::is_mobile?(ie8).should == false
|
66
|
+
SimpleUserAgent::browser(ie8).should == 'ie8'
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-useragent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gal Steinitz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-13 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.9
|
24
|
+
version:
|
25
|
+
description: "\n \n The useragent gem provides a few utilities related to browser detection. It has two main uses, described below:\n\n 1. The \"somewhat less hacky CSS browser targetting\"\n 2. Mobile / Desktop / iPhone / Blackberry detection\n "
|
26
|
+
email: gal@steinitz.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- lib/simple-useragent.rb
|
42
|
+
- simple-useragent.gemspec
|
43
|
+
- spec/simple-useragent_spec.rb
|
44
|
+
- spec/spec.opts
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://thespottyblog.wordpress.com
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.5
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: provides a few utilities related to browser detection
|
74
|
+
test_files:
|
75
|
+
- spec/simple-useragent_spec.rb
|
76
|
+
- spec/spec_helper.rb
|