quartermaster 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig ADDED
Binary file
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2008-05-06
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/quartermaster.rb
6
+ test/test_quartermaster.rb
data/README.txt ADDED
@@ -0,0 +1,60 @@
1
+ = quartermaster
2
+
3
+ * http://contentfree.rubyforge.org/quartermaster
4
+
5
+ == DESCRIPTION:
6
+
7
+ A collection of shortcuts and helpers for leveraging a request's env in Rails, such as including a browser-specific stylesheet if one exists or putting a short version of the user agent in the CSS classes of the body tag. This removes the need for most hacks or conditional comments since you can now do get browser-specific with your CSS rules (ex. body.ie6 div { ... })
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Short user agents for major browsers
12
+ * Detect and include browser-specific stylesheets
13
+ * Add short user agent to CSS classes which includes OS and browser info
14
+
15
+ == SYNOPSIS:
16
+
17
+ # Including classes in the body tag of an HTML layout when making a request with IE6/Win:
18
+ <body class="<%= user_agent_for_css %>"> #=> Results in: <body class="win ie ie6">
19
+
20
+ # Including browser-specific stylesheets, using Firefox 2 and a stylesheet at public/stylesheets/browsers/firefox2.css. It
21
+ # only includes stylesheets if they exist. Will look for stylesheets for the base browser - "firefox" - as well as
22
+ # version-specific - "firefox2"
23
+ <head>
24
+ <%= stylesheet_link_tag_for_browser %> #=> results in a link tag for the stylesheet(s) for the requesting browser
25
+ </head>
26
+
27
+ == CAVEATS:
28
+
29
+ If you use user_agent_for_css, you'll lose the ability to (usefully) page cache since the first requester's browser information would get cached.
30
+
31
+ Another trade-off if you're using stylesheet_link_tag_for_browser is that you have multiple stylesheet requests. If you want to consolidate your requests per page, don't use stylesheet_link_tag_for_browser and instead use a combination of user_agent_for_css and body.<short user agent> in your rules
32
+
33
+ == INSTALL:
34
+
35
+ * sudo gem install quartermaster
36
+
37
+ == LICENSE:
38
+
39
+ (The MIT License)
40
+
41
+ Copyright (c) 2008 FIX
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining
44
+ a copy of this software and associated documentation files (the
45
+ 'Software'), to deal in the Software without restriction, including
46
+ without limitation the rights to use, copy, modify, merge, publish,
47
+ distribute, sublicense, and/or sell copies of the Software, and to
48
+ permit persons to whom the Software is furnished to do so, subject to
49
+ the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be
52
+ included in all copies or substantial portions of the Software.
53
+
54
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
55
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
56
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
57
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
58
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
59
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
60
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/quartermaster.rb'
6
+
7
+ Hoe.new('quartermaster', Quartermaster::VERSION) do |p|
8
+ p.rubyforge_name = 'quartermaster' # if different than lowercase project name
9
+ p.developer('Dave Myron', 'dave.myron@contentfree.com')
10
+ end
11
+
12
+ # vim: syntax=Ruby
@@ -0,0 +1,52 @@
1
+ module Quartermaster
2
+ VERSION = '1.0.0'
3
+
4
+ module Helper
5
+ # Uses the output of +browser_from_user_agent+ to figure out what stylesheets to look for and then uses +stylesheet_link_tag+
6
+ # to produce the link tags. Stylesheets must appear in STYLESHEETS_DIR/browsers/ (STYLESHEETS_DIR is public/stylesheets by default) and be named the same as the output of +browser_from_user_agents+. If both firefox.css and firefox2.css, for example, are
7
+ # present and Firefox 2 makes a request, both stylesheets will be loaded. Takes any options that can be passed to
8
+ # +stylesheet_link_tag+
9
+ def stylesheet_link_tag_for_browser( options = {} )
10
+ agent_attributes = [os_from_user_agent] + browser_from_user_agent
11
+ agent_attributes.select{ |attribute| File.exists?( File.join(self.class::STYLESHEETS_DIR, 'browsers', "#{attribute}.css" )) }.collect{ |attribute| stylesheet_link_tag( attribute, options )}.to_s
12
+ end
13
+
14
+ # Very similar to +stylesheet_link_tag_for_browser+ except for javascripts
15
+ def javascript_include_tag_for_browser( options = {} )
16
+ agent_attributes = [os_from_user_agent] + browser_from_user_agent
17
+ agent_attributes.select{ |attribute| File.exists?( File.join(self.class::JAVASCRIPTS_DIR, 'browsers', "#{attribute}.js" )) }.collect{ |attribute| javascript_include_tag( attribute, options )}.to_s
18
+ end
19
+
20
+ # Returns a space-separated string of the OS and the short user agents for the requesting browser
21
+ def user_agent_for_css
22
+ "#{os_from_user_agent} #{browser_from_user_agent.join(' ')}"
23
+ end
24
+
25
+ # Returns an array containing the base browser name and a version-specific name (except for Konqueror) for the given +user_agent+ which defaults to Rails' +request.user_agent+
26
+ def browser_from_user_agent( user_agent = request.user_agent )
27
+ @browser_from_user_agent ||= case user_agent.downcase
28
+ when /opera[ \/](\d)/ then "opera opera#{$1}" # Have to check for opera before msie
29
+ when /msie (\d)/ then "ie ie#{$1}" # F U ie5.5 - todo: Support minor versions
30
+ when /firefox\/(\d)/ then "firefox firefox#{$1}"
31
+ when /safari\/([2-9])/ then "safari safari#{$1.to_i - 2}" # Safari uses the webkit build number. Only works with Safari 1.3+
32
+ when /rv:([^)]+)\) gecko/ then "gecko gecko#{$1}"
33
+ when /applewebkit\/(\d)/ then "webkit webkit#{$1}"
34
+ when /konqueror/ then 'konqueror'
35
+ end.split(' ')
36
+ end
37
+
38
+ # Returns a short version of the OS name for the given +user_agent+ which defaults to Rails' +request.user_agent+
39
+ def os_from_user_agent( user_agent = request.user_agent )
40
+ @os_from_user_agent ||= case user_agent.downcase
41
+ when /win/ then 'win'
42
+ when /mac/ then 'mac'
43
+ when /(linux|x11)/ then 'linux'
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ if defined?(RAILS_ROOT)
50
+ # Automatically include it into Rails
51
+ ActionView::Base.class_eval { include Quartermaster::Helper }
52
+ end
@@ -0,0 +1,161 @@
1
+ require './lib/quartermaster'
2
+ require 'rubygems'
3
+ require 'spec'
4
+
5
+ class QMTest
6
+ STYLESHEETS_DIR = 'path/to/stylesheets'
7
+ JAVASCRIPTS_DIR = 'path/to/javascripts'
8
+ include Quartermaster::Helper
9
+
10
+ # Mock a couple ActionView helpers
11
+ def stylesheet_link_tag(*sources)
12
+ sources.pop if sources.last.is_a?(Hash)
13
+ "<link for #{sources.join(',')}>"
14
+ end
15
+
16
+ def javascript_include_tag(*sources)
17
+ sources.pop if sources.last.is_a?(Hash)
18
+ "<script for #{sources.join(',')}>"
19
+ end
20
+ end
21
+
22
+ USER_AGENTS = {
23
+ :firefox2 => 'Mozilla/5.0 (Windows; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9',
24
+ :firefox3 => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9b5) Gecko/2008032619 Firefox/3.0b5',
25
+ :ie6 => 'Mozilla/4.0 (Windows; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)',
26
+ :ie7 => 'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)',
27
+ :safari2 => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS; en-en) AppleWebKit/412 (KHTML, like Gecko) Safari/412',
28
+ :safari3 => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/522.11 (KHTML, like Gecko) Version/3.0.2 Safari/522.12',
29
+ :opera8 => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.00',
30
+ :opera9 => 'Opera/9.00 (Windows NT 5.1; U; en)',
31
+ :konqueror => 'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.9 (like Gecko)'
32
+ }
33
+ OS_USER_AGENTS = {
34
+ :mac => USER_AGENTS[:safari3],
35
+ :win => USER_AGENTS[:ie6],
36
+ :linux => USER_AGENTS[:konqueror]
37
+ }
38
+
39
+ describe 'Quartermaster' do
40
+ before(:each) do
41
+ @qm = QMTest.new
42
+ end
43
+
44
+ USER_AGENTS.each do |short_agent_name, user_agent|
45
+ it "should correctly detect #{short_agent_name}" do
46
+ @qm.browser_from_user_agent( user_agent ).last.should == short_agent_name.to_s
47
+ end
48
+ end
49
+
50
+ describe 'after a request has been made' do
51
+ before(:each) do
52
+ @request = mock('Request', :user_agent => USER_AGENTS[:firefox2])
53
+ @qm.stub!(:request).and_return(@request)
54
+ end
55
+
56
+ describe 'when calculating classes for CSS' do
57
+ OS_USER_AGENTS.each do |os, user_agent|
58
+ describe "for #{os}" do
59
+ it "should include '#{os}' in the classes" do
60
+ @request.stub!(:user_agent).and_return(user_agent)
61
+ @qm.user_agent_for_css.split(' ').should include(os.to_s)
62
+ end
63
+ end
64
+ end
65
+
66
+ USER_AGENTS.each do |browser, user_agent|
67
+ describe "for #{browser}" do
68
+ before(:each) do
69
+ @request.stub!(:user_agent).and_return(user_agent)
70
+ end
71
+
72
+ it "should include '#{browser}' in the classes" do
73
+ @qm.user_agent_for_css.split(' ').should include(browser.to_s)
74
+ end
75
+
76
+ if browser.to_s =~ /\d$/
77
+ it "should include the base browser name '#{browser.to_s[0..-2]}' in the classes" do
78
+ @qm.user_agent_for_css.split(' ').should include(browser.to_s[0..-2])
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ # Uses mocked helpers defined in QMTest class
86
+ describe 'when creating stylesheet link tags' do
87
+ before(:each) do
88
+ %w(win.css firefox.css firefox2.css).each do |file|
89
+ File.stub!(:exists?).with(File.join(QMTest::STYLESHEETS_DIR, 'browsers', file )).and_return(true)
90
+ end
91
+ end
92
+
93
+ def expected_output_for( *sources )
94
+ sources.collect{ |attribute| @qm.stylesheet_link_tag(attribute)}.to_s
95
+ end
96
+
97
+ it "should create links to the os file, the browser-base file, and the browser-specific file" do
98
+ @qm.stylesheet_link_tag_for_browser.should == expected_output_for( *%w(win firefox firefox2) )
99
+ end
100
+
101
+ describe "and the OS-specific file doesn't exist" do
102
+ it "should not create a link to the file" do
103
+ File.stub!(:exists?).with(File.join(QMTest::STYLESHEETS_DIR, 'browsers', 'win.css')).and_return(false)
104
+ @qm.stylesheet_link_tag_for_browser.should == expected_output_for( *%w(firefox firefox2) )
105
+ end
106
+ end
107
+
108
+ describe "and the browser-base version doesn't exist" do
109
+ it "should not create a link to the file" do
110
+ File.stub!(:exists?).with(File.join(QMTest::STYLESHEETS_DIR, 'browsers', 'firefox.css')).and_return(false)
111
+ @qm.stylesheet_link_tag_for_browser.should == expected_output_for( *%w(win firefox2) )
112
+ end
113
+ end
114
+
115
+ describe "and the browser-specific version doesn't exist" do
116
+ it "should not create a link to the file" do
117
+ File.stub!(:exists?).with(File.join(QMTest::STYLESHEETS_DIR, 'browsers', 'firefox2.css')).and_return(false)
118
+ @qm.stylesheet_link_tag_for_browser.should == expected_output_for( *%w(win firefox) )
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+ describe 'when creating javascript include tags' do
125
+ before(:each) do
126
+ %w(win.js firefox.js firefox2.js).each do |file|
127
+ File.stub!(:exists?).with(File.join(QMTest::JAVASCRIPTS_DIR, 'browsers', file )).and_return(true)
128
+ end
129
+ end
130
+
131
+ def expected_output_for( *sources )
132
+ sources.collect{ |attribute| @qm.javascript_include_tag(attribute)}.to_s
133
+ end
134
+
135
+ it "should create script tags for the os file, the browser-base file, and the browser-specific file" do
136
+ @qm.javascript_include_tag_for_browser.should == expected_output_for( *%w(win firefox firefox2) )
137
+ end
138
+
139
+ describe "and the OS-specific file doesn't exist" do
140
+ it "should not create a script tag for the file" do
141
+ File.stub!(:exists?).with(File.join(QMTest::JAVASCRIPTS_DIR, 'browsers', 'win.js')).and_return(false)
142
+ @qm.javascript_include_tag_for_browser.should == expected_output_for( *%w(firefox firefox2) )
143
+ end
144
+ end
145
+
146
+ describe "and the browser-base version doesn't exist" do
147
+ it "should not create a script tag for the file" do
148
+ File.stub!(:exists?).with(File.join(QMTest::JAVASCRIPTS_DIR, 'browsers', 'firefox.js')).and_return(false)
149
+ @qm.javascript_include_tag_for_browser.should == expected_output_for( *%w(win firefox2) )
150
+ end
151
+ end
152
+
153
+ describe "and the browser-specific version doesn't exist" do
154
+ it "should not create a script tag for the file" do
155
+ File.stub!(:exists?).with(File.join(QMTest::JAVASCRIPTS_DIR, 'browsers', 'firefox2.js')).and_return(false)
156
+ @qm.javascript_include_tag_for_browser.should == expected_output_for( *%w(win firefox) )
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quartermaster
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dave Myron
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDQjCCAiqgAwIBAgIBADANBgkqhkiG9w0BAQUFADBHMRMwEQYDVQQDDApkYXZl
14
+ Lm15cm9uMRswGQYKCZImiZPyLGQBGRYLY29udGVudGZyZWUxEzARBgoJkiaJk/Is
15
+ ZAEZFgNjb20wHhcNMDgwNDE3MTAwNTMzWhcNMDkwNDE3MTAwNTMzWjBHMRMwEQYD
16
+ VQQDDApkYXZlLm15cm9uMRswGQYKCZImiZPyLGQBGRYLY29udGVudGZyZWUxEzAR
17
+ BgoJkiaJk/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
18
+ AQDS5jTexxypvZPqoIRWYcbNGbbgHMn5pd2dUA74fq5IJ0y0J9TK/xy2Ncf8Hv6l
19
+ o43531AmDVlPQ7aTTZfqDHQQEoCsHiTxtIc8S3mRQ03exGG+sJIq5Fsgzqg2jvQh
20
+ MF3lWjVgENU8/INxpW4f/iST/ojn/PciYSIKs6SBcm9tHfU/jiMOT0qxCkyVAxM0
21
+ 0rD/yPQyPb7ogUNsO3RU1v5KBrlcV3lQPRQyRCDUpJ6H0AmeAa4iax/xfK0d/ta+
22
+ A9t4MmelIMUohH3VYEgYzCN/SnJsLMcEWbaXYFJMUUk07f+EmV060VUi4vsqvrMy
23
+ vyRmhHyxBuiyNNoSi/wfF3ebAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQD
24
+ AgSwMB0GA1UdDgQWBBSYmhWA9lg6R++f6Z0m5/ZJ8mwTAzANBgkqhkiG9w0BAQUF
25
+ AAOCAQEANprOIqYQsh0myh1GeHwTYo75bFHeMns5kkx44pVRSNWO4M5WEVFztyqO
26
+ VW8ZS4aHOqZ/XvOZ3YIP0mNNJEOM3jVirbdRBBnu75q87xDuPX0HVkk687qXFfJ7
27
+ Qb+KYshgOEn3n1iBzL6zIYyPOFRxFBEeix7uAZw9gq/EJf7isDToYKG+BE+q53ES
28
+ i/ul3Zg65QMGyXWBJlDEcQ7bxD/+pdUhOqew5tBuMvgxB/9XUPTCTLK9rfhakiBd
29
+ ZOWAbHDEFtZtQMT5GUHvuZ5jqfEKsE8tkFfFnUPY7DwpqWKkhuQzmmunB2J9aykn
30
+ arkBVHd8TABNoJ+MQvwL/7sCwSTiTg==
31
+ -----END CERTIFICATE-----
32
+
33
+ date: 2008-05-06 00:00:00 -07:00
34
+ default_executable:
35
+ dependencies:
36
+ - !ruby/object:Gem::Dependency
37
+ name: hoe
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.5.1
44
+ version:
45
+ description: A collection of shortcuts and helpers for leveraging a request's env in Rails, such as including a browser-specific stylesheet if one exists or putting a short version of the user agent in the CSS classes of the body tag. This removes the need for most hacks or conditional comments since you can now do get browser-specific with your CSS rules (ex. body.ie6 div { ... })
46
+ email:
47
+ - dave.myron@contentfree.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - History.txt
54
+ - Manifest.txt
55
+ - README.txt
56
+ files:
57
+ - History.txt
58
+ - Manifest.txt
59
+ - README.txt
60
+ - Rakefile
61
+ - lib/quartermaster.rb
62
+ - test/test_quartermaster.rb
63
+ has_rdoc: true
64
+ homepage: http://contentfree.rubyforge.org/quartermaster
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --main
68
+ - README.txt
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project: quartermaster
86
+ rubygems_version: 1.1.1
87
+ signing_key:
88
+ specification_version: 2
89
+ summary: A collection of shortcuts and helpers for leveraging a request's env in Rails, such as including a browser-specific stylesheet if one exists or putting a short version of the user agent in the CSS classes of the body tag
90
+ test_files:
91
+ - test/test_quartermaster.rb
metadata.gz.sig ADDED
Binary file