icon_links 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
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.md ADDED
@@ -0,0 +1,10 @@
1
+ IconLinks
2
+ =========
3
+ Easily link icons of your choosing with handy helpers. Works great with Silk icons.
4
+
5
+
6
+ Example
7
+ =======
8
+ Example goes here.
9
+
10
+ Copyright (c) 2008-2010 [Nate Wiger](http://nateware.com), released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the icon_links plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the icon_links plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'IconLinks'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,182 @@
1
+ module IconLinks
2
+ module MethodMissing
3
+ include ViewHelpers
4
+
5
+ # Handle missing methods so we can do fancy URL hooks.
6
+ # This is what gives us "edit_player_icon" and "new_game_icon"
7
+ def method_missing_with_icon_links(method_id, *args)
8
+ method = method_id.to_s
9
+
10
+ # special catch for "run_icon", where it really means "run_run_icon"
11
+ method = "#{$1}_#{$1}_icon" if method =~ /^([a-z]+)_icon$/
12
+ if method =~ /^([a-z]+)_(.+)_icon$/
13
+ options = args.last.is_a?(Hash) ? args.pop : {}
14
+ if options.has_key?(:if)
15
+ return icon_tag(:clear) unless options.delete(:if)
16
+ end
17
+ type = $1
18
+ meth = $2
19
+ icon = options.delete(:icon) || type
20
+ unless label = options.delete(:label)
21
+ label = meth.dup
22
+ IconLinks.remove_prefixes_for_labels.each {|prefix| break if label.sub!(/^#{prefix}_/, '')}
23
+ label = label.titleize
24
+ end
25
+
26
+ # Note: We pass *either* args OR options to a given xxx_path() method,
27
+ # depending on whether it's a collection or member method.
28
+ url = ''
29
+ case type
30
+
31
+ when 'new'
32
+ url = send("new_#{meth}_path", options)
33
+ #options[:rel] = "gb_page_center[600, 500]" # greybox
34
+ options[:title] ||= "Create a new #{label}"
35
+ return link_icon(icon, url, options)
36
+
37
+ when 'ajaxnew'
38
+ url = send("new_#{meth}_path", options)
39
+ #options[:rel] = "gb_page_center[600, 500]" # greybox
40
+ options[:title] ||= "Create a new #{label}"
41
+ return link_icon(icon, url, options)
42
+
43
+ when 'edit'
44
+ url = send("edit_#{meth}_path", args)
45
+ #options[:rel] = "gb_page_center[600, 500]" # greybox
46
+ options[:title] ||= "Edit this #{label}"
47
+ return link_icon(icon, url, options)
48
+
49
+ when 'delete'
50
+ url = send("#{meth}_path", args)
51
+ options[:method] ||= :delete
52
+ options[:title] ||= "Delete this #{label}"
53
+ return link_icon(icon, url, options)
54
+
55
+ when 'ajaxdelete'
56
+ # Delete a record with an id, ala user_path(user)
57
+ # Fancy AJAX, so that it deletes the row in-place
58
+ options[:url] ||= send("#{meth}_path", args)
59
+ options[:method] ||= 'delete'
60
+ show = options.delete(:show) || args.first
61
+ target = show.is_a?(ActiveRecord::Base) ? "#{show.class.name.to_s.underscore}_#{show.to_param}" : "#{show.to_param}"
62
+ #options[:update] ||= target
63
+ options[:success] ||= "$('#{options[:update]}').hide;alert('success');"
64
+
65
+ # I hate that sometimes in Rails, you need a fucking :html subelement
66
+ htmlopt = {:title => "Delete this #{label}"}
67
+
68
+ # If no condition, set a toggle so that we tell if we have clicked
69
+ # on the button, and can collapse it appropriately.
70
+ unless options[:condition]
71
+ options[:id] = "#{options[:update]}_icon"
72
+ end
73
+ return link_to_remote(icon_tag(type, :id => options[:id]), options, htmlopt)
74
+
75
+ when 'list'
76
+ # Main index, this does NOT have an id, ie users_path
77
+ # Fancy AJAX, so that it expands/collapses a sub-row
78
+ options_without_update = options.dup
79
+ options_without_update.delete(:update)
80
+ url = send("#{meth.pluralize}_path", options_without_update)
81
+ show = options.delete(:show) || options.values.first
82
+ target = show.is_a?(ActiveRecord::Base) ? "show_#{show.class.name.to_s.underscore}_#{show.to_param}" : "show_#{show.to_param}"
83
+ options[:update] ||= target
84
+ options[:url] ||= url
85
+ options[:method] ||= 'get'
86
+ options[:complete] ||= "$('#{options[:update]}').show();"
87
+
88
+ # I hate that sometimes in Rails, you need a fucking :html subelement
89
+ htmlopt = {:title => "List #{label.pluralize}"}
90
+
91
+ # If no condition, set a toggle so that we tell if we have clicked
92
+ # on the button, and can collapse it appropriately.
93
+ extra_js = ''
94
+ unless options[:condition]
95
+ options[:id] = "#{options[:update]}_icon"
96
+ var = "loaded_#{options[:update]}"
97
+ options[:before] =
98
+ "#{var} = !#{var};" +
99
+ " if (#{var}) { $('#{options[:update]}').hide();"+
100
+ " $('#{options[:id]}').src = '#{icon_url(:show)}'; return false }"+
101
+ " else { $('#{options[:id]}').src = '#{icon_url(:loading)}' }"
102
+ options[:complete] += "$('#{options[:id]}').src = '#{icon_url(:hide)}';"
103
+ # Don't use javascript_tag or, ironically, Prototype chokes
104
+ extra_js = '<script type="text/javascript">' +
105
+ "#{var} = true;" + '</script>'
106
+ end
107
+ return extra_js + link_to_remote(icon_tag(:show, :id => options[:id]), options, htmlopt)
108
+
109
+ when 'show'
110
+ # Show a record with an id, ala user_path(user)
111
+ # Fancy AJAX, so that it expands/collapses a sub-row
112
+ options[:url] ||= send("#{meth}_path", args)
113
+ options[:method] ||= 'get'
114
+ show = options.delete(:show) || args.first
115
+ target = show.is_a?(ActiveRecord::Base) ? "show_#{show.class.name.to_s.underscore}_#{show.to_param}" : "show_#{show.to_param}"
116
+ options[:update] ||= target
117
+ options[:complete] ||= "$('#{options[:update]}').show();"
118
+
119
+ # I hate that sometimes in Rails, you need a fucking :html subelement
120
+ htmlopt = {:title => "Show more about this #{label}"}
121
+
122
+ # If no condition, set a toggle so that we tell if we have clicked
123
+ # on the button, and can collapse it appropriately.
124
+ extra_js = ''
125
+ unless options[:condition]
126
+ options[:id] = "#{options[:update]}_icon"
127
+ var = "loaded_#{options[:update]}"
128
+ options[:before] =
129
+ "#{var} = !#{var};" +
130
+ " if (#{var}) { $('#{options[:update]}').hide();"+
131
+ " $('#{options[:id]}').src = '#{icon_url(:show)}'; return false }"+
132
+ " else { $('#{options[:id]}').src = '#{icon_url(:loading)}' }"
133
+ options[:complete] += "$('#{options[:id]}').src = '#{icon_url(:hide)}';"
134
+ # Don't use javascript_tag or, ironically, Prototype chokes
135
+ extra_js = '<script type="text/javascript">' +
136
+ "#{var} = true;" + '</script>'
137
+ end
138
+ return extra_js + link_to_remote(icon_tag(type, :id => options[:id]), options, htmlopt)
139
+
140
+ when 'view'
141
+ # Like "show", but we changed it to "view" to indicate new page
142
+ # main index, this does NOT have an id
143
+ url = send("#{meth}_path", args)
144
+ options[:title] ||= "View this #{label}"
145
+ return link_icon(icon, url, options)
146
+ else
147
+ # This generic handler handles all other actions
148
+ options[:title] ||= "#{type.titleize} this #{label}"
149
+ if options[:url]
150
+ url = options.delete(:url)
151
+ url[:controller] ||= meth.pluralize if url.is_a? Hash
152
+ url[:id] ||= args[:id] if url.is_a? Hash and args.is_a? Hash
153
+ elsif type == meth
154
+ # call "run_path" for "run_run_icon"
155
+ url = send("#{meth}_path", args)
156
+ else
157
+ # call "review_revision_path" for "review_revision_icon"
158
+ url = send("#{type}_#{meth}_path", args)
159
+ end
160
+ if options[:remote]
161
+ htmlopt = {}
162
+ htmlopt[:title] = options.delete(:title) if options.has_key?(:title)
163
+ htmlopt[:id] = options.delete(:id) if options.has_key?(:id)
164
+ options[:url] = url
165
+ return link_to_remote(icon_tag(icon), options, htmlopt)
166
+ else
167
+ return link_icon(icon, url, options)
168
+ end
169
+ end
170
+ end
171
+ method_missing_without_icon_links(method_id, args)
172
+ end
173
+ end
174
+ end
175
+
176
+ # Override Rails CDATA JS wrapper because it kills AJAX requests (doh!)
177
+ module ActionView::Helpers::JavaScriptHelper
178
+ def javascript_tag(content, html_options = {})
179
+ content_tag("script", content,
180
+ html_options.merge(:type => "text/javascript"))
181
+ end
182
+ end
@@ -0,0 +1,154 @@
1
+ # methods for making links and help stuff
2
+ module IconLinks
3
+ module ViewHelpers
4
+ @@icon_url_cache = {}
5
+
6
+ # This creates a link using the specified type of icon. The args
7
+ # accepted are the exact same as the args for +link_to+.
8
+ def link_icon(text, *args)
9
+ if args.first.is_a?(Hash)
10
+ return icon_tag(:clear) unless args[0].delete(:if)
11
+ end
12
+ link_to(icon_for(text), *args)
13
+ end
14
+
15
+ # This creates a link using the specified type of icon. The args
16
+ # accepted are the exact same as the args for +link_to_remote+.
17
+ def link_icon_remote(text, *args)
18
+ if args.first.is_a?(Hash)
19
+ return icon_tag(:clear) unless args[0].delete(:if)
20
+ end
21
+ link_to_remote(icon_for(text), *args)
22
+ end
23
+
24
+ # This is similar to link_icon, only it is designed to call a JS function
25
+ def function_icon(text, function)
26
+ link_to(icon_for(text), '#', :onclick => function)
27
+ end
28
+
29
+ # This expands the text and returns the icon path. It is used internally
30
+ # by +link_icon+ and +link_icon_remote+ to render the link text.
31
+ def icon_for(text, excess=nil)
32
+ link = nil
33
+ if text.is_a? Array
34
+ # array
35
+ icon = icon_tag(text.first)
36
+ link = cat(icon, text.last)
37
+ else
38
+ link = icon_tag(text)
39
+ end
40
+ link += excess if excess
41
+ link
42
+ end
43
+
44
+ # Can't normalize this with above because calls to this want to exclude help
45
+ def icon_url(type)
46
+ name = type.to_s
47
+ return @@icon_url_cache[name] if @@icon_url_cache[name]
48
+ # Can't normalize this with above because calls to this want to exclude help
49
+ @@icon_url_cache[name] ||= IconLinks.custom_icon_images[name] ||
50
+ File.join(IconLinks.icon_image_url, name + IconLinks.icon_image_suffix)
51
+ end
52
+
53
+ # This retrieves the assigned icon from the System object,
54
+ # then returns suitably-formatted HTML. It does some simple
55
+ # caching for each icon URL as well.
56
+ def icon_tag(type, options={})
57
+ name = type.to_s
58
+ png_image_tag icon_url(type), {
59
+ :class => 'icon', :border => 0, :alt => name.humanize,
60
+ :width => 16, :height => 16
61
+ }.update(options)
62
+ end
63
+
64
+ # This returns a help link similar to +link_icon+, only using the help
65
+ # from the system_help table. If no help is found, then an empty
66
+ # string is returned (allowing you to randomly call this on any
67
+ # object, without having to check if help exists first).
68
+ def help_for(help_topic, icon=:help)
69
+ help = help_text(help_topic)
70
+ help == '' ? '' : help_icon(help, icon)
71
+ end
72
+
73
+ # Return help text, suitable for use as a help tooltip box thingy
74
+ # Note: Comma escaping is a workaround for a workaround, in the
75
+ # hacks to dhtmlXGrid to support "img:[/path Plain Text],b" <-- comma
76
+ def help_text(help_topic)
77
+ help = SystemHelp.topic(help_topic)
78
+ help ? help.help_text.to_s.gsub('&','&amp;').
79
+ gsub('"','&quot;').gsub('<','&lt;').
80
+ gsub('>','&gt;').gsub(',','&#044;') : ''
81
+ end
82
+
83
+ # Creates the icon to pop up the help bubble
84
+ def help_icon(help_text, icon=:help)
85
+ return '' unless help_text
86
+ return %Q(<a href="#" title="#{help_text}" onclick="return false">#{icon_tag(icon, :class => 'help')}</a>)
87
+ end
88
+
89
+ # This is similar to help_for(), but it instead looks up the description
90
+ # for a field on a per-table basis. For example, desc_of :life_cycle, 'QA'
91
+ # would look up life_cycles where life_cycle = 'QA' and return life_cycle.description
92
+ def desc_of(class_symbol, field_val)
93
+ class_name = class_symbol.to_s.camelize
94
+ row = nil
95
+ eval "row = #{class_name}.find(:first, :conditions => ['name = ?', field_val])"
96
+ return '' unless row
97
+ help_icon row.description
98
+ end
99
+
100
+ # This is a hack needed for IE, adapted from http://koivi.com/ie-png-transparency/
101
+ def png_image_tag(image, options={})
102
+ image = icon_url image if image.is_a?(Symbol)
103
+ begin
104
+ # When called from table_form_builder, request does not exist and raises exception
105
+ if image =~ /\.png$/i && request.user_agent.downcase =~ /msie\s+(5\.[5-9]|[6]\.[0-9]*).*(win)/
106
+ options[:style] ||= ''
107
+ options[:style] += "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader" +
108
+ "(src=&quot;#{image}&quot;,sizingMethod=&quot;scale&quot;);"
109
+ image = System.clear_png_url # reset image to clear png
110
+ end
111
+ rescue
112
+ # In FormBuilder, so write it to the builder
113
+ @template.image_tag image, options
114
+ else
115
+ # Return a string
116
+ image_tag image, options
117
+ end
118
+ end
119
+
120
+ # Creates an expandable toggleable div
121
+ def expandable_tag(type, options)
122
+ toggle_tag(type, options, :expand, :collapse)
123
+ end
124
+
125
+ # Creates a collapsible div
126
+ def collapsible_tag(type, options)
127
+ toggle_tag(type, options, :collapse, :expand)
128
+ end
129
+
130
+ # "Raw" function that can be used to create an expand/collapse tag
131
+ def toggle_tag(type, options, first_icon, alt_icon)
132
+
133
+ target = options[:id]
134
+ if !target
135
+ if options.has_key?(:show)
136
+ show = options[:show]
137
+ target = show.is_a?(ActiveRecord::Base) ? "show_#{show.class.name.to_s.underscore}_#{show.to_param}" \
138
+ : "show_#{show.to_param}"
139
+ else
140
+ target = 'toggle'
141
+ end
142
+ end
143
+
144
+ options[:style] = 'display:none;' + (options[:style]||'')
145
+ var = "toggle_#{target}"
146
+ img = "icon_for_#{var}"
147
+ %(<script type="text/javascript">#{var} = true;</script>) +
148
+ %(<a href="#" onclick="#{var} = !#{var}; $('#{target}').toggle();) +
149
+ %( if (#{var}) { $('#{img}').src = '#{icon_url(first_icon)}'; })+
150
+ %( else { $('#{img}').src = '#{icon_url(alt_icon)}'; }) +
151
+ %(">#{icon_tag(first_icon, :id => img)}#{options[:label]||''}</a>)
152
+ end
153
+ end
154
+ end
data/lib/icon_links.rb ADDED
@@ -0,0 +1,31 @@
1
+ # IconLinks
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
+ module IconLinks
4
+ # Relative path to the icons
5
+ mattr_accessor :icon_image_url
6
+ @@icon_image_url = '/images/icons'
7
+
8
+ # Full suffix including the "."
9
+ mattr_accessor :icon_image_suffix
10
+ @@icon_image_suffix = '.png'
11
+
12
+ # Special icons
13
+ mattr_accessor :custom_icon_images
14
+ @@custom_icon_images = {
15
+ 'loading' => "#{@@icon_image_url}/loading.gif"
16
+ }
17
+
18
+ # Prefixes to automagically remove within auto-generated labels e.g. 'admin_'
19
+ mattr_accessor :remove_prefixes_for_labels
20
+ @@remove_prefixes_for_labels = []
21
+
22
+ def self.included(base)
23
+ base.class_eval do
24
+ include ::IconLinks::ViewHelpers
25
+ include ::IconLinks::MethodMissing
26
+ alias_method_chain :method_missing, :icon_links
27
+ end
28
+ end
29
+ end
30
+
31
+ ActionView::Base.send :include, IconLinks if defined?(ActionView::Base)
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :icon_links do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: icon_links
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Nate Wiger
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-05 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ version: "2.3"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ description: Easily replace text links with icons in Rails views with handy link_icon helpers.
34
+ email: nate@wiger.org
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - MIT-LICENSE
41
+ - Rakefile
42
+ - README.md
43
+ files:
44
+ - lib/icon_links/method_missing.rb
45
+ - lib/icon_links/view_helpers.rb
46
+ - lib/icon_links.rb
47
+ - tasks/icon_links_tasks.rake
48
+ - MIT-LICENSE
49
+ - Rakefile
50
+ - README.md
51
+ has_rdoc: true
52
+ homepage: http://github.com/nateware/icon_links
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --title
58
+ - Icon Links -- Easily link with icons in Rails views
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirements:
76
+ - activesupport v2.3.x
77
+ rubyforge_project: icon_links
78
+ rubygems_version: 1.3.6
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Replace text links with icons in Rails views with handy icon_links helpers.
82
+ test_files: []
83
+