ms_tools 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 wmerrell
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,9 @@
1
+ = MsTools
2
+
3
+ == Overview
4
+
5
+ This is a collection of tools that I use in my projects. The tools included
6
+ are helpers for use in the head section of a page, an assortment of helpers for
7
+ use in pages and some enhanced tools to help with
8
+ sanitizing input for pages.
9
+
@@ -0,0 +1,108 @@
1
+ module MsTools
2
+ module ApplicationHelpers
3
+
4
+ # Outputs the corresponding flash message if any are set
5
+ #
6
+ # This function is used to output the flash messages in a nice formated
7
+ # way. It is typically used in the application layout.
8
+ #
9
+ def flash_messages
10
+ messages = []
11
+ %w(notice warning).each do |msg|
12
+ messages << content_tag(:div, flash[msg.to_sym], :id => "flash-#{msg}") unless flash[msg.to_sym].blank?
13
+ end
14
+ if flash[:error].is_a?( Hash)
15
+ flash_to_display << activerecord_error_list(flash[:error])
16
+ else
17
+ flash_to_display = flash[:error]
18
+ end
19
+ messages << content_tag(:div, flash_to_display, :id => "flash-error") unless flash_to_display.blank?
20
+ raw(messages)
21
+ end
22
+
23
+ # Normalizes image file names
24
+ #
25
+ # This function tries to find the file based on the name supplied. In
26
+ # normal use you will only need to supply the image file name without
27
+ # any extention. It will check for the supplied name as is, and with
28
+ # .png, .gif, or .jpg extentions added to the supplied name, in the
29
+ # public, public/images, and public/images/icons directories. If the
30
+ # file is found, it's normalized path name is returned. Note: It will
31
+ # also match any file that is explictly specified.
32
+ #
33
+ def clean_imagefile_name(name='')
34
+ root = Rails.public_path
35
+ filename = ""
36
+ # Shortcut to handle the most common cases.
37
+ if FileTest.exist?( File.join( root, "/images/#{name}.png" ) )
38
+ filename = "/images/#{name}.png"
39
+ elsif FileTest.exist?( File.join( root, "/images/icons/#{name}.png" ) )
40
+ filename = "/images/icons/#{name}.png"
41
+ else
42
+ # If not, check all
43
+ ["", ".png", ".gif", ".jpg"].each do |ext|
44
+ # Check if full path has been specified
45
+ if FileTest.exist?( File.join( root, name + ext ) )
46
+ filename = name + ext
47
+ elsif FileTest.exist?( File.join( root, "/images/", name + ext ) )
48
+ filename = File.join( "/images/", name + ext )
49
+ elsif FileTest.exist?( File.join( root, "/images/icons/", name + ext ) )
50
+ filename = File.join( "/images/icons/", name + ext )
51
+ end
52
+ end
53
+ end
54
+ if filename.blank?
55
+ filename = "/images/broken.png"
56
+ end
57
+ filename
58
+ end
59
+
60
+ # Formats a "command_button" class link
61
+ #
62
+ # This function creates a link with an embedded image along with text. The
63
+ # link has a class of "command_button" added to it. It is expected that the
64
+ # "command_button" class will be formatted to resemble a button.
65
+ #
66
+ def command_button(text='', image='', url='', permission=nil, options = {})
67
+ options.stringify_keys!
68
+ text = text.blank? ? "" : text
69
+ img_tag = image_tag(clean_imagefile_name(image), :class=>"edit_icon", :alt=>" &raquo; ", :title=>text)
70
+ url = url.blank? ? "#" : url
71
+ options['class'] = options.has_key?('class') ? options['class'] + " command_button" : "command_button"
72
+
73
+ if permission.nil? || permission
74
+ link_to( img_tag + text, url, options )
75
+ end
76
+ end
77
+
78
+ # Formats a "menu_icon" class link
79
+ #
80
+ # This function creates a link with an embedded image along with text. The
81
+ # image has a class of "menu_icon" added to it. It is expected that the
82
+ # "menu_icon" class will be formatted to resemble a button.
83
+ #
84
+ def image_button(text='', image='', url='', permission=nil, options = {})
85
+ options.stringify_keys!
86
+ text = text.blank? ? "" : text
87
+ img_tag = image_tag(clean_imagefile_name(image), :class => 'menu_icon', :alt=>" &raquo; ", :title=>text)
88
+ url = url.blank? ? "#" : url
89
+
90
+ if permission.nil? || permission
91
+ link_to( img_tag + text, url, options )
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ def activerecord_error_list(errors)
98
+ error_list = '<ul class="error_list">'
99
+ error_list << errors.collect do |e, m|
100
+ "<li>#{e.humanize unless e == "base"} #{m}</li>"
101
+ end.to_s << '</ul>'
102
+ error_list
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+ ActionView::Base.send :include, MsTools::ApplicationHelpers
@@ -0,0 +1,7 @@
1
+ require "ms_tools"
2
+ require "rails"
3
+
4
+ module MsTools
5
+ class Engine < Rails::Engine
6
+ end
7
+ end
@@ -0,0 +1,125 @@
1
+ module MsTools
2
+ module HeadHelpers
3
+
4
+ # Adds inline javascript data to the head section of a page.
5
+ #
6
+ # The intent of this function is to simplify your view code when you need
7
+ # javascript specifically for a particular page.
8
+ #
9
+ # Assumes that there is yield call in the <head> section of your layout
10
+ # like this:
11
+ # <script type="text/javascript">
12
+ # <%= yield :javascript_data %>
13
+ # </script>
14
+ #
15
+ #
16
+ # === Usage:
17
+ # <%- javascript do -%>
18
+ # alert("Hello world!");
19
+ # <%- end -%>
20
+ #
21
+ # This function expects a block which will be the javascript you
22
+ # wish to add to the page.
23
+ #
24
+ def javascript(*args, &block)
25
+ if block_given?
26
+ content = capture(&block)
27
+ content_for(:javascript_data) { content }
28
+ end
29
+ end
30
+
31
+ # Adds javascript files to the head section of a page.
32
+ #
33
+ # The intent of this function is to simplify your view code when you need
34
+ # special javascript files for a particular page.
35
+ # This function may be called as many times as desired, the javascript files
36
+ # are added in the order they are called.
37
+ #
38
+ # Assumes that there is yield call in the <head> section of your layout
39
+ # like this:
40
+ # <%= yield :javascript_list %>
41
+ #
42
+ # All of the accumulated javascript files are added, in the order they were
43
+ # called when the page is generated.
44
+ #
45
+ # === Usage:
46
+ # <%- javascripts 'javascriptname' -%>
47
+ # or
48
+ # <%- javascripts ['javascriptname1', 'javascriptname2', ...] -%>
49
+ #
50
+ # The function takes either a string or and array of strings, and you
51
+ # may use an string that is valid for the +javascript_include_tag+ function.
52
+ # Be sure to include any paths for the file you wish to add.
53
+ #
54
+ def javascripts(*args)
55
+ items = args.class == Array ? args : args.to_a
56
+ items.each {|item|
57
+ content_for(:javascript_list) { javascript_include_tag item }
58
+ }
59
+ end
60
+
61
+ # Adds inline style information to the head section of a page.
62
+ #
63
+ # The intent of this function is to simplify your view code when you need
64
+ # special css style rules for a particular page.
65
+ #
66
+ # Assumes that there is yield call in the <head> section of your layout
67
+ # like this:
68
+ # <style type="text/css">
69
+ # <%= yield :stylesheet_data %>
70
+ # </style>
71
+ #
72
+ #
73
+ # === Usage:
74
+ # <%- stylesheet do -%>
75
+ # body {
76
+ # line-height: 1;
77
+ # color: black;
78
+ # background: white;
79
+ # }
80
+ # <%- end -%>
81
+ #
82
+ # This function expects a block which will be the css style rules you
83
+ # wish to add to the page. It can be any valid css text.
84
+ #
85
+ def stylesheet(*args, &block)
86
+ if block_given?
87
+ content = capture(&block)
88
+ content_for(:stylesheet_data) { content }
89
+ end
90
+ end
91
+
92
+ # Adds style sheet files to the head section of a page.
93
+ #
94
+ # The intent of this function is to simplify your view code when you need
95
+ # special style sheets for a particular page.
96
+ # This function may be called as many times as desired, the style sheets
97
+ # are added in the order they are called.
98
+ #
99
+ # Assumes that there is yield call in the <head> section of your layout
100
+ # like this:
101
+ # <%= yield :stylesheet_list %>
102
+ #
103
+ # All of the accumulated style sheets are added, in the order they were
104
+ # called when the page is generated.
105
+ #
106
+ # === Usage:
107
+ # <%- stylesheets 'stylesheetname' -%>
108
+ # or
109
+ # <%- stylesheets ['stylesheetname1', 'stylesheetname2', ...] -%>
110
+ #
111
+ # The function takes either a string or and array of strings, and you
112
+ # may use an string that is valid for the +stylesheet_link_tag+ function.
113
+ # Be sure to include any paths for the file you wish to add.
114
+ #
115
+ def stylesheets(*args)
116
+ items = args.class == Array ? args : args.to_a
117
+ items.each {|item|
118
+ content_for(:stylesheet_list) { stylesheet_link_tag item }
119
+ }
120
+ end
121
+
122
+ end
123
+ end
124
+
125
+ ActionView::Base.send :include, MsTools::HeadHelpers
@@ -0,0 +1,155 @@
1
+ module MsTools
2
+ module MsSanitize
3
+
4
+ module Config
5
+ DEFAULT = Sanitize::Config::DEFAULT.update({:remove_contents => ['script', 'embed', 'iframe']})
6
+ BASIC = Sanitize::Config::BASIC.update({:remove_contents => ['script', 'embed', 'iframe']})
7
+ RESTRICTED = Sanitize::Config::RESTRICTED.update({:remove_contents => ['script', 'embed', 'iframe']})
8
+ RELAXED = Sanitize::Config::RELAXED.update({:remove_contents => ['script', 'embed', 'iframe']})
9
+ EXTENDED = {
10
+ :elements => [
11
+ 'a', 'b', 'blockquote', 'br', 'caption', 'cite', 'code', 'col',
12
+ 'colgroup', 'dd', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
13
+ 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike',
14
+ 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead',
15
+ 'tr', 'u', 'ul'],
16
+
17
+ :attributes => {
18
+ 'a' => ['class', 'href', 'title'],
19
+ 'blockquote' => ['class', 'cite'],
20
+ 'br' => ['class'],
21
+ 'code' => ['class'],
22
+ 'col' => ['class', 'span', 'width'],
23
+ 'colgroup' => ['class', 'span', 'width'],
24
+ 'hr' => ['class'],
25
+ 'img' => ['class', 'align', 'alt', 'height', 'src', 'title', 'width', 'title'],
26
+ 'li' => ['class', 'title'],
27
+ 'ol' => ['class', 'start', 'type'],
28
+ 'p' => ['class', 'title'],
29
+ 'q' => ['class', 'cite'],
30
+ 'table' => ['border', 'class', 'cellspacing', 'cellpadding', 'summary', 'width'],
31
+ 'td' => ['abbr', 'axis', 'class', 'colspan', 'rowspan', 'width', 'title'],
32
+ 'th' => ['abbr', 'axis', 'class', 'colspan', 'rowspan', 'scope', 'width', 'title'],
33
+ 'ul' => ['class', 'type']
34
+ },
35
+
36
+ :protocols => {
37
+ 'a' => {'href' => ['ftp', 'http', 'https', 'mailto', :relative]},
38
+ 'blockquote' => {'cite' => ['http', 'https', :relative]},
39
+ 'img' => {'src' => ['http', 'https', :relative]},
40
+ 'q' => {'cite' => ['http', 'https', :relative]}
41
+ },
42
+
43
+ :remove_contents => ['script', 'embed', 'iframe']
44
+ }
45
+ end
46
+
47
+ # Returns a sanitized copy of _html_, using the settings in _config_ if
48
+ # specified.
49
+ def msclean(html, options = {})
50
+ config = options.delete(:config) || {}
51
+ radius = options.delete(:radius) || false
52
+ if( radius ) then
53
+ Sanitize.clean(html.gsub(/<r:([a-z0-9 _'"=-]+) \/>/i, '(r:\1 /)'), config).gsub('&#13;',"").gsub(/\(r:([a-z0-9 _'"=-]+) \/\)/i, '<r:\1 />')
54
+ else
55
+ Sanitize.clean(html, config).gsub('&#13;',"")
56
+ end
57
+ end
58
+
59
+ # Performs Sanitize#clean in place, returning _html_, or +nil+ if no changes
60
+ # were made.
61
+ def msclean!(html, options = {})
62
+ config = options.delete(:config) || {}
63
+ radius = options.delete(:radius) || false
64
+ if( radius ) then
65
+ Sanitize.clean!(html.gsub(/<r:([a-z0-9 _'"=-]+) \/>/i, '(r:\1 /)'), config).gsub('&#13;',"").gsub(/\(r:([a-z0-9 _'"=-]+) \/\)/i, '<r:\1 />')
66
+ else
67
+ Sanitize.clean!(html, config).gsub('&#13;',"")
68
+ end
69
+ end
70
+
71
+ # A sanitizer before filter that walks all parameters before any
72
+ # processing takes place.
73
+ #
74
+ # == Description
75
+ #
76
+ # This is based on the sanitize_params plugin written by Jay Laney, updated
77
+ # by Danny Sofer to work with the Sanitizer module that is now part of
78
+ # the Rails core.
79
+ #
80
+ # The original version of sanitize_params used Rick Olsen's white_list plugin,
81
+ # but as Rick pointed out some time ago, "I recently just refactored a lot of
82
+ # that code into the html tokenizer library. You can now access the classes
83
+ # directly as HTML::Sanitizer, HTML::LinkSanitizer, and HTML::WhiteListSanitizer."
84
+ #
85
+ # Danny Sofer's version of sanitize_params does exactly that. Otherwise,
86
+ # it is unchanged from Jay's original code designed for scrubbing your
87
+ # user input clean.
88
+ #
89
+ # I modified this to work with Ryan Grove's Sanitize gem which is required
90
+ # by this function.
91
+ #
92
+ # == Usage
93
+ #
94
+ # in application.rb:
95
+ #
96
+ # before_filter :sanitize_params
97
+ #
98
+ # Alternatively, add the filter to your controllers selectively.
99
+ #
100
+ # == Contact
101
+ #
102
+ # The original sanitize_params plugin was written by Jay Laney and is still
103
+ # available at http://code.google.com/p/sanitizeparams/
104
+ #
105
+ # This version was dereived from the forked version tweaked by Danny Sofer,
106
+ # which can be found at http://github.com/sofer/sanitize_params.
107
+ #
108
+ def sanitize_params(params = params)
109
+ params = walk_hash(params) if params
110
+ end
111
+
112
+ # Returns a sanitized copy of _html_, using the settings in _config_ if
113
+ # specified.
114
+ def sanitize(html, options = {})
115
+ msclean(html, options)
116
+ end
117
+
118
+ # Performs Sanitize#clean in place, returning _html_, or +nil+ if no changes
119
+ # were made.
120
+ def sanitize!(html, options = {})
121
+ msclean!(html, options)
122
+ end
123
+
124
+ private
125
+
126
+ def walk_hash(hash)
127
+ hash.keys.each do |key|
128
+ if hash[key].is_a? String
129
+ hash[key] = sanitize(hash[key])
130
+ elsif hash[key].is_a? Hash
131
+ hash[key] = walk_hash(hash[key])
132
+ elsif hash[key].is_a? Array
133
+ hash[key] = walk_array(hash[key])
134
+ end
135
+ end
136
+ hash
137
+ end
138
+
139
+ def walk_array(array)
140
+ array.each_with_index do |el,i|
141
+ if el.is_a? String
142
+ array[i] = sanitize(el)
143
+ elsif el.is_a? Hash
144
+ array[i] = walk_hash(el)
145
+ elsif el.is_a? Array
146
+ array[i] = walk_array(el)
147
+ end
148
+ end
149
+ array
150
+ end
151
+
152
+ end
153
+ end
154
+
155
+ ActionController::Base.send :include, MsTools::MsSanitize
data/lib/ms_tools.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'action_view'
2
+ require 'sanitize'
3
+ require 'nokogiri'
4
+ require 'ms_tools/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
5
+ require 'ms_tools/application_helpers'
6
+ require 'ms_tools/head_helpers'
7
+ require 'ms_tools/sanitize'
8
+ module MsTools
9
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'ms_tools'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestMsTools < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ms_tools
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
+ platform: ruby
12
+ authors:
13
+ - Will Merrell
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-13 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: nokogiri
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 4
33
+ - 3
34
+ version: 1.4.3
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: sanitize
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 29
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 1
50
+ version: 1.2.1
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: thoughtbot-shoulda
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ description: A collection of functions and tools I use in my projects. Longer description.
68
+ email: will@morelandsolutions.com
69
+ executables: []
70
+
71
+ extensions: []
72
+
73
+ extra_rdoc_files:
74
+ - LICENSE
75
+ - README.rdoc
76
+ files:
77
+ - lib/ms_tools.rb
78
+ - lib/ms_tools/application_helpers.rb
79
+ - lib/ms_tools/engine.rb
80
+ - lib/ms_tools/head_helpers.rb
81
+ - lib/ms_tools/sanitize.rb
82
+ - LICENSE
83
+ - README.rdoc
84
+ - test/test_ms_tools.rb
85
+ - test/helper.rb
86
+ has_rdoc: true
87
+ homepage: http://github.com/wmerrell/ms_tools
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options:
92
+ - --charset=UTF-8
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
111
+ - 0
112
+ version: "0"
113
+ requirements: []
114
+
115
+ rubyforge_project:
116
+ rubygems_version: 1.3.7
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: A collection of functions and tools I use in my projects.
120
+ test_files:
121
+ - test/test_ms_tools.rb
122
+ - test/helper.rb