simple-tooltip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +21 -0
  4. data/README.markdown +136 -0
  5. data/Rakefile +2 -0
  6. data/TODO +13 -0
  7. data/lib/generators/simple_tooltip/install_generator.rb +95 -0
  8. data/lib/generators/simple_tooltip/templates/app/controllers/tooltips_controller.rb +117 -0
  9. data/lib/generators/simple_tooltip/templates/app/helpers/tooltip_helper.rb +25 -0
  10. data/lib/generators/simple_tooltip/templates/app/models/tooltip.rb +81 -0
  11. data/lib/generators/simple_tooltip/templates/app/views/tooltips/_form.html.erb +41 -0
  12. data/lib/generators/simple_tooltip/templates/app/views/tooltips/edit.html.erb +6 -0
  13. data/lib/generators/simple_tooltip/templates/app/views/tooltips/index.html.erb +29 -0
  14. data/lib/generators/simple_tooltip/templates/app/views/tooltips/new.html.erb +5 -0
  15. data/lib/generators/simple_tooltip/templates/app/views/tooltips/show.html.erb +31 -0
  16. data/lib/generators/simple_tooltip/templates/app/views/tooltips/tooltip_content.html.erb +9 -0
  17. data/lib/generators/simple_tooltip/templates/db/migrate/create_tooltips.rb +15 -0
  18. data/lib/generators/simple_tooltip/templates/public/images/simple_tooltip_close_icon.png +0 -0
  19. data/lib/generators/simple_tooltip/templates/public/images/simple_tooltip_help_icon.png +0 -0
  20. data/lib/generators/simple_tooltip/templates/public/javascripts/simple_tooltip.js +68 -0
  21. data/lib/generators/simple_tooltip/templates/public/stylesheets/simple_tooltip.css +27 -0
  22. data/lib/generators/simple_tooltip/templates/test/fixtures/tooltips.yml +24 -0
  23. data/lib/generators/simple_tooltip/templates/test/functional/tooltips_controller_test.rb +59 -0
  24. data/lib/generators/simple_tooltip/templates/test/unit/helpers/tooltips_helper_test.rb +8 -0
  25. data/lib/generators/simple_tooltip/templates/test/unit/tooltip_test.rb +97 -0
  26. data/lib/simple_tooltip.rb +3 -0
  27. data/lib/simple_tooltip/version.rb +3 -0
  28. data/simple_tooltip.gemspec +31 -0
  29. metadata +177 -0
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *~
2
+ pkg/*
3
+ *.gem
4
+ .bundle
5
+ craic
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in simple_tooltip.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Robert Jones, Craic Computing LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,136 @@
1
+ SimpleTooltip
2
+ =============
3
+
4
+ Simple and flexible Tooltip Help for Rails applications
5
+
6
+ There are many JavaScript plugins that provide basic tooltip (popup) help for web pages. These work by including the
7
+ text of the help message directly in the content of each page.
8
+
9
+ But this approach fails when the information requires more than one paragraph and when more than plain
10
+ text is required. For example, the help message might require a link to an external web site.
11
+
12
+ With SimpleTooltip you create tooltip help content in a web form and record it in the database via a Tooltip model.
13
+ Content can be created in plain text, HTML, Markdown and Textile, allowing tooltips to use the
14
+ full features of HTML, including links, CSS styling, etc.
15
+
16
+ Tooltip links, typically small icons, are placed in your views with calls to a simple helper method that refer
17
+ to the related content by title.
18
+
19
+ Tooltip records include a locale column that defines the language used for their content. Multiple tooltips can
20
+ be created with the same title but different locales. When a given title is requested, the code tries to find
21
+ a version that matches the user's current locale.
22
+
23
+ SimpleTooltip helps bridge the gap between short, fixed tooltips and full help pages.
24
+
25
+ Tooltips are displayed via a [jQuery](http://jquery.com "jQuery"). They can be configured to appear transiently when a user hovers over a link icon,
26
+ or to appear when the link icon is clicked, remaining until closed by a click within the tooltip.
27
+
28
+
29
+ If the client browser does not have JavaScript enabled, the tooltip links take the user to a separate help
30
+ page.
31
+
32
+ Developers can customize the styling of the tooltip content via CSS definitions and tooltip icons can be replaced with others.
33
+
34
+
35
+ Prerequisites
36
+ =============
37
+
38
+ The initial release of SimpleTooltip works [Rails](http://rubyonrails.org "Rails 3") and [jQuery](http://jquery.com "jQuery"). It is not expected to work with Rails 2.
39
+
40
+
41
+ Installation
42
+ ============
43
+
44
+ SimpleTooltip is distributed as a Ruby Gem and is installed in an application via a Rails generator.
45
+
46
+ 1: Install the gem on your system
47
+
48
+ $ gem install simple-tooltip
49
+
50
+ The gem is hosted at [Ruby Gems](https://rubygems.org "Ruby Gems")
51
+
52
+ 2: Within your Rails application, run the generator
53
+
54
+ $ rails generate simple_tooltip:install
55
+
56
+ (note the underscore in the generator name - this seems to be a requirement of the Rails generator machinery)
57
+
58
+ The generator creates the following items
59
+
60
+ * A Tooltip model, controller and views and a database migration
61
+ * A stylesheet, javascript file and icon image files
62
+ * Tests
63
+
64
+ 3: Setup your gem dependencies
65
+
66
+ Add this line to your Gemfile and run `$ bundle install`
67
+
68
+ gem 'simple-tooltip'
69
+
70
+ 4: Create the tooltips table in your database
71
+
72
+ $ rake db:migrate
73
+
74
+ 5: Include the JQuery file
75
+
76
+ Make sure you have the jQuery JavaScript library installed (via jquery-rails)'
77
+ $ rails generate jquery:install
78
+
79
+ Then add this line to `app/views/layouts/application.html.erb` after other JavaScript files
80
+ <%= javascript_include_tag 'simple_tooltip.js' %>
81
+
82
+ The stylesheet should be included automatically.
83
+
84
+ 6: Now create some tooltips
85
+
86
+ Start your application and go to /tooltips/new
87
+
88
+ 7: In the views of other models, add links to your tooltip records
89
+
90
+ For example:
91
+
92
+ <%= tooltip('email format', :hover) %>
93
+ <%= tooltip('privacy agreement', :click) %>
94
+
95
+
96
+ Usage
97
+ =====
98
+
99
+ Tooltips are defined in your views with the tooltip helper method, found in `app/helpers/tooltip_helper.rb`
100
+
101
+ Each tooltip record in the database should be given a title, preferably something informative such as 'phone number format'.
102
+ This title is supplied to the tooltip helper in order to retrieve the matching record.
103
+
104
+ Multiple calls to the helper can use the same title. They will operate independently.
105
+
106
+ The tooltip 'popup' is displayed in one of two modes.
107
+
108
+ The default `:hover` mode specifies that the tooltip will appear when the mouse is held over the help icon and will
109
+ disappear when the mouse leaves that icon.
110
+
111
+ With the `:click` mode, the tooltip appears then the icon is clicked. The tooltip remains in view until the `close` icon at the
112
+ top of the tooltip is clicked or until another tooltip help icon is clicked.
113
+
114
+ This mode is used when the tooltip contains a link to another web page or when the content is extensive.
115
+
116
+
117
+ Customizing
118
+ ===========
119
+
120
+ Although the Tooltip model, etc use the word `tooltip`, the images and other asset files use the longer form `simple_tooltip`. This is
121
+ intentional as a number of the JavaScript tooltip solutions use the shorter form.
122
+
123
+ The help and close icons are found in `public/images/simple_tooltip_help_icon.png` and `public/images/simple_tooltip_close_icon.png`
124
+ respectively. The images can be replaced as long as the file names stay the same. If you want to change the filenames you will
125
+ need to modify them in the JavaScript file.
126
+
127
+ The stylesheet is found at `public/stylesheets/simple_tooltip.css` and defines two class selectors that affect how the icons are displayed and an ID selector that defines how the 'popup'
128
+ tooltip content is displayed.
129
+
130
+ The jQuery JavaScript is found at `public/javascripts/simple_tooltip.js`. You should not need to modify this file.
131
+
132
+ SimpleTooltip is written by [Rob Jones](http://github.com/craic "Rob Jones") at [Craic Computing](http://craic.com "Craic Computing") in Seattle. It is distributed freely under the MIT license.
133
+
134
+
135
+
136
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/TODO ADDED
@@ -0,0 +1,13 @@
1
+ March 2011 - initial release
2
+
3
+ - add instructions to README on adding tooltip links on static pages - explicit HTML
4
+
5
+ - add an action that clones an existing tooltip with an alternate locale
6
+
7
+ - include link to Google Translate to facilitate creation of tooltips in
8
+ alternate locales
9
+
10
+ - improve the styling of the tooltip popups - either directly with 'themes' or
11
+ through incorporating jQuery tooltip/popup plugins
12
+
13
+
@@ -0,0 +1,95 @@
1
+ module SimpleTooltip
2
+ module Generators
3
+ class InstallGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ desc "This generator installs all the files necessary for the simple_tooltip gem"
7
+
8
+
9
+ def copy_stylesheet_and_images
10
+ path = "public/stylesheets/simple_tooltip.css"
11
+ copy_file "./#{path}", path
12
+ path = "public/images/simple_tooltip_help_icon.png"
13
+ copy_file "./#{path}", path
14
+ path = "public/images/simple_tooltip_close_icon.png"
15
+ copy_file "./#{path}", path
16
+ end
17
+
18
+ def copy_javascript
19
+ path = "public/javascripts/simple_tooltip.js"
20
+ copy_file "./#{path}", path
21
+ end
22
+
23
+ def copy_migration
24
+ # Migration file name is preceded by the date/time string - UTC timestamp Time.now.gmtime.strftime("%Y%m%d%H%M%S")
25
+ copy_file "./db/migrate/create_tooltips.rb",
26
+ "db/migrate/#{Time.now.gmtime.strftime("%Y%m%d%H%M%S")}_create_tooltips.rb"
27
+ end
28
+
29
+ def copy_app_files
30
+ path = "app/controllers/tooltips_controller.rb"
31
+ copy_file "./#{path}", path
32
+ path = "app/models/tooltip.rb"
33
+ copy_file "./#{path}", path
34
+ path = "app/helpers/tooltip_helper.rb"
35
+ copy_file "./#{path}", path
36
+ path = "app/views/tooltips"
37
+ directory "./#{path}", path
38
+ end
39
+
40
+ def copy_tests
41
+ path = "test/unit/tooltip_test.rb"
42
+ copy_file "./#{path}", path
43
+ path = "test/unit/helpers/tooltips_helper_test.rb"
44
+ copy_file "./#{path}", path
45
+ path = "test/fixtures/tooltips.yml"
46
+ copy_file "./#{path}", path
47
+ path = "test/functional/tooltips_controller_test.rb"
48
+ copy_file "./#{path}", path
49
+ end
50
+
51
+ # Add this multi line definition to the routes file - but only a single call to route
52
+ # otherwise they are placed in reverse line order!
53
+ def setup_route
54
+ route "resources :tooltips do\n" +
55
+ " collection do\n" +
56
+ " get 'tooltip_content'\n" +
57
+ " end\n" +
58
+ " end"
59
+ end
60
+
61
+ # Output installation instructions for the user
62
+ def instructions
63
+ puts '---------------------------------------------------------------'
64
+ puts 'To complete your installation...'
65
+ puts ''
66
+ puts "1: Add this gem to your project Gemfile and run 'bundle install'"
67
+ puts ''
68
+ puts " gem 'simple-tooltip'"
69
+ puts ''
70
+ puts '2: Run db:migrate to create the tooltips database table'
71
+ puts ''
72
+ puts " $ rake db:migrate"
73
+ puts ''
74
+ puts '3: Make sure you have the jQuery JavaScript library installed (via jquery-rails)'
75
+ puts ''
76
+ puts ' $ rails generate jquery:install'
77
+ puts ''
78
+ puts '4: Check that these first two lines are in layouts/application.html.erb and add the third'
79
+ puts ''
80
+ puts ' <%= stylesheet_link_tag :all %>'
81
+ puts ' <%= javascript_include_tag :defaults %>'
82
+ puts " <%= javascript_include_tag 'simple_tooltip.js' %>"
83
+ puts ''
84
+ puts '5: Create some tooltip entries in /tooltips and then add links'
85
+ puts ' to them in views of your other models'
86
+ puts " <%= tooltip('tooltip title', :hover) %>"
87
+ puts ''
88
+ puts 'For more information see the project page on GitHub'
89
+ puts ' https://github.com/craic/simple_tooltip'
90
+ puts '---------------------------------------------------------------'
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,117 @@
1
+ class TooltipsController < ApplicationController
2
+
3
+ # Add admin before_filter here - something like this (depends on your authorization solution)
4
+ # This prevents regular users from modifying the help pages
5
+ # before_filter admin?, :except => [ :tooltip_content ]
6
+
7
+ # GET /tooltips
8
+ # GET /tooltips.xml
9
+ def index
10
+ @tooltips = Tooltip.all
11
+
12
+ respond_to do |format|
13
+ format.html # index.html.erb
14
+ format.xml { render :xml => @tooltips }
15
+ end
16
+ end
17
+
18
+ # GET /tooltips/1
19
+ # GET /tooltips/1.xml
20
+ def show
21
+ @tooltip = Tooltip.find(params[:id])
22
+
23
+ respond_to do |format|
24
+ format.html # show.html.erb
25
+ format.xml { render :xml => @tooltip }
26
+ end
27
+ end
28
+
29
+ # GET /tooltips/new
30
+ # GET /tooltips/new.xml
31
+ def new
32
+ @tooltip = Tooltip.new
33
+
34
+ respond_to do |format|
35
+ format.html # new.html.erb
36
+ format.xml { render :xml => @tooltip }
37
+ end
38
+ end
39
+
40
+ # GET /tooltips/1/edit
41
+ def edit
42
+ @tooltip = Tooltip.find(params[:id])
43
+ end
44
+
45
+ # POST /tooltips
46
+ # POST /tooltips.xml
47
+ def create
48
+ @tooltip = Tooltip.new(params[:tooltip])
49
+
50
+ respond_to do |format|
51
+ if @tooltip.save
52
+ format.html { redirect_to(@tooltip, :notice => 'Tooltip was successfully created.') }
53
+ format.xml { render :xml => @tooltip, :status => :created, :location => @tooltip }
54
+ else
55
+ format.html { render :action => "new" }
56
+ format.xml { render :xml => @tooltip.errors, :status => :unprocessable_entity }
57
+ end
58
+ end
59
+ end
60
+
61
+ # PUT /tooltips/1
62
+ # PUT /tooltips/1.xml
63
+ def update
64
+ @tooltip = Tooltip.find(params[:id])
65
+
66
+ respond_to do |format|
67
+ if @tooltip.update_attributes(params[:tooltip])
68
+ format.html { redirect_to(@tooltip, :notice => 'Tooltip was successfully updated.') }
69
+ format.xml { head :ok }
70
+ else
71
+ format.html { render :action => "edit" }
72
+ format.xml { render :xml => @tooltip.errors, :status => :unprocessable_entity }
73
+ end
74
+ end
75
+ end
76
+
77
+ # DELETE /tooltips/1
78
+ # DELETE /tooltips/1.xml
79
+ def destroy
80
+ @tooltip = Tooltip.find(params[:id])
81
+ @tooltip.destroy
82
+
83
+ respond_to do |format|
84
+ format.html { redirect_to(tooltips_url) }
85
+ format.xml { head :ok }
86
+ end
87
+ end
88
+
89
+
90
+ # fetch and return the content of the specified tooltip, taking into account user's locale where relevant
91
+ def tooltip_content
92
+
93
+ if params[:title]
94
+
95
+ # find and display a specific tooltip
96
+ @tooltip = Tooltip.from_title_and_locale(params[:title])
97
+
98
+ if params[:js]
99
+ if @tooltip.blank?
100
+ data = "Sorry... unable to find that help content"
101
+ else
102
+ data = @tooltip.content_to_html
103
+ end
104
+ send_data(data, :type => 'text/plain', :disposition => 'inline')
105
+ else
106
+ if @tooltip.blank?
107
+ flash[:notice] = "Sorry... unable to find that help content"
108
+ end
109
+ end
110
+
111
+ else
112
+ # should be impossible to get here
113
+ flash[:notice] = "Sorry... no tooltip Title was provided"
114
+ end
115
+ end
116
+
117
+ end
@@ -0,0 +1,25 @@
1
+ module TooltipHelper
2
+
3
+ # tooltip helper for inclusion in views
4
+ # TODO - allow a custom class to be passed - e.g. twitter style - look at poshy tip
5
+ def tooltip(text='', mode=:hover)
6
+
7
+ return if text == ''
8
+
9
+ tooltip_help_icon_file = "/images/simple_tooltip_help_icon.png"
10
+
11
+ class_str = "simple-tooltip-help-icon"
12
+ if mode == :click
13
+ title = 'Click for help'
14
+ class_str << " simple-tooltip-clickable"
15
+ else
16
+ title = text
17
+ end
18
+
19
+ link_to(image_tag(tooltip_help_icon_file),
20
+ tooltip_content_tooltips_path(:title => text),
21
+ :name => text, :title => title,
22
+ :class => class_str)
23
+ end
24
+
25
+ end
@@ -0,0 +1,81 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rdiscount'
4
+
5
+ class Tooltip < ActiveRecord::Base
6
+
7
+ attr_accessible :title, :content, :markup, :locale
8
+
9
+ validates_presence_of :title
10
+ validates_presence_of :content
11
+ validates_presence_of :markup
12
+
13
+ validates_format_of :locale,
14
+ :with => /^[a-z][a-z]$/,
15
+ :message => 'must be in ISO-639-1 two letter format (e.g. en, de, zh)',
16
+ :allow_blank => true
17
+
18
+ validates_inclusion_of :markup,
19
+ :in => %w{ html markdown textile },
20
+ :message => 'must be one of html, markdown or textile'
21
+
22
+ validate :validate_no_script_tags
23
+
24
+ validate :validate_unique_title_locale_combination, :on => :create
25
+
26
+
27
+ # find the tooltip that matches the title and locale
28
+ def self.from_title_and_locale(title, user_locale = I18n.locale.to_s)
29
+
30
+ tooltip = nil
31
+ tooltips = Tooltip.where(:title => title).all
32
+
33
+ if tooltips.count == 1
34
+ # there is only one, so use that
35
+ tooltip = tooltips.first
36
+
37
+ elsif tooltips.count > 1
38
+
39
+ # Try and match by locale
40
+ default_tooltip = nil
41
+ tooltips.each do |tooltip_i|
42
+ if tooltip_i.locale == user_locale
43
+ tooltip = tooltip_i
44
+ break
45
+ elsif tooltip_i.locale.nil? or tooltip_i.locale == I18n.default_locale.to_s
46
+ default_tooltip = tooltip_i
47
+ end
48
+ end
49
+ tooltip = default_tooltip if tooltip.blank?
50
+ end
51
+
52
+ tooltip
53
+ end
54
+
55
+
56
+ # Process content with RDiscount if needed
57
+ def content_to_html
58
+ if self.markup == 'markdown'
59
+ RDiscount.new(self.content, :autolink).to_html
60
+ elsif self.markup == 'textile'
61
+ RedCloth.new(self.content).to_html
62
+ else
63
+ self.content
64
+ end
65
+ end
66
+
67
+ protected
68
+
69
+ def validate_unique_title_locale_combination
70
+ if Tooltip.where(:title => self.title).where(:locale => self.locale).count > 0
71
+ errors.add(:title, 'and locale combination already exists')
72
+ end
73
+ end
74
+
75
+ def validate_no_script_tags
76
+ if self.content =~ /\<\s*script/im
77
+ errors.add(:content, 'must not contain <script> tags')
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,41 @@
1
+ <%= form_for(@tooltip) do |f| %>
2
+ <% if @tooltip.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@tooltip.errors.count, "error") %> prohibited this Tooltip from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @tooltip.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :title %><br />
16
+ <%= f.text_field :title %>
17
+ </div>
18
+ <div class="field">
19
+ <%= f.label :content %><br />
20
+ <%= f.text_area :content %>
21
+ </div>
22
+ <div class="field">
23
+ <%= f.label :locale %><br />
24
+ <%= f.text_field :locale %> Use two letter ISO-639-1 code
25
+ </div>
26
+ <div class="field">
27
+ <%= f.label :markup %><br />
28
+ <%= f.radio_button :markup, 'markdown', :selected => true %> Markdown
29
+ <%= f.radio_button :markup, 'textile' %> Textile
30
+ <%= f.radio_button :markup, 'html' %> HTML / Plain Text &nbsp;
31
+ <br/>
32
+ <a href="http://en.wikipedia.org/wiki/Markdown">Markdown syntax</a>
33
+ <br/>
34
+ <a href="http://redcloth.org/textile">Textile syntax</a>
35
+
36
+ </div>
37
+
38
+ <div class="actions">
39
+ <%= f.submit %>
40
+ </div>
41
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing Tooltip</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @tooltip %> |
6
+ <%= link_to 'Back', tooltips_path %>
@@ -0,0 +1,29 @@
1
+ <h1>Listing Tooltips</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Title</th>
6
+ <th>Locale</th>
7
+ <th>Markup</th>
8
+
9
+ <th></th>
10
+ <th></th>
11
+ <th></th>
12
+ </tr>
13
+
14
+ <% @tooltips.each do |tooltip| %>
15
+ <tr>
16
+ <td><%= tooltip.title %></td>
17
+ <td><%= tooltip.locale %></td>
18
+ <td><%= tooltip.markup %></td>
19
+
20
+ <td><%= link_to 'Show', tooltip %></td>
21
+ <td><%= link_to 'Edit', edit_tooltip_path(tooltip) %></td>
22
+ <td><%= link_to 'Destroy', tooltip, :confirm => 'Are you sure?', :method => :delete %></td>
23
+ </tr>
24
+ <% end %>
25
+ </table>
26
+
27
+ <br />
28
+
29
+ <%= link_to 'New Tooltip', new_tooltip_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Tooltip</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', tooltips_path %>
@@ -0,0 +1,31 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <% if @user_view %>
4
+
5
+ <%= raw(@tooltip.content_to_html) %>
6
+ <p><br/><%= link_to "Go Back", request.referer %></p>
7
+
8
+ <% else %>
9
+ <p>
10
+ <b>Title:</b>
11
+ <%= @tooltip.title %>
12
+ </p>
13
+
14
+ <p>
15
+ <b>Content:</b>
16
+ <%= raw(@tooltip.content_to_html) %>
17
+ </p>
18
+
19
+ <p>
20
+ <b>Markup:</b>
21
+ <%= @tooltip.markup %>
22
+ </p>
23
+
24
+ <p>
25
+ <b>Locale:</b>
26
+ <%= @tooltip.locale %>
27
+ </p>
28
+
29
+ <%= link_to 'Edit', edit_tooltip_path(@tooltip) %> |
30
+ <%= link_to 'Back', tooltips_path %>
31
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <h2>Tooltip Help</h2>
2
+ <p id="notice"><%= notice %></p>
3
+
4
+ <% unless @tooltip.blank? %>
5
+ <%= raw(@tooltip.content_to_html) %>
6
+ <% end %>
7
+
8
+ <p><br/><%= link_to "Go Back", request.referer %></p>
9
+
@@ -0,0 +1,15 @@
1
+ class CreateTooltips < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tooltips do |t|
4
+ t.string :title
5
+ t.text :content
6
+ t.string :markup, :default => "markdown"
7
+ t.string :locale
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :tooltips
14
+ end
15
+ end
@@ -0,0 +1,68 @@
1
+ // jQuery code for the simple_tooltip gem
2
+ jQuery(document).ready(function() {
3
+
4
+ var close_icon_file = "/images/simple_tooltip_close_icon.png";
5
+
6
+ jQuery('.simple-tooltip-help-icon').mouseenter(function(e) {
7
+ // remove any existing tooltip - should not be necessary, just a safety clause
8
+
9
+ // this has the side efect of removing any other visible tooltip on entering any other icon
10
+ jQuery("#simple-tooltip").remove();
11
+
12
+ // setup tooltip on hover
13
+ if(!jQuery(this).hasClass('simple-tooltip-clickable')) {
14
+ // Remove the 'title' attribute to prevent it appearing on hover
15
+ this.title = null;
16
+
17
+ // get the content for this tooltip by ajax and create the popup
18
+ jQuery.get("/tooltips/tooltip_content?js=true&title=" + this.name, function(data) {
19
+
20
+ jQuery("body").append("<div id='simple-tooltip'>" + data + "</div>");
21
+
22
+ // position the tooltip at the bottom right of mouse pointer
23
+ jQuery("#simple-tooltip").css("top",(e.pageY + 5) + "px").css("left",(e.pageX + 5) + "px").show();
24
+
25
+ // with fast mouse movements the tooltip can remain visible
26
+ // setup an action that if it is clicked then it is removed
27
+ // shouldn't be necessary but it seems to be...
28
+ jQuery('#simple-tooltip').click(function() {
29
+ jQuery(this).remove();
30
+ });
31
+ });
32
+ }
33
+
34
+ }).click(function(e) {
35
+ // prevent this event bubbling up to the link
36
+ e.preventDefault();
37
+
38
+ // setup tooltip on click
39
+ if(jQuery(this).hasClass('simple-tooltip-clickable')) {
40
+
41
+ // get the content for this tooltip by ajax and create the popup
42
+ jQuery.get("/tooltips/tooltip_content?js=true&title=" + this.name, function(data) {
43
+
44
+ // setup a close button within the tooltip at top right
45
+ var close_div = "<div id=\"simple-tooltip-close\" class=\"simple-tooltip-close\">" +
46
+ "<img src=\"" + close_icon_file + "\" alt=\"Close tooltip\"/></div>";
47
+
48
+ jQuery("body").append("<div id='simple-tooltip'>" + close_div + data + "</div>");
49
+
50
+ // position the tooltip at the bottom right of mouse pointer
51
+ jQuery("#simple-tooltip").css("top",(e.pageY + 5) + "px").css("left",(e.pageX + 5) + "px").show();
52
+
53
+ // remove the tooltip when close button is clicked
54
+ jQuery('#simple-tooltip-close').click(function() {
55
+ jQuery("#simple-tooltip").remove();
56
+ });
57
+ // ?? remove tooltip if the tooltip_icon is clicked a second time ??
58
+
59
+ });
60
+ }
61
+
62
+ }).mouseleave(function(e) {
63
+ // in :hover mode, remove the tooltip when the mouse leaves the tooltip icon
64
+ if(!jQuery(this).hasClass('simple-tooltip-clickable')) {
65
+ jQuery("#simple-tooltip").remove();
66
+ }
67
+ });
68
+ });
@@ -0,0 +1,27 @@
1
+
2
+ .simple-tooltip-help-icon {
3
+ text-decoration: none;
4
+ }
5
+
6
+ .simple-tooltip-help-icon>img {
7
+ vertical-align: middle;
8
+ }
9
+
10
+ .simple-tooltip-help-icon:hover {
11
+ background: none;
12
+ }
13
+
14
+ .simple-tooltip-close {
15
+ text-align: right;
16
+ }
17
+
18
+ #simple-tooltip {
19
+ position: absolute;
20
+ border: 1px solid #333;
21
+ background: #ffffd8;
22
+ padding: 2px 5px;
23
+ color: #000;
24
+ display: none;
25
+ text-align: left;
26
+ }
27
+
@@ -0,0 +1,24 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+
3
+ one:
4
+ title: MyString_1
5
+ content: MyText
6
+ markup: html
7
+ locale: en
8
+ two:
9
+ title: MyString_2
10
+ content: MyText
11
+ markup: html
12
+ locale: en
13
+
14
+ en_locale:
15
+ title: locale_test
16
+ content: Hello
17
+ markup: html
18
+ locale: en
19
+
20
+ es_locale:
21
+ title: locale_test
22
+ content: Hola
23
+ markup: html
24
+ locale: es
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+
3
+ class TooltipsControllerTest < ActionController::TestCase
4
+ setup do
5
+ @tooltip = tooltips(:one)
6
+ end
7
+
8
+ test "should get index" do
9
+ get :index
10
+ assert_response :success
11
+ assert_not_nil assigns(:tooltips)
12
+ end
13
+
14
+ test "should get new" do
15
+ get :new
16
+ assert_response :success
17
+ end
18
+
19
+ test "should create tooltip" do
20
+ assert_difference('Tooltip.count') do
21
+ tooltip = Tooltip.new({:title => 'foo', :content => 'bar'})
22
+ post :create, :tooltip => tooltip.attributes
23
+ end
24
+
25
+ assert_redirected_to tooltip_path(assigns(:tooltip))
26
+ end
27
+
28
+ test "should show tooltip" do
29
+ get :show, :id => @tooltip.to_param
30
+ assert_response :success
31
+ end
32
+
33
+ test "should get edit" do
34
+ get :edit, :id => @tooltip.to_param
35
+ assert_response :success
36
+ end
37
+
38
+ test "should update tooltip" do
39
+ put :update, :id => @tooltip.to_param, :tooltip => @tooltip.attributes
40
+ assert_redirected_to tooltip_path(assigns(:tooltip))
41
+ end
42
+
43
+ test "should destroy tooltip" do
44
+ assert_difference('Tooltip.count', -1) do
45
+ delete :destroy, :id => @tooltip.to_param
46
+ end
47
+
48
+ assert_redirected_to tooltips_path
49
+ end
50
+
51
+ # Add tests for the ajax functions....
52
+
53
+ # tooltip_content
54
+ test "should show tooltip content given a title" do
55
+ get :tooltip_content, :title => @tooltip.title
56
+ assert_response :success
57
+ end
58
+
59
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+
4
+ class TooltipsHelperTest < ActionView::TestCase
5
+
6
+ # Need to add tests here
7
+
8
+ end
@@ -0,0 +1,97 @@
1
+ require 'test_helper'
2
+
3
+ class TooltipTest < ActiveSupport::TestCase
4
+
5
+
6
+ # test no script validation routine
7
+
8
+ test "validate ok if content has no <script> tag" do
9
+ tooltip = Tooltip.new(:title => 'foo', :markup => 'html',
10
+ :content => "<p>all good here</p>")
11
+ assert tooltip.valid?
12
+ end
13
+
14
+ test "validate with error if content has <script> tag" do
15
+ tooltip = Tooltip.new(:title => 'foo', :markup => 'html',
16
+ :content => "foo <script> bad \n stuff </script> bar")
17
+ assert !tooltip.valid?
18
+ assert tooltip.errors[:content].any?
19
+ end
20
+
21
+ test "validate with error if format of locale is not two letter" do
22
+ tooltip = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'locale',
23
+ :content => "text")
24
+ assert !tooltip.valid?
25
+ assert tooltip.errors[:locale].any?
26
+ end
27
+
28
+ test "validate OK if format of locale is two letter" do
29
+ tooltip = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'en',
30
+ :content => "text")
31
+ assert tooltip.valid?
32
+ end
33
+
34
+
35
+ test "validate fails unless unique title and locale" do
36
+ tooltip0 = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'en',
37
+ :content => "<p>Here to help</p>")
38
+ tooltip0.save!
39
+
40
+ tooltip1 = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'en',
41
+ :content => "<p>Here to help</p>")
42
+
43
+
44
+ assert !tooltip1.valid?
45
+ assert tooltip1.errors[:title].any?
46
+ end
47
+
48
+
49
+ test "validate passes duplicate title but unique locale" do
50
+
51
+ tooltip0 = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'en',
52
+ :content => "<p>Here to help</p>")
53
+ tooltip0.save!
54
+
55
+ tooltip1 = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'de',
56
+ :content => "<p>Here to help</p>")
57
+
58
+ assert tooltip1.valid?
59
+ end
60
+
61
+
62
+ test "content_to_html passes through html content" do
63
+ content = "<p>Here is some text in <span style=\"color: red;\">HTML</span> format.</p>"
64
+ tooltip = Tooltip.new(:title => 'foo', :markup => 'html',
65
+ :content => content)
66
+ assert_equal tooltip.content_to_html, content
67
+ end
68
+
69
+
70
+ test "content_to_html converts Markdown content to html" do
71
+ content = "<p>Here is some text in <strong>Markdown</strong> format</p>\n\n<p><a href=\"http://craic.com\">http://craic.com</a></p>\n"
72
+ markdown = "Here is some text in **Markdown** format\n\nhttp://craic.com"
73
+ tooltip = Tooltip.new(:title => 'foo', :markup => 'markdown',
74
+ :content => markdown)
75
+ assert_equal tooltip.content_to_html, content
76
+ end
77
+
78
+ test 'class method from_title_and_locale return the correct tooltip' do
79
+
80
+ tooltip0 = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'en',
81
+ :content => "<p>English text</p>")
82
+ tooltip0.save!
83
+
84
+ tooltip1 = Tooltip.new(:title => 'foo', :markup => 'html', :locale => 'de',
85
+ :content => "<p>German text</p>")
86
+
87
+ tooltip1.save!
88
+
89
+
90
+ tooltip_out = Tooltip.from_title_and_locale('foo', 'de')
91
+
92
+ assert_equal tooltip_out.content_to_html, "<p>German text</p>"
93
+ assert_equal tooltip_out.title, "foo"
94
+ assert_equal tooltip_out.locale, "de"
95
+ end
96
+
97
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleTooltip
2
+ # Your code goes here...
3
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleTooltip
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "simple_tooltip/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "simple-tooltip"
7
+ s.version = SimpleTooltip::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Robert Jones"]
10
+ s.email = ["jones@craic.com"]
11
+ s.homepage = "http://rubygems.org/gems/simple-tooltip"
12
+ s.summary = %q{Create and display Tooltip Help in view pages in Rails applications}
13
+ s.description = %q{Create and display Tooltip Help in view pages in Rails applications.
14
+ Uses jQuery to display tooltips, with fallback if Javascript is not available.
15
+ Makes use of help text in the user's locale if available.'}
16
+
17
+
18
+ s.add_dependency "rails", "~> 3.0"
19
+ s.add_dependency "jquery-rails"
20
+ s.add_dependency "rdiscount"
21
+ s.add_dependency "RedCloth"
22
+ s.add_dependency "thor", "~>0.14.4"
23
+ s.add_development_dependency "bundler", "~> 1.0.0"
24
+
25
+ s.rubyforge_project = "simple-tooltip"
26
+
27
+ s.files = `git ls-files`.split("\n")
28
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
29
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
30
+ s.require_paths = ["lib"]
31
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-tooltip
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Robert Jones
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-03-04 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rails
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 3
30
+ - 0
31
+ version: "3.0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: jquery-rails
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdiscount
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ type: :runtime
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: RedCloth
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ type: :runtime
72
+ version_requirements: *id004
73
+ - !ruby/object:Gem::Dependency
74
+ name: thor
75
+ prerelease: false
76
+ requirement: &id005 !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ~>
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ - 14
84
+ - 4
85
+ version: 0.14.4
86
+ type: :runtime
87
+ version_requirements: *id005
88
+ - !ruby/object:Gem::Dependency
89
+ name: bundler
90
+ prerelease: false
91
+ requirement: &id006 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 1
98
+ - 0
99
+ - 0
100
+ version: 1.0.0
101
+ type: :development
102
+ version_requirements: *id006
103
+ description: |-
104
+ Create and display Tooltip Help in view pages in Rails applications.
105
+ Uses jQuery to display tooltips, with fallback if Javascript is not available.
106
+ Makes use of help text in the user's locale if available.'
107
+ email:
108
+ - jones@craic.com
109
+ executables: []
110
+
111
+ extensions: []
112
+
113
+ extra_rdoc_files: []
114
+
115
+ files:
116
+ - .gitignore
117
+ - Gemfile
118
+ - LICENSE
119
+ - README.markdown
120
+ - Rakefile
121
+ - TODO
122
+ - lib/generators/simple_tooltip/install_generator.rb
123
+ - lib/generators/simple_tooltip/templates/app/controllers/tooltips_controller.rb
124
+ - lib/generators/simple_tooltip/templates/app/helpers/tooltip_helper.rb
125
+ - lib/generators/simple_tooltip/templates/app/models/tooltip.rb
126
+ - lib/generators/simple_tooltip/templates/app/views/tooltips/_form.html.erb
127
+ - lib/generators/simple_tooltip/templates/app/views/tooltips/edit.html.erb
128
+ - lib/generators/simple_tooltip/templates/app/views/tooltips/index.html.erb
129
+ - lib/generators/simple_tooltip/templates/app/views/tooltips/new.html.erb
130
+ - lib/generators/simple_tooltip/templates/app/views/tooltips/show.html.erb
131
+ - lib/generators/simple_tooltip/templates/app/views/tooltips/tooltip_content.html.erb
132
+ - lib/generators/simple_tooltip/templates/db/migrate/create_tooltips.rb
133
+ - lib/generators/simple_tooltip/templates/public/images/simple_tooltip_close_icon.png
134
+ - lib/generators/simple_tooltip/templates/public/images/simple_tooltip_help_icon.png
135
+ - lib/generators/simple_tooltip/templates/public/javascripts/simple_tooltip.js
136
+ - lib/generators/simple_tooltip/templates/public/stylesheets/simple_tooltip.css
137
+ - lib/generators/simple_tooltip/templates/test/fixtures/tooltips.yml
138
+ - lib/generators/simple_tooltip/templates/test/functional/tooltips_controller_test.rb
139
+ - lib/generators/simple_tooltip/templates/test/unit/helpers/tooltips_helper_test.rb
140
+ - lib/generators/simple_tooltip/templates/test/unit/tooltip_test.rb
141
+ - lib/simple_tooltip.rb
142
+ - lib/simple_tooltip/version.rb
143
+ - simple_tooltip.gemspec
144
+ has_rdoc: true
145
+ homepage: http://rubygems.org/gems/simple-tooltip
146
+ licenses: []
147
+
148
+ post_install_message:
149
+ rdoc_options: []
150
+
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ segments:
159
+ - 0
160
+ version: "0"
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ segments:
167
+ - 0
168
+ version: "0"
169
+ requirements: []
170
+
171
+ rubyforge_project: simple-tooltip
172
+ rubygems_version: 1.3.7
173
+ signing_key:
174
+ specification_version: 3
175
+ summary: Create and display Tooltip Help in view pages in Rails applications
176
+ test_files: []
177
+