Browse files

Upate to use Rails 3.2.15 and a now-Gemified Safe In Place Editing

library/gem available from RubyGems.
  • Loading branch information...
1 parent 0ed3ee5 commit 5c2ffc2861f9ca241fe874e5ae2fb3e9ef14ade8 @pond committed Nov 29, 2013
View
4 Gemfile
@@ -4,7 +4,7 @@ source 'http://rubygems.org'
# http://gembundler.com/v1.2/whats_new.html
ruby '1.9.3'
-gem 'rails', '3.2.14'
+gem 'rails', '3.2.15'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
@@ -39,13 +39,15 @@ gem 'prototype-rails'
# https://github.com/mislav/will_paginate/
# https://github.com/collectiveidea/audited
# https://github.com/swanandp/acts_as_list
+# https://github.com/pond/safe_in_place_editing
gem 'calendar_date_select', '~> 1.6', :git => 'http://github.com/paneq/calendar_date_select'
gem 'ruby-openid', '~> 2.3'
gem 'open_id_authentication', '~> 1.2'
gem 'will_paginate', '~> 3.0'
gem 'audited-activerecord', '~> 3.0'
gem 'acts_as_list'
+gem 'safe_in_place_editing', '~> 2.0'
# If you want the charting stuff for some reason... Note that
# this brings in awkward dependencies such as ImageMagick via
View
65 Gemfile.lock
@@ -7,36 +7,36 @@ GIT
GEM
remote: http://rubygems.org/
specs:
- actionmailer (3.2.14)
- actionpack (= 3.2.14)
+ actionmailer (3.2.15)
+ actionpack (= 3.2.15)
mail (~> 2.5.4)
- actionpack (3.2.14)
- activemodel (= 3.2.14)
- activesupport (= 3.2.14)
+ actionpack (3.2.15)
+ activemodel (= 3.2.15)
+ activesupport (= 3.2.15)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.5)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
- activemodel (3.2.14)
- activesupport (= 3.2.14)
+ activemodel (3.2.15)
+ activesupport (= 3.2.15)
builder (~> 3.0.0)
- activerecord (3.2.14)
- activemodel (= 3.2.14)
- activesupport (= 3.2.14)
+ activerecord (3.2.15)
+ activemodel (= 3.2.15)
+ activesupport (= 3.2.15)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
- activeresource (3.2.14)
- activemodel (= 3.2.14)
- activesupport (= 3.2.14)
- activesupport (3.2.14)
+ activeresource (3.2.15)
+ activemodel (= 3.2.15)
+ activesupport (= 3.2.15)
+ activesupport (3.2.15)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
acts_as_list (0.3.0)
activerecord (>= 3.0)
- arel (3.0.2)
+ arel (3.0.3)
audited (3.0.0)
audited-activerecord (3.0.0)
activerecord (~> 3.0)
@@ -55,7 +55,7 @@ GEM
hike (1.2.3)
i18n (0.6.5)
journey (1.0.4)
- json (1.8.0)
+ json (1.8.1)
libv8 (3.16.14.3)
mail (2.5.4)
mime-types (~> 1.16)
@@ -71,26 +71,26 @@ GEM
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
- rack-openid (1.4.0)
+ rack-openid (1.4.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-ssl (1.3.3)
rack
rack-test (0.6.2)
rack (>= 1.0)
- rails (3.2.14)
- actionmailer (= 3.2.14)
- actionpack (= 3.2.14)
- activerecord (= 3.2.14)
- activeresource (= 3.2.14)
- activesupport (= 3.2.14)
+ rails (3.2.15)
+ actionmailer (= 3.2.15)
+ actionpack (= 3.2.15)
+ activerecord (= 3.2.15)
+ activeresource (= 3.2.15)
+ activesupport (= 3.2.15)
bundler (~> 1.0)
- railties (= 3.2.14)
- rails_autolink (1.1.4)
+ railties (= 3.2.15)
+ rails_autolink (1.1.5)
rails (> 3.1)
- railties (3.2.14)
- actionpack (= 3.2.14)
- activesupport (= 3.2.14)
+ railties (3.2.15)
+ actionpack (= 3.2.15)
+ activesupport (= 3.2.15)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
@@ -100,6 +100,8 @@ GEM
json (~> 1.4)
ref (1.0.5)
ruby-openid (2.3.0)
+ safe_in_place_editing (2.0.0)
+ railties (~> 3.2)
sass (3.2.12)
sass-rails (3.2.6)
railties (~> 3.2.0)
@@ -119,9 +121,9 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.38)
- uglifier (2.2.1)
+ uglifier (2.3.1)
execjs (>= 0.3.0)
- multi_json (~> 1.0, >= 1.0.2)
+ json (>= 1.8.0)
will_paginate (3.0.5)
PLATFORMS
@@ -137,9 +139,10 @@ DEPENDENCIES
open_id_authentication (~> 1.2)
pg (>= 0.16)
prototype-rails
- rails (= 3.2.14)
+ rails (= 3.2.15)
rails_autolink
ruby-openid (~> 2.3)
+ safe_in_place_editing (~> 2.0)
sass-rails
therubyracer
uglifier
View
2 app/views/layouts/application.html.erb
@@ -21,7 +21,7 @@
<% end -%>
<% end -%>
<% if ( action_name == 'index' ) -%>
- <%= javascript_include_tag( 'safe_in_place_editing/safe_in_place_editing' ) %>
+ <%= javascript_include_tag( 'safe_in_place_editing' ) %>
<% end -%>
<% if ( controller.controller_name == 'saved_reports' || controller.controller_name == 'timesheet_force_commits' || action_name == 'index' ) -%>
<%= raw( calendar_date_select_includes().gsub( /^/, ' ' ) ) %>
View
11 config/initializers/rails_2_plugin_safe_in_place_editing.rb
@@ -1,11 +0,0 @@
-########################################################################
-# File:: init.rb
-# (C):: Hipposoft 2008
-#
-# Purpose:: Safe in-place editing. See the README for more information.
-# ----------------------------------------------------------------------
-# 24-Jun-2008 (ADH): Created.
-########################################################################
-
-ActionController::Base.send( :include, SafeInPlaceEditing )
-ActionController::Base.helper( SafeInPlaceEditingHelper )
View
296 doc/app/SafeInPlaceEditing.html
@@ -1,296 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
-
-<title>module SafeInPlaceEditing - YOUR_TITLE</title>
-
-<link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">
-
-<script type="text/javascript">
- var rdoc_rel_prefix = "./";
-</script>
-
-<script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>
-
-
-<body id="top" class="module">
-<nav id="metadata">
- <nav id="home-section" class="section">
- <h3 class="section-header">
- <a href="./index.html">Home</a>
- <a href="./table_of_contents.html#classes">Classes</a>
- <a href="./table_of_contents.html#methods">Methods</a>
- </h3>
-</nav>
-
-
- <nav id="search-section" class="section project-section" class="initially-hidden">
- <form action="#" method="get" accept-charset="utf-8">
- <h3 class="section-header">
- <input type="text" name="search" placeholder="Search" id="search-field"
- title="Type to search, Up and Down to navigate, Enter to load">
- </h3>
- </form>
-
- <ul id="search-results" class="initially-hidden"></ul>
-</nav>
-
-
- <div id="file-metadata">
- <nav id="file-list-section" class="section">
- <h3 class="section-header">Defined In</h3>
- <ul>
- <li>lib/safe_in_place_editing/safe_in_place_editing.rb
- </ul>
-</nav>
-
-
- </div>
-
- <div id="class-metadata">
-
-
-
-
- </div>
-
- <div id="project-metadata">
- <nav id="fileindex-section" class="section project-section">
- <h3 class="section-header">Pages</h3>
-
- <ul>
-
- <li class="file"><a href="./doc/README_FOR_APP.html">README_FOR_APP</a>
-
- </ul>
-</nav>
-
- <nav id="classindex-section" class="section project-section">
- <h3 class="section-header">Class and Module Index</h3>
-
- <ul class="link-list">
-
- <li><a href="./TrackRecordReport.html">TrackRecordReport</a>
-
- <li><a href="./TrackRecordReport/Calculator.html">TrackRecordReport::Calculator</a>
-
- <li><a href="./TrackRecordReport/CalculatorWithUsers.html">TrackRecordReport::CalculatorWithUsers</a>
-
- <li><a href="./TrackRecordReport/Cell.html">TrackRecordReport::Cell</a>
-
- <li><a href="./TrackRecordReport/Report.html">TrackRecordReport::Report</a>
-
- <li><a href="./TrackRecordReport/Row.html">TrackRecordReport::Row</a>
-
- <li><a href="./TrackRecordReport/Section.html">TrackRecordReport::Section</a>
-
- <li><a href="./TrackRecordSections.html">TrackRecordSections</a>
-
- <li><a href="./TrackRecordSections/Group.html">TrackRecordSections::Group</a>
-
- <li><a href="./TrackRecordSections/GroupMixin.html">TrackRecordSections::GroupMixin</a>
-
- <li><a href="./TrackRecordSections/Section.html">TrackRecordSections::Section</a>
-
- <li><a href="./TrackRecordSections/SectionMixin.html">TrackRecordSections::SectionMixin</a>
-
- <li><a href="./TrackRecordSections/Sections.html">TrackRecordSections::Sections</a>
-
- <li><a href="./TrackRecordSections/SectionsMixin.html">TrackRecordSections::SectionsMixin</a>
-
- <li><a href="./ReportsHelper.html">ReportsHelper</a>
-
- <li><a href="./ReportsHelper/ReportMonth.html">ReportsHelper::ReportMonth</a>
-
- <li><a href="./ReportsHelper/ReportWeek.html">ReportsHelper::ReportWeek</a>
-
- <li><a href="./ReportsHelper/ReportYear.html">ReportsHelper::ReportYear</a>
-
- <li><a href="./QuietLeightbox.html">QuietLeightbox</a>
-
- <li><a href="./QuietLeightbox/ClassMethods.html">QuietLeightbox::ClassMethods</a>
-
- <li><a href="./QuietLeightbox/QuietLeightboxHelper.html">QuietLeightbox::QuietLeightboxHelper</a>
-
- <li><a href="./QuietPrototype.html">QuietPrototype</a>
-
- <li><a href="./QuietPrototype/ClassMethods.html">QuietPrototype::ClassMethods</a>
-
- <li><a href="./QuietPrototype/QuietPrototypeHelper.html">QuietPrototype::QuietPrototypeHelper</a>
-
- <li><a href="./YuiTree.html">YuiTree</a>
-
- <li><a href="./YuiTree/ClassMethods.html">YuiTree::ClassMethods</a>
-
- <li><a href="./YuiTree/YuiTreeHelper.html">YuiTree::YuiTreeHelper</a>
-
- <li><a href="./SafeInPlaceEditing.html">SafeInPlaceEditing</a>
-
- <li><a href="./SafeInPlaceEditing/ClassMethods.html">SafeInPlaceEditing::ClassMethods</a>
-
- <li><a href="./TrackRecordReportGenerator.html">TrackRecordReportGenerator</a>
-
- <li><a href="./TrackRecordReportGenerator/UkOrgPondCSV.html">TrackRecordReportGenerator::UkOrgPondCSV</a>
-
- <li><a href="./ApplicationController.html">ApplicationController</a>
-
- <li><a href="./ApplicationHelper.html">ApplicationHelper</a>
-
- <li><a href="./AuditsController.html">AuditsController</a>
-
- <li><a href="./AuditsHelper.html">AuditsHelper</a>
-
- <li><a href="./ChartsController.html">ChartsController</a>
-
- <li><a href="./ChartsHelper.html">ChartsHelper</a>
-
- <li><a href="./ControlPanel.html">ControlPanel</a>
-
- <li><a href="./ControlPanelsController.html">ControlPanelsController</a>
-
- <li><a href="./Customer.html">Customer</a>
-
- <li><a href="./CustomersController.html">CustomersController</a>
-
- <li><a href="./CustomersHelper.html">CustomersHelper</a>
-
- <li><a href="./EmailNotifier.html">EmailNotifier</a>
-
- <li><a href="./HelpController.html">HelpController</a>
-
- <li><a href="./HelpHelper.html">HelpHelper</a>
-
- <li><a href="./Project.html">Project</a>
-
- <li><a href="./ProjectsController.html">ProjectsController</a>
-
- <li><a href="./ProjectsHelper.html">ProjectsHelper</a>
-
- <li><a href="./Rangeable.html">Rangeable</a>
-
- <li><a href="./ReportsController.html">ReportsController</a>
-
- <li><a href="./SafeInPlaceEditingHelper.html">SafeInPlaceEditingHelper</a>
-
- <li><a href="./SavedReport.html">SavedReport</a>
-
- <li><a href="./SavedReportAutoTitlesController.html">SavedReportAutoTitlesController</a>
-
- <li><a href="./SavedReportsBaseController.html">SavedReportsBaseController</a>
-
- <li><a href="./SavedReportsByCustomerController.html">SavedReportsByCustomerController</a>
-
- <li><a href="./SavedReportsByProjectController.html">SavedReportsByProjectController</a>
-
- <li><a href="./SavedReportsByTaskController.html">SavedReportsByTaskController</a>
-
- <li><a href="./SavedReportsByUserController.html">SavedReportsByUserController</a>
-
- <li><a href="./SavedReportsController.html">SavedReportsController</a>
-
- <li><a href="./SavedReportsHelper.html">SavedReportsHelper</a>
-
- <li><a href="./SessionsController.html">SessionsController</a>
-
- <li><a href="./Task.html">Task</a>
-
- <li><a href="./TaskGroup.html">TaskGroup</a>
-
- <li><a href="./TaskImport.html">TaskImport</a>
-
- <li><a href="./TaskImportsController.html">TaskImportsController</a>
-
- <li><a href="./TaskImportsHelper.html">TaskImportsHelper</a>
-
- <li><a href="./TasksController.html">TasksController</a>
-
- <li><a href="./TasksHelper.html">TasksHelper</a>
-
- <li><a href="./Timesheet.html">Timesheet</a>
-
- <li><a href="./TimesheetForceCommit.html">TimesheetForceCommit</a>
-
- <li><a href="./TimesheetForceCommitsController.html">TimesheetForceCommitsController</a>
-
- <li><a href="./TimesheetRow.html">TimesheetRow</a>
-
- <li><a href="./TimesheetRowsController.html">TimesheetRowsController</a>
-
- <li><a href="./TimesheetRowsHelper.html">TimesheetRowsHelper</a>
-
- <li><a href="./TimesheetsController.html">TimesheetsController</a>
-
- <li><a href="./TimesheetsHelper.html">TimesheetsHelper</a>
-
- <li><a href="./TreesController.html">TreesController</a>
-
- <li><a href="./User.html">User</a>
-
- <li><a href="./UsersController.html">UsersController</a>
-
- <li><a href="./UsersHelper.html">UsersHelper</a>
-
- <li><a href="./WorkPacket.html">WorkPacket</a>
-
- <li><a href="./WorkPacketsController.html">WorkPacketsController</a>
-
- <li><a href="./WorkPacketsHelper.html">WorkPacketsHelper</a>
-
- </ul>
-</nav>
-
- </div>
-</nav>
-
-<div id="documentation">
- <h1 class="module">module SafeInPlaceEditing</h1>
-
- <div id="description" class="description">
- <dl class="rdoc-list note-list"><dt>File
-<dd>
-<p>safe_in_place_editing.rb</p>
-</dd><dt>(C)
-<dd>
-<p>Hipposoft 2008</p>
-</dd><dt>Purpose
-<dd>
-<p>Safe, lockable in-place editing - controller support.</p>
-</dd></dl>
-<hr style="height: 10px">
-
-<pre>24-Jun-2008 (ADH): Created.</pre>
-
- </div><!-- description -->
-
-
-
-
- <section id="5Buntitled-5D" class="documentation-section">
-
-
-
-
-
-
-
-
- <!-- Methods -->
-
- </section><!-- 5Buntitled-5D -->
-
-</div><!-- documentation -->
-
-
-<footer id="validator-badges">
- <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
- <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.12.2.
- <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
-</footer>
-
View
349 doc/app/SafeInPlaceEditing/ClassMethods.html
@@ -1,349 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
-
-<title>module SafeInPlaceEditing::ClassMethods - YOUR_TITLE</title>
-
-<link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet">
-
-<script type="text/javascript">
- var rdoc_rel_prefix = "../";
-</script>
-
-<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
-<script type="text/javascript" charset="utf-8" src="../js/navigation.js"></script>
-<script type="text/javascript" charset="utf-8" src="../js/search_index.js"></script>
-<script type="text/javascript" charset="utf-8" src="../js/search.js"></script>
-<script type="text/javascript" charset="utf-8" src="../js/searcher.js"></script>
-<script type="text/javascript" charset="utf-8" src="../js/darkfish.js"></script>
-
-
-<body id="top" class="module">
-<nav id="metadata">
- <nav id="home-section" class="section">
- <h3 class="section-header">
- <a href="../index.html">Home</a>
- <a href="../table_of_contents.html#classes">Classes</a>
- <a href="../table_of_contents.html#methods">Methods</a>
- </h3>
-</nav>
-
-
- <nav id="search-section" class="section project-section" class="initially-hidden">
- <form action="#" method="get" accept-charset="utf-8">
- <h3 class="section-header">
- <input type="text" name="search" placeholder="Search" id="search-field"
- title="Type to search, Up and Down to navigate, Enter to load">
- </h3>
- </form>
-
- <ul id="search-results" class="initially-hidden"></ul>
-</nav>
-
-
- <div id="file-metadata">
- <nav id="file-list-section" class="section">
- <h3 class="section-header">Defined In</h3>
- <ul>
- <li>lib/safe_in_place_editing/safe_in_place_editing.rb
- </ul>
-</nav>
-
-
- </div>
-
- <div id="class-metadata">
-
-
-
- <!-- Method Quickref -->
-<nav id="method-list-section" class="section">
- <h3 class="section-header">Methods</h3>
-
- <ul class="link-list">
-
- <li><a href="#method-i-safe_in_place_edit_for">#safe_in_place_edit_for</a>
-
- </ul>
-</nav>
-
- </div>
-
- <div id="project-metadata">
- <nav id="fileindex-section" class="section project-section">
- <h3 class="section-header">Pages</h3>
-
- <ul>
-
- <li class="file"><a href="../doc/README_FOR_APP.html">README_FOR_APP</a>
-
- </ul>
-</nav>
-
- <nav id="classindex-section" class="section project-section">
- <h3 class="section-header">Class and Module Index</h3>
-
- <ul class="link-list">
-
- <li><a href="../TrackRecordReport.html">TrackRecordReport</a>
-
- <li><a href="../TrackRecordReport/Calculator.html">TrackRecordReport::Calculator</a>
-
- <li><a href="../TrackRecordReport/CalculatorWithUsers.html">TrackRecordReport::CalculatorWithUsers</a>
-
- <li><a href="../TrackRecordReport/Cell.html">TrackRecordReport::Cell</a>
-
- <li><a href="../TrackRecordReport/Report.html">TrackRecordReport::Report</a>
-
- <li><a href="../TrackRecordReport/Row.html">TrackRecordReport::Row</a>
-
- <li><a href="../TrackRecordReport/Section.html">TrackRecordReport::Section</a>
-
- <li><a href="../TrackRecordSections.html">TrackRecordSections</a>
-
- <li><a href="../TrackRecordSections/Group.html">TrackRecordSections::Group</a>
-
- <li><a href="../TrackRecordSections/GroupMixin.html">TrackRecordSections::GroupMixin</a>
-
- <li><a href="../TrackRecordSections/Section.html">TrackRecordSections::Section</a>
-
- <li><a href="../TrackRecordSections/SectionMixin.html">TrackRecordSections::SectionMixin</a>
-
- <li><a href="../TrackRecordSections/Sections.html">TrackRecordSections::Sections</a>
-
- <li><a href="../TrackRecordSections/SectionsMixin.html">TrackRecordSections::SectionsMixin</a>
-
- <li><a href="../ReportsHelper.html">ReportsHelper</a>
-
- <li><a href="../ReportsHelper/ReportMonth.html">ReportsHelper::ReportMonth</a>
-
- <li><a href="../ReportsHelper/ReportWeek.html">ReportsHelper::ReportWeek</a>
-
- <li><a href="../ReportsHelper/ReportYear.html">ReportsHelper::ReportYear</a>
-
- <li><a href="../QuietLeightbox.html">QuietLeightbox</a>
-
- <li><a href="../QuietLeightbox/ClassMethods.html">QuietLeightbox::ClassMethods</a>
-
- <li><a href="../QuietLeightbox/QuietLeightboxHelper.html">QuietLeightbox::QuietLeightboxHelper</a>
-
- <li><a href="../QuietPrototype.html">QuietPrototype</a>
-
- <li><a href="../QuietPrototype/ClassMethods.html">QuietPrototype::ClassMethods</a>
-
- <li><a href="../QuietPrototype/QuietPrototypeHelper.html">QuietPrototype::QuietPrototypeHelper</a>
-
- <li><a href="../YuiTree.html">YuiTree</a>
-
- <li><a href="../YuiTree/ClassMethods.html">YuiTree::ClassMethods</a>
-
- <li><a href="../YuiTree/YuiTreeHelper.html">YuiTree::YuiTreeHelper</a>
-
- <li><a href="../SafeInPlaceEditing.html">SafeInPlaceEditing</a>
-
- <li><a href="../SafeInPlaceEditing/ClassMethods.html">SafeInPlaceEditing::ClassMethods</a>
-
- <li><a href="../TrackRecordReportGenerator.html">TrackRecordReportGenerator</a>
-
- <li><a href="../TrackRecordReportGenerator/UkOrgPondCSV.html">TrackRecordReportGenerator::UkOrgPondCSV</a>
-
- <li><a href="../ApplicationController.html">ApplicationController</a>
-
- <li><a href="../ApplicationHelper.html">ApplicationHelper</a>
-
- <li><a href="../AuditsController.html">AuditsController</a>
-
- <li><a href="../AuditsHelper.html">AuditsHelper</a>
-
- <li><a href="../ChartsController.html">ChartsController</a>
-
- <li><a href="../ChartsHelper.html">ChartsHelper</a>
-
- <li><a href="../ControlPanel.html">ControlPanel</a>
-
- <li><a href="../ControlPanelsController.html">ControlPanelsController</a>
-
- <li><a href="../Customer.html">Customer</a>
-
- <li><a href="../CustomersController.html">CustomersController</a>
-
- <li><a href="../CustomersHelper.html">CustomersHelper</a>
-
- <li><a href="../EmailNotifier.html">EmailNotifier</a>
-
- <li><a href="../HelpController.html">HelpController</a>
-
- <li><a href="../HelpHelper.html">HelpHelper</a>
-
- <li><a href="../Project.html">Project</a>
-
- <li><a href="../ProjectsController.html">ProjectsController</a>
-
- <li><a href="../ProjectsHelper.html">ProjectsHelper</a>
-
- <li><a href="../Rangeable.html">Rangeable</a>
-
- <li><a href="../ReportsController.html">ReportsController</a>
-
- <li><a href="../SafeInPlaceEditingHelper.html">SafeInPlaceEditingHelper</a>
-
- <li><a href="../SavedReport.html">SavedReport</a>
-
- <li><a href="../SavedReportAutoTitlesController.html">SavedReportAutoTitlesController</a>
-
- <li><a href="../SavedReportsBaseController.html">SavedReportsBaseController</a>
-
- <li><a href="../SavedReportsByCustomerController.html">SavedReportsByCustomerController</a>
-
- <li><a href="../SavedReportsByProjectController.html">SavedReportsByProjectController</a>
-
- <li><a href="../SavedReportsByTaskController.html">SavedReportsByTaskController</a>
-
- <li><a href="../SavedReportsByUserController.html">SavedReportsByUserController</a>
-
- <li><a href="../SavedReportsController.html">SavedReportsController</a>
-
- <li><a href="../SavedReportsHelper.html">SavedReportsHelper</a>
-
- <li><a href="../SessionsController.html">SessionsController</a>
-
- <li><a href="../Task.html">Task</a>
-
- <li><a href="../TaskGroup.html">TaskGroup</a>
-
- <li><a href="../TaskImport.html">TaskImport</a>
-
- <li><a href="../TaskImportsController.html">TaskImportsController</a>
-
- <li><a href="../TaskImportsHelper.html">TaskImportsHelper</a>
-
- <li><a href="../TasksController.html">TasksController</a>
-
- <li><a href="../TasksHelper.html">TasksHelper</a>
-
- <li><a href="../Timesheet.html">Timesheet</a>
-
- <li><a href="../TimesheetForceCommit.html">TimesheetForceCommit</a>
-
- <li><a href="../TimesheetForceCommitsController.html">TimesheetForceCommitsController</a>
-
- <li><a href="../TimesheetRow.html">TimesheetRow</a>
-
- <li><a href="../TimesheetRowsController.html">TimesheetRowsController</a>
-
- <li><a href="../TimesheetRowsHelper.html">TimesheetRowsHelper</a>
-
- <li><a href="../TimesheetsController.html">TimesheetsController</a>
-
- <li><a href="../TimesheetsHelper.html">TimesheetsHelper</a>
-
- <li><a href="../TreesController.html">TreesController</a>
-
- <li><a href="../User.html">User</a>
-
- <li><a href="../UsersController.html">UsersController</a>
-
- <li><a href="../UsersHelper.html">UsersHelper</a>
-
- <li><a href="../WorkPacket.html">WorkPacket</a>
-
- <li><a href="../WorkPacketsController.html">WorkPacketsController</a>
-
- <li><a href="../WorkPacketsHelper.html">WorkPacketsHelper</a>
-
- </ul>
-</nav>
-
- </div>
-</nav>
-
-<div id="documentation">
- <h1 class="module">module SafeInPlaceEditing::ClassMethods</h1>
-
- <div id="description" class="description">
-
- </div><!-- description -->
-
-
-
-
- <section id="5Buntitled-5D" class="documentation-section">
-
-
-
-
-
-
-
-
- <!-- Methods -->
-
- <section id="public-instance-5Buntitled-5D-method-details" class="method-section section">
- <h3 class="section-header">Public Instance Methods</h3>
-
-
- <div id="method-i-safe_in_place_edit_for" class="method-detail ">
-
- <div class="method-heading">
- <span class="method-name">safe_in_place_edit_for</span><span
- class="method-args">( object, attribute, options = {} )</span>
- <span class="method-click-advice">click to toggle source</span>
- </div>
-
-
- <div class="method-description">
-
- <p>Exact API equivalent of in_place_edit_for, except:</p>
-<ul><li>
-<p>Runs all user data through “ERB::Util::html_escape” when sending it to the
-view to avoid associated vulnerabilities with otherwise-unescaped
-user-supplied data; the current InPlaceEditing plugin does this too, albeit
-using “CGI::escapeHTML” for some reason.</p>
-</li><li>
-<p>Supports optimistic locking if a lock_version CGI parameter is supplied, by
-explicitly checking the version being updated.</p>
-</li><li>
-<p>Explicitly catches errors and returns them as 500 status codes with a plain
-text message regardless of Rails environment.</p>
-</li></ul>
-
-<p>See safe_in_place_editor and safe_in_place_editor_field inside file
-“safe_in_place_editing_helper.rb” for the counterpart helper functions.</p>
-
-<p>The Prototype library getText function must be patched as described in the
-README rationale; see public/javascripts/safe_in_place_editing.js.</p>
-
-
-
- <div class="method-source-code" id="safe_in_place_edit_for-source">
- <pre><span class="ruby-comment"># File lib/safe_in_place_editing/safe_in_place_editing.rb, line 37</span>
-<span class="ruby-keyword">def</span> <span class="ruby-identifier">safe_in_place_edit_for</span>( <span class="ruby-identifier">object</span>, <span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">options</span> = {} )
- <span class="ruby-identifier">define_method</span>( <span class="ruby-node">&quot;set_#{object}_#{attribute}&quot;</span> ) <span class="ruby-keyword">do</span>
- <span class="ruby-identifier">safe_in_place_edit_backend</span>( <span class="ruby-identifier">object</span>, <span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">options</span> )
- <span class="ruby-keyword">end</span>
-<span class="ruby-keyword">end</span></pre>
- </div><!-- safe_in_place_edit_for-source -->
-
- </div>
-
-
-
-
- </div><!-- safe_in_place_edit_for-method -->
-
-
- </section><!-- public-instance-method-details -->
-
- </section><!-- 5Buntitled-5D -->
-
-</div><!-- documentation -->
-
-
-<footer id="validator-badges">
- <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
- <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.12.2.
- <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
-</footer>
-
View
586 doc/app/SafeInPlaceEditingHelper.html
@@ -1,586 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
-
-<title>module SafeInPlaceEditingHelper - YOUR_TITLE</title>
-
-<link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">
-
-<script type="text/javascript">
- var rdoc_rel_prefix = "./";
-</script>
-
-<script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
-<script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>
-
-
-<body id="top" class="module">
-<nav id="metadata">
- <nav id="home-section" class="section">
- <h3 class="section-header">
- <a href="./index.html">Home</a>
- <a href="./table_of_contents.html#classes">Classes</a>
- <a href="./table_of_contents.html#methods">Methods</a>
- </h3>
-</nav>
-
-
- <nav id="search-section" class="section project-section" class="initially-hidden">
- <form action="#" method="get" accept-charset="utf-8">
- <h3 class="section-header">
- <input type="text" name="search" placeholder="Search" id="search-field"
- title="Type to search, Up and Down to navigate, Enter to load">
- </h3>
- </form>
-
- <ul id="search-results" class="initially-hidden"></ul>
-</nav>
-
-
- <div id="file-metadata">
- <nav id="file-list-section" class="section">
- <h3 class="section-header">Defined In</h3>
- <ul>
- <li>lib/safe_in_place_editing/safe_in_place_editing_helper.rb
- </ul>
-</nav>
-
-
- </div>
-
- <div id="class-metadata">
-
-
-
- <!-- Method Quickref -->
-<nav id="method-list-section" class="section">
- <h3 class="section-header">Methods</h3>
-
- <ul class="link-list">
-
- <li><a href="#method-i-safe_in_place_editor">#safe_in_place_editor</a>
-
- <li><a href="#method-i-safe_in_place_editor_field">#safe_in_place_editor_field</a>
-
- </ul>
-</nav>
-
- </div>
-
- <div id="project-metadata">
- <nav id="fileindex-section" class="section project-section">
- <h3 class="section-header">Pages</h3>
-
- <ul>
-
- <li class="file"><a href="./doc/README_FOR_APP.html">README_FOR_APP</a>
-
- </ul>
-</nav>
-
- <nav id="classindex-section" class="section project-section">
- <h3 class="section-header">Class and Module Index</h3>
-
- <ul class="link-list">
-
- <li><a href="./TrackRecordReport.html">TrackRecordReport</a>
-
- <li><a href="./TrackRecordReport/Calculator.html">TrackRecordReport::Calculator</a>
-
- <li><a href="./TrackRecordReport/CalculatorWithUsers.html">TrackRecordReport::CalculatorWithUsers</a>
-
- <li><a href="./TrackRecordReport/Cell.html">TrackRecordReport::Cell</a>
-
- <li><a href="./TrackRecordReport/Report.html">TrackRecordReport::Report</a>
-
- <li><a href="./TrackRecordReport/Row.html">TrackRecordReport::Row</a>
-
- <li><a href="./TrackRecordReport/Section.html">TrackRecordReport::Section</a>
-
- <li><a href="./TrackRecordSections.html">TrackRecordSections</a>
-
- <li><a href="./TrackRecordSections/Group.html">TrackRecordSections::Group</a>
-
- <li><a href="./TrackRecordSections/GroupMixin.html">TrackRecordSections::GroupMixin</a>
-
- <li><a href="./TrackRecordSections/Section.html">TrackRecordSections::Section</a>
-
- <li><a href="./TrackRecordSections/SectionMixin.html">TrackRecordSections::SectionMixin</a>
-
- <li><a href="./TrackRecordSections/Sections.html">TrackRecordSections::Sections</a>
-
- <li><a href="./TrackRecordSections/SectionsMixin.html">TrackRecordSections::SectionsMixin</a>
-
- <li><a href="./ReportsHelper.html">ReportsHelper</a>
-
- <li><a href="./ReportsHelper/ReportMonth.html">ReportsHelper::ReportMonth</a>
-
- <li><a href="./ReportsHelper/ReportWeek.html">ReportsHelper::ReportWeek</a>
-
- <li><a href="./ReportsHelper/ReportYear.html">ReportsHelper::ReportYear</a>
-
- <li><a href="./QuietLeightbox.html">QuietLeightbox</a>
-
- <li><a href="./QuietLeightbox/ClassMethods.html">QuietLeightbox::ClassMethods</a>
-
- <li><a href="./QuietLeightbox/QuietLeightboxHelper.html">QuietLeightbox::QuietLeightboxHelper</a>
-
- <li><a href="./QuietPrototype.html">QuietPrototype</a>
-
- <li><a href="./QuietPrototype/ClassMethods.html">QuietPrototype::ClassMethods</a>
-
- <li><a href="./QuietPrototype/QuietPrototypeHelper.html">QuietPrototype::QuietPrototypeHelper</a>
-
- <li><a href="./YuiTree.html">YuiTree</a>
-
- <li><a href="./YuiTree/ClassMethods.html">YuiTree::ClassMethods</a>
-
- <li><a href="./YuiTree/YuiTreeHelper.html">YuiTree::YuiTreeHelper</a>
-
- <li><a href="./SafeInPlaceEditing.html">SafeInPlaceEditing</a>
-
- <li><a href="./SafeInPlaceEditing/ClassMethods.html">SafeInPlaceEditing::ClassMethods</a>
-
- <li><a href="./TrackRecordReportGenerator.html">TrackRecordReportGenerator</a>
-
- <li><a href="./TrackRecordReportGenerator/UkOrgPondCSV.html">TrackRecordReportGenerator::UkOrgPondCSV</a>
-
- <li><a href="./ApplicationController.html">ApplicationController</a>
-
- <li><a href="./ApplicationHelper.html">ApplicationHelper</a>
-
- <li><a href="./AuditsController.html">AuditsController</a>
-
- <li><a href="./AuditsHelper.html">AuditsHelper</a>
-
- <li><a href="./ChartsController.html">ChartsController</a>
-
- <li><a href="./ChartsHelper.html">ChartsHelper</a>
-
- <li><a href="./ControlPanel.html">ControlPanel</a>
-
- <li><a href="./ControlPanelsController.html">ControlPanelsController</a>
-
- <li><a href="./Customer.html">Customer</a>
-
- <li><a href="./CustomersController.html">CustomersController</a>
-
- <li><a href="./CustomersHelper.html">CustomersHelper</a>
-
- <li><a href="./EmailNotifier.html">EmailNotifier</a>
-
- <li><a href="./HelpController.html">HelpController</a>
-
- <li><a href="./HelpHelper.html">HelpHelper</a>
-
- <li><a href="./Project.html">Project</a>
-
- <li><a href="./ProjectsController.html">ProjectsController</a>
-
- <li><a href="./ProjectsHelper.html">ProjectsHelper</a>
-
- <li><a href="./Rangeable.html">Rangeable</a>
-
- <li><a href="./ReportsController.html">ReportsController</a>
-
- <li><a href="./SafeInPlaceEditingHelper.html">SafeInPlaceEditingHelper</a>
-
- <li><a href="./SavedReport.html">SavedReport</a>
-
- <li><a href="./SavedReportAutoTitlesController.html">SavedReportAutoTitlesController</a>
-
- <li><a href="./SavedReportsBaseController.html">SavedReportsBaseController</a>
-
- <li><a href="./SavedReportsByCustomerController.html">SavedReportsByCustomerController</a>
-
- <li><a href="./SavedReportsByProjectController.html">SavedReportsByProjectController</a>
-
- <li><a href="./SavedReportsByTaskController.html">SavedReportsByTaskController</a>
-
- <li><a href="./SavedReportsByUserController.html">SavedReportsByUserController</a>
-
- <li><a href="./SavedReportsController.html">SavedReportsController</a>
-
- <li><a href="./SavedReportsHelper.html">SavedReportsHelper</a>
-
- <li><a href="./SessionsController.html">SessionsController</a>
-
- <li><a href="./Task.html">Task</a>
-
- <li><a href="./TaskGroup.html">TaskGroup</a>
-
- <li><a href="./TaskImport.html">TaskImport</a>
-
- <li><a href="./TaskImportsController.html">TaskImportsController</a>
-
- <li><a href="./TaskImportsHelper.html">TaskImportsHelper</a>
-
- <li><a href="./TasksController.html">TasksController</a>
-
- <li><a href="./TasksHelper.html">TasksHelper</a>
-
- <li><a href="./Timesheet.html">Timesheet</a>
-
- <li><a href="./TimesheetForceCommit.html">TimesheetForceCommit</a>
-
- <li><a href="./TimesheetForceCommitsController.html">TimesheetForceCommitsController</a>
-
- <li><a href="./TimesheetRow.html">TimesheetRow</a>
-
- <li><a href="./TimesheetRowsController.html">TimesheetRowsController</a>
-
- <li><a href="./TimesheetRowsHelper.html">TimesheetRowsHelper</a>
-
- <li><a href="./TimesheetsController.html">TimesheetsController</a>
-
- <li><a href="./TimesheetsHelper.html">TimesheetsHelper</a>
-
- <li><a href="./TreesController.html">TreesController</a>
-
- <li><a href="./User.html">User</a>
-
- <li><a href="./UsersController.html">UsersController</a>
-
- <li><a href="./UsersHelper.html">UsersHelper</a>
-
- <li><a href="./WorkPacket.html">WorkPacket</a>
-
- <li><a href="./WorkPacketsController.html">WorkPacketsController</a>
-
- <li><a href="./WorkPacketsHelper.html">WorkPacketsHelper</a>
-
- </ul>
-</nav>
-
- </div>
-</nav>
-
-<div id="documentation">
- <h1 class="module">module SafeInPlaceEditingHelper</h1>
-
- <div id="description" class="description">
- <dl class="rdoc-list note-list"><dt>File
-<dd>
-<p>safe_in_place_editing_helper.rb</p>
-</dd><dt>(C)
-<dd>
-<p>Hipposoft 2008</p>
-</dd><dt>Purpose
-<dd>
-<p>Safe, lockable in-place editing - helper methods.</p>
-</dd></dl>
-<hr style="height: 10px">
-
-<pre>24-Jun-2008 (ADH): Created.</pre>
-
- </div><!-- description -->
-
-
-
-
- <section id="5Buntitled-5D" class="documentation-section">
-
-
-
-
-
-
-
-
- <!-- Methods -->
-
- <section id="public-instance-5Buntitled-5D-method-details" class="method-section section">
- <h3 class="section-header">Public Instance Methods</h3>
-
-
- <div id="method-i-safe_in_place_editor" class="method-detail ">
-
- <div class="method-heading">
- <span class="method-name">safe_in_place_editor</span><span
- class="method-args">( field_id, options = {} )</span>
- <span class="method-click-advice">click to toggle source</span>
- </div>
-
-
- <div class="method-description">
-
- <p>Exact API equivalent of in_place_editor, except fixes various bugs (see
-README for the rationale) and:</p>
-<ul><li>
-<p>New option “:lock_var”, which is the name of a global variable to be used
-in the JS domain to track the lock version at the client side. By default
-set to nil, meaning no optimistic locking support. Options value
-“:lock_version” MUST be set to the lock version of the object for which the
-in-place editor is being created in this case. The variable is incremented
-each time the object is successfully updated through the in-place editor,
-since the server will have incremented its lock version so the client must
-keep in step. If someone else edits the item, the client and server lock
-versions will not match and the update will fail, which is the desired
-result.</p>
-</li><li>
-<p>The “:save_text” option is set to “OK” by default, since I detest that
-nasty lower case “ok” button that’s produced by the JS code otherwise.</p>
-</li><li>
-<p>The “:cancel_text” option is set to “Cancel” by default to match the above
-change.</p>
-</li><li>
-<p>New option “:is_boolean” indicating a true/false popup should be offered
-instead of a text field; if omitted, a text field is assumed. If present
-and ‘true’, additional optional value “:first_value” says whether or not
-the pop-up menu should start with True/Yes (if “:first_value”‘s value is
-itself true), or False/No (if “:first_value”’s value is itself false, or if
-the option is omitted).</p>
-</li></ul>
-
-<p>Custom on-failure and on-complete functions are used. To try and reduce the
-code bulk for each instance of the editor, hard-coded JS function names are
-used with the support code placed in ‘safe_in_place_editing.js’. See there
-for a reference implementation if intending to write customised
-equivalents. To override the default names of these functions for any
-reason, give the names as strings in options properties :on_complete and
-:on_failure, then make sure appropriate JS functions are actually defined.</p>
-
-
-
- <div class="method-source-code" id="safe_in_place_editor-source">
- <pre><span class="ruby-comment"># File lib/safe_in_place_editing/safe_in_place_editing_helper.rb, line 47</span>
-<span class="ruby-keyword">def</span> <span class="ruby-identifier">safe_in_place_editor</span>( <span class="ruby-identifier">field_id</span>, <span class="ruby-identifier">options</span> = {} )
-
- <span class="ruby-comment"># Set up some default values</span>
-
- <span class="ruby-identifier">options</span>[ <span class="ruby-value">:with</span> ] <span class="ruby-operator">||=</span> <span class="ruby-string">&quot;Form.serialize(form).replace(/\\+/g,'%20')&quot;</span>
-
- <span class="ruby-keyword">if</span> <span class="ruby-identifier">protect_against_forgery?</span>
- <span class="ruby-identifier">options</span>[ <span class="ruby-value">:with</span> ] <span class="ruby-operator">+=</span> <span class="ruby-node">&quot; + '&amp;authenticity_token=' + encodeURIComponent('#{ form_authenticity_token }')&quot;</span>
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-identifier">options</span>[ <span class="ruby-value">:on_complete</span> ] <span class="ruby-operator">||=</span> <span class="ruby-string">'safeInPlaceEditorOnComplete'</span>
- <span class="ruby-identifier">options</span>[ <span class="ruby-value">:on_failure</span> ] <span class="ruby-operator">||=</span> <span class="ruby-string">'safeInPlaceEditorOnFailure'</span>
- <span class="ruby-identifier">options</span>[ <span class="ruby-value">:save_text</span> ] <span class="ruby-operator">||=</span> <span class="ruby-string">'OK'</span>
- <span class="ruby-identifier">options</span>[ <span class="ruby-value">:cancel_text</span> ] <span class="ruby-operator">||=</span> <span class="ruby-string">'Cancel'</span>
-
- <span class="ruby-comment"># Preliminary script data</span>
-
- <span class="ruby-keyword">if</span> ( <span class="ruby-identifier">options</span>.<span class="ruby-identifier">include?</span>( <span class="ruby-value">:lock_var</span> ) )
- <span class="ruby-identifier">function</span> = <span class="ruby-node">&quot;window['#{ options[ :lock_var ] }']=#{ options[ :lock_version ] };&quot;</span>
- <span class="ruby-keyword">else</span>
- <span class="ruby-identifier">function</span> = <span class="ruby-string">''</span>
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-identifier">function_name</span> = <span class="ruby-identifier">options</span>[ <span class="ruby-value">:is_boolean</span> ] <span class="ruby-operator">?</span> <span class="ruby-string">'InPlaceCollectionEditor'</span> <span class="ruby-operator">:</span> <span class="ruby-string">'InPlaceEditor'</span>
-
- <span class="ruby-identifier">function</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;new Ajax.#{ function_name }(&quot;</span>
- <span class="ruby-identifier">function</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;'#{ field_id }', &quot;</span>
- <span class="ruby-identifier">function</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;'#{ url_for( options[ :url ] ) }'&quot;</span>
-
- <span class="ruby-comment"># Map Rails in-place editor options to JS in-place editor options - see:</span>
- <span class="ruby-comment">#</span>
- <span class="ruby-comment"># http://github.com/madrobby/scriptaculous/wikis/ajax-inplaceeditor</span>
-
- <span class="ruby-identifier">js_options</span> = {}
-
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'rows'</span> ] = <span class="ruby-identifier">options</span>[ <span class="ruby-value">:rows</span> ] <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:rows</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'cols'</span> ] = <span class="ruby-identifier">options</span>[ <span class="ruby-value">:cols</span> ] <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:cols</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'size'</span> ] = <span class="ruby-identifier">options</span>[ <span class="ruby-value">:size</span> ] <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:size</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'ajaxOptions'</span> ] = <span class="ruby-identifier">options</span>[ <span class="ruby-value">:options</span> ] <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:options</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'htmlResponse'</span> ] = <span class="ruby-operator">!</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:script</span> ] <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:script</span> ]
-
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'cancelText'</span> ] = <span class="ruby-node">%Q('#{ options[ :cancel_text ] }')</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:cancel_text</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'okText'</span> ] = <span class="ruby-node">%Q('#{ options[ :save_text ] }')</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:save_text</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'loadingText'</span> ] = <span class="ruby-node">%Q('#{ options[ :loading_text ] }')</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:loading_text</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'savingText'</span> ] = <span class="ruby-node">%Q('#{ options[ :saving_text ] }')</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:saving_text</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'clickToEditText'</span> ] = <span class="ruby-node">%Q('#{ options[ :click_to_edit_text ] }')</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:click_to_edit_text</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'textBetweenControls'</span> ] = <span class="ruby-node">%Q('#{ options[ :text_between_controls ] }')</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:text_between_controls</span> ]
-
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'externalControl'</span> ] = <span class="ruby-node">&quot;'#{ options[ :external_control ] }'&quot;</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:external_control</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'loadTextURL'</span> ] = <span class="ruby-node">&quot;'#{ url_for( options[ :load_text_url ] ) }'&quot;</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:load_text_url</span> ]
-
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'callback'</span> ] = <span class="ruby-node">&quot;function(form) { return #{ options[ :with ] }; }&quot;</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:with</span> ]
-
- <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:is_boolean</span> ]
- <span class="ruby-keyword">if</span> <span class="ruby-identifier">options</span>[ <span class="ruby-value">:start_value</span> ]
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'collection'</span> ] = <span class="ruby-string">&quot;[['true','Yes'],['false','No']]&quot;</span>
- <span class="ruby-keyword">else</span>
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'collection'</span> ] = <span class="ruby-string">&quot;[['false','No'],['true','Yes']]&quot;</span>
- <span class="ruby-keyword">end</span>
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-comment"># Set up the custom on-failure and on-complete handlers</span>
-
- <span class="ruby-identifier">js_options</span>[ <span class="ruby-string">'onFailure'</span> ] = <span class="ruby-node">&quot;#{ options[ :on_failure ] }&quot;</span>
-
- <span class="ruby-keyword">if</span> ( <span class="ruby-identifier">options</span>.<span class="ruby-identifier">include?</span>( <span class="ruby-value">:lock_var</span> ) )
- <span class="ruby-identifier">js_options</span>[<span class="ruby-string">'onComplete'</span>] = <span class="ruby-node">&quot;function(transport, element) {#{ options[ :on_complete ] }(transport,element,'#{ options[ :lock_var ] }');}&quot;</span>
- <span class="ruby-keyword">else</span>
- <span class="ruby-identifier">js_options</span>[<span class="ruby-string">'onComplete'</span>] = <span class="ruby-node">&quot;#{ options[ :on_complete ] }&quot;</span>
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-comment"># Assemble the content</span>
-
- <span class="ruby-identifier">function</span> <span class="ruby-operator">&lt;&lt;</span> ( <span class="ruby-string">', '</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">options_for_javascript</span>( <span class="ruby-identifier">js_options</span> ) ) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">js_options</span>.<span class="ruby-identifier">empty?</span>
- <span class="ruby-identifier">function</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-string">')'</span>
-
- <span class="ruby-keyword">return</span> <span class="ruby-identifier">javascript_tag</span>( <span class="ruby-identifier">function</span> )
-<span class="ruby-keyword">end</span></pre>
- </div><!-- safe_in_place_editor-source -->
-
- </div>
-
-
-
-
- </div><!-- safe_in_place_editor-method -->
-
-
- <div id="method-i-safe_in_place_editor_field" class="method-detail ">
-
- <div class="method-heading">
- <span class="method-name">safe_in_place_editor_field</span><span
- class="method-args">( object, method, tag_options = {}, editor_options = {}, no_escape = false )</span>
- <span class="method-click-advice">click to toggle source</span>
- </div>
-
-
- <div class="method-description">
-
- <p>Close API equivalent of in_place_editor_field, except fixes various bugs
-(see the README for rationale). Allows either an object name in the first
-parameter (e.g. “:foo”, in which case instance variable “@foo” must point
-to the object instance of interest) or an object instance (to save messing
-around with magic instance variables, but obtains the object name from
-“class.name.underscore”, so may not be appropriate for unusual object
-classes). Anyway, clearer error reporting and the ability to pass in an
-object reference directly may help avoid a common error experienced with
-the InPlaceEditing plug-in code, as described here at the time of writing:</p>
-
-<p><a
-href="http://oldwiki.rubyonrails.org/rails/pages/InPlaceEditing">oldwiki.rubyonrails.org/rails/pages/InPlaceEditing</a></p>
-
-<p>Includes the following options:</p>
-<ul><li>
-<p>:lock_var is the name of the variable used for optimistic locking, by
-default set to a row-unique value. The assumption is that this same
-variable gets used throughout the row so that multiple edits on that row
-all cause the same variable to be incremented. If your back-end update
-function has side effects that might invalidate the value shown in another
-column on that row - which would be pretty strange! - you’d need to
-override the lock variable name with something that’s unique to both the
-row and the column. When using a lock variable, additional option
-“:lock_version” is always set internally to the lock version of the object
-for which the field is being built and cannot be overridden.</p>
-</li><li>
-<p>:with is extended to include a “lock_version” parameter in the query string
-so that the client side’s idea of the current object’s lock version may be
-communicated to the server’s attribute update action. This is done
-internally; there is no need to set the option yourself.</p>
-</li></ul>
-
-<p>The editor options also support “is_boolean”, which overrides the default
-setting of whether or not the column value is considered to be a string or
-a boolean quantity. This is provided just-in-case, with no current known
-cases where the automatic detection isn’t sufficient.</p>
-
-<p>The Prototype library getText function must be patched as described in the
-README rationale; “application.js” is a good place to do this.</p>
-
-<p>Note an optional fifth parameter which if ‘true’ will prevent HTML escaping
-of the value for values which are really meant to contain HTML code. Be
-very, very careful with this.</p>
-
-
-
- <div class="method-source-code" id="safe_in_place_editor_field-source">
- <pre><span class="ruby-comment"># File lib/safe_in_place_editing/safe_in_place_editing_helper.rb, line 168</span>
-<span class="ruby-keyword">def</span> <span class="ruby-identifier">safe_in_place_editor_field</span>( <span class="ruby-identifier">object</span>, <span class="ruby-identifier">method</span>, <span class="ruby-identifier">tag_options</span> = {}, <span class="ruby-identifier">editor_options</span> = {}, <span class="ruby-identifier">no_escape</span> = <span class="ruby-keyword">false</span> )
-
- <span class="ruby-comment"># Allow a symbol or object instance to be passed. Since the symbol use</span>
- <span class="ruby-comment"># case involves accessing a 'magic' related instance variable name and</span>
- <span class="ruby-comment"># since there are lots of examples via Google of this confusing people,</span>
- <span class="ruby-comment"># raise a helpful error message if the relevant variable is missing.</span>
-
- <span class="ruby-keyword">if</span> ( <span class="ruby-identifier">object</span>.<span class="ruby-identifier">instance_of?</span>( <span class="ruby-constant">Symbol</span> ) )
- <span class="ruby-identifier">object_name</span> = <span class="ruby-identifier">object</span>
- <span class="ruby-identifier">var_name</span> = <span class="ruby-node">&quot;@#{ object_name }&quot;</span>
- <span class="ruby-keyword">if</span> ( <span class="ruby-identifier">instance_variable_defined?</span>( <span class="ruby-identifier">var_name</span> ) )
- <span class="ruby-identifier">object</span> = <span class="ruby-identifier">instance_variable_get</span>( <span class="ruby-identifier">var_name</span> )
- <span class="ruby-keyword">else</span>
- <span class="ruby-identifier">raise</span>( <span class="ruby-string">'If passing \:foo\ to in_place_editor_field, \@foo\ must refer to the object for which the field is being built'</span> )
- <span class="ruby-keyword">end</span>
- <span class="ruby-keyword">else</span>
- <span class="ruby-identifier">object_name</span> = <span class="ruby-identifier">object</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">name</span>.<span class="ruby-identifier">underscore</span>
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-comment"># Pass the lock version in for optimistic locking support, should the</span>
- <span class="ruby-comment"># object support it. The update callback function must manually compare</span>
- <span class="ruby-comment"># the params[ :lock_version ] value against the lock_version.to_s()</span>
- <span class="ruby-comment"># value of the object that's being updated.</span>
-
- <span class="ruby-keyword">if</span> ( <span class="ruby-identifier">object</span>.<span class="ruby-identifier">respond_to?</span>( <span class="ruby-value">:lock_version</span> ) )
- <span class="ruby-identifier">var</span> = <span class="ruby-node">&quot;#{ object_name }_#{ object.id }_safeInPlaceEditorLockVersion&quot;</span>
-
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:lock_version</span> ] = <span class="ruby-identifier">object</span>.<span class="ruby-identifier">lock_version</span>.<span class="ruby-identifier">to_s</span>
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:lock_var</span> ] <span class="ruby-operator">||=</span> <span class="ruby-identifier">var</span>
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:with</span> ] <span class="ruby-operator">||=</span> <span class="ruby-string">&quot;Form.serialize(form).replace(/\\+/g,'%20')&quot;</span>
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:with</span> ] <span class="ruby-operator">+=</span> <span class="ruby-node">&quot; + '&amp;lock_version=' + #{ var }&quot;</span>
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-comment"># Escape the value unless told not to and construct the complete in-place</span>
- <span class="ruby-comment"># editor assembly. Check for boolean values too, allowing caller-override.</span>
-
- <span class="ruby-identifier">column_value</span> = <span class="ruby-identifier">object</span>.<span class="ruby-identifier">send</span>( <span class="ruby-identifier">method</span> )
-
- <span class="ruby-identifier">is_boolean</span> = ( <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:is_boolean</span> ] <span class="ruby-operator">||</span> ( <span class="ruby-identifier">column_value</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">TrueClass</span> ) <span class="ruby-operator">||</span> ( <span class="ruby-identifier">column_value</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">FalseClass</span> ) )
-
- <span class="ruby-keyword">if</span> ( <span class="ruby-identifier">is_boolean</span> )
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:start_value</span> ] = <span class="ruby-operator">!</span><span class="ruby-operator">!</span> <span class="ruby-identifier">column_value</span>
- <span class="ruby-identifier">column_value</span> = <span class="ruby-identifier">column_value</span> <span class="ruby-operator">?</span> <span class="ruby-string">'Yes'</span> <span class="ruby-operator">:</span> <span class="ruby-string">'No'</span>
- <span class="ruby-keyword">else</span>
- <span class="ruby-identifier">column_value</span> = <span class="ruby-constant">ERB</span><span class="ruby-operator">::</span><span class="ruby-constant">Util</span><span class="ruby-operator">::</span><span class="ruby-identifier">html_escape</span>( <span class="ruby-identifier">column_value</span> ) <span class="ruby-keyword">unless</span> ( <span class="ruby-identifier">no_escape</span> )
- <span class="ruby-keyword">end</span>
-
- <span class="ruby-identifier">tag_options</span> = {
- <span class="ruby-value">:id</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">&quot;#{object_name}_#{method}_#{object.id}_in_place_editor&quot;</span>,
- <span class="ruby-value">:class</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-string">&quot;in_place_editor_field&quot;</span>
- }.<span class="ruby-identifier">merge!</span>( <span class="ruby-identifier">tag_options</span> )
-
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:url</span> ] <span class="ruby-operator">||=</span> <span class="ruby-identifier">url_for</span>( {
- <span class="ruby-value">:action</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">&quot;set_#{object_name}_#{method}&quot;</span>,
- <span class="ruby-value">:id</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">object</span>.<span class="ruby-identifier">id</span>
- } )
-
- <span class="ruby-comment"># Update the boolean value flag, unless the caller had already set one.</span>
-
- <span class="ruby-identifier">editor_options</span>[ <span class="ruby-value">:is_boolean</span> ] = <span class="ruby-identifier">is_boolean</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">editor_options</span>.<span class="ruby-identifier">has_key?</span>( <span class="ruby-value">:is_boolean</span> )
-
- <span class="ruby-keyword">return</span> <span class="ruby-identifier">content_tag</span>( <span class="ruby-value">:span</span>, <span class="ruby-identifier">column_value</span>.<span class="ruby-identifier">html_safe</span>, <span class="ruby-identifier">tag_options</span> ) <span class="ruby-operator">+</span>
- <span class="ruby-identifier">safe_in_place_editor</span>( <span class="ruby-identifier">tag_options</span>[ <span class="ruby-value">:id</span> ], <span class="ruby-identifier">editor_options</span> )
-<span class="ruby-keyword">end</span></pre>
- </div><!-- safe_in_place_editor_field-source -->
-
- </div>
-
-
-
-
- </div><!-- safe_in_place_editor_field-method -->
-
-
- </section><!-- public-instance-method-details -->
-
- </section><!-- 5Buntitled-5D -->
-
-</div><!-- documentation -->
-
-
-<footer id="validator-badges">
- <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
- <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.12.2.
- <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
-</footer>
-
View
20 lib/safe_in_place_editing/MIT-LICENSE
@@ -1,20 +0,0 @@
-Copyright (c) 2008 Hipposoft
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
228 lib/safe_in_place_editing/README
@@ -1,228 +0,0 @@
-
-SafeInPlaceEditing 0.03 26-Sep-2013
-================== ================
-
-The stock InPlaceEditing plug-in code is inadequate for a few reasons
-documented below. This compelled me to write a replacement. For all of
-the shortcomings I may perceive in the InPlaceEditing plug-in, though,
-this plug-in would not exist without the original, from which it
-borrows very heavily. My thanks to all involved.
-
-This variant attempts to fix the problems described below.
-
-
-1) InPlaceEditing introduces an XSS vulnerability
--------------------------------------------------
-
-One call to in_place_editor_field and you've just introduced an XSS
-security vulnerability into your site. The implementation calls an
-undocumented internal Rails interface to put the field value into the
-page in the first place, which does not use ERB::Util::html_escape to do
-so. The in-place editor JS does NOT (contrary to its documentation) strip
-HTML on entered values and the helper method "in_place_edit_for" builds a
-Controller method which updates the field and renders its new value again
-with no escaping. One can easily enter arbitrary JavaScript and have it
-executed. It's practically your very own JavaScript console for each
-in-place editor field. Oops.
-
-If we fix the in_place_editor_field code (in passing using a clue from
-ActiveScaffold which shows how to write smaller code without using the
-undocumented interface) and we update in_place_edit_for to render escaped
-text, then we arrive at something like this:
-
- def in_place_editor_field(...etc...)
- # Get the object's name into 'object_name' and *actual* object into
- # 'object' - this exercise left to reader
- #
- # You might also wish to let the function accept an object name or
- # an object reference as well as being more explicit about the magic
- # instance variable name it assumes if given an object name instead,
- # so that Google doesn't fill up with any more confused people
- # who've been caught out by the rather confusing API.
- #
- column_value = ERB::Util::html_escape(object.send(method))
- tag_options = {:tag => "span", :id =>
- "#{object_name}_#{method}_#{object.id}_in_place_editor", :class
- => "in_place_editor_field"}.merge!(tag_options)
- in_place_editor_options[:url] = in_place_editor_options[:url] ||
- url_for({ :action => "set_#{object_name}_#{method}", :id
- => object.id })
- content_tag(:span, column_value, tag_options) +
- in_place_editor(tag_options[:id], in_place_editor_options)
- end
-
- def in_place_edit_for(object, attribute, options = {})
- define_method("set_#{object}_#{attribute}") do
- @item = object.to_s.camelize.constantize.find(params[:id])
- @item.update_attribute(attribute, params[:value])
- render :text => ERB::Util::html_escape(@item.send(attribute).to_s)
- end
- end
-
-...but then we encounter more problems:
-
-(1) It's no longer possible to deliberately insert HTML, as per
- documentation examples for Textile and Markaby in-place editors.
-
-(2) The in-place editor form, when shown, shows the *literal* escaped
- text because it uses a "getText" call in the JS domain that reads
- "innerHTML" of the <span> used to mark up the text to be used for
- editing. There are two ways around this:
-
- * Patch getText to a better implementation as described on the
- scriptalicious Wiki (why is this not in their core release?!)
-
- http://github.com/madrobby/scriptaculous/wikis/ajax-inplaceeditor
-
- Object.extend(Ajax.InPlaceEditor.prototype, {
- getText: function() {
- return this.element.childNodes[0] ?
- this.element.childNodes[0].nodeValue : '';
- }
- });
-
- * Have a custom method to return the unescaped value of the field
- sitting on the server side (again, as for the Textile and Markaby
- examples) - but this means one more controller method and a server
- round-trip each time an editor is shown.
-
-SafeInPlaceEditing patches getText as described above, escapes values in
-the initially created form and its auto-generated helpers, if used, escape
-updated values when rendering them for the in-place view update. You can
-defeat escaping in the safe_in_place_editor_field helper method with a
-special override parameter but this is strongly discouraged.
-
-You must include the JavaScript code for the getText patch and supporting
-methods:
-
- <%= javascript_include_tag( "safe_in_place_editing/safe_in_place_editing" ) %>
-
-
-2) InPlaceEditing bypasses optimistic locking
----------------------------------------------
-
-List views do not hold references to objects so the lock version of an
-item with an in-place editor present is not recorded. The update code is
-forced to find a new object in the database by ID, so it always operates
-on a brand new object. Any changes someone else might have made while the
-first user was looking at their in-place editor view will be trampled over.
-
-One might take the approach of the anti-forgery request mechanism patch
-needed to get the in-place edit plug-in working with Rails 2, extending
-the ":with" key's value in the options hash with a query string passing
-the lock_version through:
-
- if ( object.respond_to?( :lock_version ) )
- in_place_editor_options[ :with ] ||= "Form.serialize(form)"
- in_place_editor_options[ :with ] += " +
- '&lock_version=#{ object.lock_version }'"
- end
-
-The update code on the server side could manually check this against the
-object it just found in the database. Unfortunately the form JavaScript
-is static, so after a first update the form itself is out of date,
-passing an old lock version through so all subsequent update attempts
-fail until the whole view is reloaded.
-
- lock_version = nil
- lock_version = @item.lock_version.to_s if
- (@item.respond_to?(:lock_version))
-
- if ( lock_version != params[ :lock_version ] )
- # Somebody else already edited this item. Do "something"
- # (see later).
- else
- @item.update_attribute( attribute, params[ :value ] )
- end
-
-We might attempt to write out JS which assigns global variables unique to
-each form with the initial lock value. An on-complete JS handler could
-then increment the lock version at the client side. But this is
-ridiculously complex for the task at hand, requires one to override the
-default on-complete handler, bypass or extend the Rails plug-in (since it
-offers no interface to change the on-complete handler details) and the
-client might still get out of sync with the server's lock versions. Since
-there is little alternative, SafeInPlaceEditing takes this approach, using
-extra JS support methods to try and reduce the inline code baggage.
-
-
-3) Error handling seems to be faulty
-------------------------------------
-
-In theory, returning a 500 error should lead to the onFailure handler
-running in the JS domain, but when used from Rails 2.0.2, the just about
-all properties of the 'transport' object used in the default handler
-function are undefined. As a result, no alert box can be shown to the user.
-
-The onComplete handler is *always* run, regardless of whether the request
-returns a 2xx or other status code. The transport.status value must be
-checked carefully by custom handler code. The responseText value is set
-correctly for failure cases here, so custom handler code must be used to
-report errors as well as handle the "it worked" case. This means custom
-JS written out for every single in-line editor field on the page and an
-extension to the plug-in since it doesn't expose the onComplete or
-onFailure JS options in its API.
-
-The JavaScript assistance functions included with SafeInPlaceEditing take
-care of error handling so that if the on-failure code seems to be having
-trouble the on-complete code will take over. These functions are also
-used to support optimistic locking as described above.
-
-
-3) It breaks when used with Prototype 1.7
------------------------------------------
-
-If running on newer Prototype JavaScript libraries (or jQuery for that
-matter), spaces in form fields are converted into "+" rather than URL
-escaped in "%XX" hex notation. The processing path within the whole Rails
-stack that receives the form submission from JavaScript is not able to
-understand this so "+" remains as such; indeed, when Form.serialize() in
-JavaScript code correctly encodes "+" to "%2B" and converts " " to "+",
-Rails makes a huge mess by correctly decoding "%2B" back to "+", but
-incorrectly leaving "+" as "+". A user-input plus is indistinguishable
-from a user-input space by the time application code runs.
-
-See RFC 1866 and for example:
-
- http://stackoverflow.com/questions/5366007/why-does-the-encodings-of-a-url-and-the-query-string-part-differ
-
-The way to fix this is by replacing "+" with "%20" in JavaScript. It will
-mean a techncially non-RFC 1866 compliant URL, but will still be obeying
-wider URL encoding rules so should pass through servers unmolested and
-will be correctly decoded by Rails.
-
-
-5) It is falling out of date
-----------------------------
-
-In-place editing was moved to a plug-in in more recent versions of Rails,
-but is has stagnated. It requires a patch just to work with the
-anti-request-forgery (CSRF) mechanism of Rails 2. It isn't RESTful. It's
-wasteful, requiring multiple near-identical handler methods in the
-Controller to deal with field updates.
-
-Some of that's the same with SafeInPlaceEditing. It certainly isn't
-RESTful, but it tries to reduce controller bloat a bit and doesn't need
-patching for Rails 2. It knows about optimistic locking and takes more
-care over security.
-
-
-Examples
-========
-
-See above. See also documentation for the standard InPlaceEditor plug-in.
-Use "safe_in_place_edit_for" where you'd have used "in_place_edit_for" in
-controllers; use "safe_in_place_editor_field" where you'd have used
-"in_place_editor_field" in views. The API is otherwise the same but works
-transparently for fields containing boolean values too, not just strings.
-
-
-Contacts
-========
-
-Feel free to contact me at "ahodgkin@rowing.org.uk" with questions, patches
-or suggestions. Or even praise, if you reckon this is worth it :-)
-
- http://pond.org.uk/
-
-Copyright (c) 2008-2013 Hipposoft, released under the MIT license.
View
95 lib/safe_in_place_editing/safe_in_place_editing.rb
@@ -1,95 +0,0 @@
-########################################################################
-# File:: safe_in_place_editing.rb
-# (C):: Hipposoft 2008
-#
-# Purpose:: Safe, lockable in-place editing - controller support.
-# ----------------------------------------------------------------------
-# 24-Jun-2008 (ADH): Created.
-########################################################################
-
-module SafeInPlaceEditing
-
- def self.included( base ) # :nodoc:
- base.extend( ClassMethods )
- end
-
- module ClassMethods
-
- # Exact API equivalent of in_place_edit_for, except:
- #
- # - Runs all user data through "ERB::Util::html_escape" when sending it to
- # the view to avoid associated vulnerabilities with otherwise-unescaped
- # user-supplied data; the current InPlaceEditing plugin does this too,
- # albeit using "CGI::escapeHTML" for some reason.
- #
- # - Supports optimistic locking if a lock_version CGI parameter is
- # supplied, by explicitly checking the version being updated.
- #
- # - Explicitly catches errors and returns them as 500 status codes
- # with a plain text message regardless of Rails environment.
- #
- # See safe_in_place_editor and safe_in_place_editor_field inside file
- # "safe_in_place_editing_helper.rb" for the counterpart helper functions.
- #
- # The Prototype library getText function must be patched as described in
- # the README rationale; see public/javascripts/safe_in_place_editing.js.
-
- def safe_in_place_edit_for( object, attribute, options = {} )
- define_method( "set_#{object}_#{attribute}" ) do
- safe_in_place_edit_backend( object, attribute, options )
- end
- end
- end
-
-private
-
- # Back-end for "safe_in_place_edit_for" - the actual invoked implementation
- # of the dynamically created functions.
-
- def safe_in_place_edit_backend( object, attribute, options )
- @item = object.to_s.camelize.constantize.find( params[ :id ] )
-
- lock_version = nil
- lock_version = @item.lock_version.to_s if ( @item.respond_to?( :lock_version ) )
-
- if ( params.include?( :lock_version ) and lock_version != params[ :lock_version ] )
- render( { :status => 500, :text => "Somebody else already edited this #{ object.to_s.humanize.downcase }. Reload the page to obtain the updated version." } )
- return
- else
- begin
-
- # Call "touch" to make sure the item is modified even if the user has
- # actually just submitted the form with an unchanged variable. This
- # makes sure that Rails sees the object as 'dirty' and saves it. For
- # objects with lock versions, that means the lock version always
- # increments. The JavaScript code has to assume such an increment and
- # has no clear way to know if it doesn't happen; we could dream up
- # something complex but simpler just to ensure Rails is in step.
- #
- # In the worst possible case, JavaScript and Rails end up out of step
- # with the lock version and the user gets told there's a mismatch. A
- # page reload later and everything is sorted out.
-
- success = @item.update_attribute( attribute, params[ :value ] )
- success = @item.touch if ( success && ! lock_version.nil? && @item.lock_version.to_s == lock_version )
-
- raise "Unable to save changes to database" unless ( success )
-
- rescue => error
- render( { :status => 500, :text => error.message } )
- return
-
- end
- end
-
- value = @item.send( attribute )
-
- if ( ( value.is_a? TrueClass ) || ( value.is_a? FalseClass ) )
- value = value ? 'Yes' : 'No'
- else
- value = ERB::Util::html_escape( value.to_s )
- end
-
- render( { :text => value } )
- end
-end
View
78 ...afe_in_place_editing/resources/javascripts/safe_in_place_editing/safe_in_place_editing.js
@@ -1,78 +0,0 @@
-/************************************************************************\
- * File: safe_in_place_editing.js *
- * Hipposoft 2008 *
- * *
- * Purpose: Safe, lockable in-place editing - client-side code. *
- * *
- * History: 24-Jun-2008 (ADH): Created. *
-\************************************************************************/
-
-/* Stop "Jack &amp; Jill", written for display purposes into an HTML page,
- * from being edited as exactly that - "Jack &amp; Jill" - if the in-place
- * editor is activated due to Prototype's use of "innerHTML" in its internal
- * "getText" function. See:
- *
- * http://github.com/madrobby/scriptaculous/wikis/ajax-inplaceeditor
- */
-
-Object.extend
-(
- Ajax.InPlaceEditor.prototype,
- {
- getText: function()
- {
- return this.element.childNodes[ 0 ] ? this.element.childNodes[ 0 ].nodeValue : '';
- }
- }
-);
-
-/* Support the "on success" and "on failure" functions */
-
-var safeInPlaceEditorDoneFailureReport = false;
-
-/* Custom in-place editor "on failure" function */
-
-function safeInPlaceEditorOnFailure( transport )
-{
- if ( transport.responseText )
- {
- safeInPlaceEditorRaiseAlert( transport );
- safeInPlaceEditorDoneFailureReport = true;
- }
- else
- {
- safeInPlaceEditorDoneFailureReport = false;
- }
-}
-
-/* Custom in-place editor "on complete" function (call by proxy to set
- * the value of 'lockVar' with the name of the lock variable, if any,
- * held in global (i.e. 'window') context).
- */
-
-function safeInPlaceEditorOnComplete( transport, element, lockVar )
-{
- if ( transport.status == 200 )
- {
- if ( lockVar ) window[ lockVar ] += 1;
- }
- else if ( ! safeInPlaceEditorDoneFailureReport )
- {
- safeInPlaceEditorRaiseAlert( transport );
- }
-
- safeInPlaceEditorDoneFailureReport = false;
-}
-
-/* Helper function - raise an alert describing the given transport object's
- * responseText value.
- */
-
-function safeInPlaceEditorRaiseAlert( transport )
-{
- alert
- (
- "Error communicating with the server: " +
- transport.responseText.stripTags()
- );
-}
View
232 lib/safe_in_place_editing/safe_in_place_editing_helper.rb
@@ -1,232 +0,0 @@
-########################################################################
-# File:: safe_in_place_editing_helper.rb
-# (C):: Hipposoft 2008
-#
-# Purpose:: Safe, lockable in-place editing - helper methods.
-# ----------------------------------------------------------------------
-# 24-Jun-2008 (ADH): Created.
-########################################################################
-
-module SafeInPlaceEditingHelper
-
- # Exact API equivalent of in_place_editor, except fixes various bugs
- # (see README for the rationale) and:
- #
- # - New option ":lock_var", which is the name of a global variable to be
- # used in the JS domain to track the lock version at the client side. By
- # default set to nil, meaning no optimistic locking support. Options
- # value ":lock_version" MUST be set to the lock version of the object for
- # which the in-place editor is being created in this case. The variable
- # is incremented each time the object is successfully updated through the
- # in-place editor, since the server will have incremented its lock version
- # so the client must keep in step. If someone else edits the item, the
- # client and server lock versions will not match and the update will fail,
- # which is the desired result.
- #
- # - The ":save_text" option is set to "OK" by default, since I detest that
- # nasty lower case "ok" button that's produced by the JS code otherwise.
- #
- # - The ":cancel_text" option is set to "Cancel" by default to match the
- # above change.
- #
- # - New option ":is_boolean" indicating a true/false popup should be offered
- # instead of a text field; if omitted, a text field is assumed. If present
- # and 'true', additional optional value ":first_value" says whether or not
- # the pop-up menu should start with True/Yes (if ":first_value"'s value is
- # itself true), or False/No (if ":first_value"'s value is itself false, or
- # if the option is omitted).
- #
- # Custom on-failure and on-complete functions are used. To try and reduce
- # the code bulk for each instance of the editor, hard-coded JS function names
- # are used with the support code placed in 'safe_in_place_editing.js'. See
- # there for a reference implementation if intending to write customised
- # equivalents. To override the default names of these functions for any
- # reason, give the names as strings in options properties :on_complete and
- # :on_failure, then make sure appropriate JS functions are actually defined.
- #
- def safe_in_place_editor( field_id, options = {} )
-
- # Set up some default values
-
- options[ :with ] ||= "Form.serialize(form).replace(/\\+/g,'%20')"
-
- if protect_against_forgery?
- options[ :with ] += " + '&authenticity_token=' + encodeURIComponent('#{ form_authenticity_token }')"
- end
-
- options[ :on_complete ] ||= 'safeInPlaceEditorOnComplete'
- options[ :on_failure ] ||= 'safeInPlaceEditorOnFailure'
- options[ :save_text ] ||= 'OK'
- options[ :cancel_text ] ||= 'Cancel'
-
- # Preliminary script data
-
- if ( options.include?( :lock_var ) )
- function = "window['#{ options[ :lock_var ] }']=#{ options[ :lock_version ] };"
- else
- function = ''
- end
-
- function_name = options[ :is_boolean ] ? 'InPlaceCollectionEditor' : 'InPlaceEditor'
-
- function << "new Ajax.#{ function_name }("
- function << "'#{ field_id }', "
- function << "'#{ url_for( options[ :url ] ) }'"
-
- # Map Rails in-place editor options to JS in-place editor options - see:
- #
- # http://github.com/madrobby/scriptaculous/wikis/ajax-inplaceeditor
-
- js_options = {}
-
- js_options[ 'rows' ] = options[ :rows ] if options[ :rows ]
- js_options[ 'cols' ] = options[ :cols ] if options[ :cols ]
- js_options[ 'size' ] = options[ :size ] if options[ :size ]
- js_options[ 'ajaxOptions' ] = options[ :options ] if options[ :options ]
- js_options[ 'htmlResponse' ] = ! options[ :script ] if options[ :script ]
-
- js_options[ 'cancelText' ] = %('#{ options[ :cancel_text ] }') if options[ :cancel_text ]
- js_options[ 'okText' ] = %('#{ options[ :save_text ] }') if options[ :save_text ]
- js_options[ 'loadingText' ] = %('#{ options[ :loading_text ] }') if options[ :loading_text ]
- js_options[ 'savingText' ] = %('#{ options[ :saving_text ] }') if options[ :saving_text ]
- js_options[ 'clickToEditText' ] = %('#{ options[ :click_to_edit_text ] }') if options[ :click_to_edit_text ]
- js_options[ 'textBetweenControls' ] = %('#{ options[ :text_between_controls ] }') if options[ :text_between_controls ]
-
- js_options[ 'externalControl' ] = "'#{ options[ :external_control ] }'" if options[ :external_control ]
- js_options[ 'loadTextURL' ] = "'#{ url_for( options[ :load_text_url ] ) }'" if options[ :load_text_url ]
-
- js_options[ 'callback' ] = "function(form) { return #{ options[ :with ] }; }" if options[ :with ]
-
- if options[ :is_boolean ]
- if options[ :start_value ]
- js_options[ 'collection' ] = "[['true','Yes'],['false','No']]"
- else
- js_options[ 'collection' ] = "[['false','No'],['true','Yes']]"
- end
- end
-
- # Set up the custom on-failure and on-complete handlers
-
- js_options[ 'onFailure' ] = "#{ options[ :on_failure ] }"
-
- if ( options.include?( :lock_var ) )
- js_options['onComplete'] = "function(transport, element) {#{ options[ :on_complete ] }(transport,element,'#{ options[ :lock_var ] }');}"
- else
- js_options['onComplete'] = "#{ options[ :on_complete ] }"
- end
-
- # Assemble the content
-
- function << ( ', ' + options_for_javascript( js_options ) ) unless js_options.empty?
- function << ')'
-
- return javascript_tag( function )
- end
-
- # Close API equivalent of in_place_editor_field, except fixes various bugs
- # (see the README for rationale). Allows either an object name in the first
- # parameter (e.g. ":foo", in which case instance variable "@foo" must point
- # to the object instance of interest) or an object instance (to save messing
- # around with magic instance variables, but obtains the object name from
- # "class.name.underscore", so may not be appropriate for unusual object
- # classes). Anyway, clearer error reporting and the ability to pass in an
- # object reference directly may help avoid a common error experienced with
- # the InPlaceEditing plug-in code, as described here at the time of writing:
- #
- # http://oldwiki.rubyonrails.org/rails/pages/InPlaceEditing
- #
- # Includes the following options:
- #
- # - :lock_var is the name of the variable used for optimistic locking, by
- # default set to a row-unique value. The assumption is that this same
- # variable gets used throughout the row so that multiple edits on that
- # row all cause the same variable to be incremented. If your back-end
- # update function has side effects that might invalidate the value shown
- # in another column on that row - which would be pretty strange! - you'd
- # need to override the lock variable name with something that's unique to
- # both the row and the column. When using a lock variable, additional
- # option ":lock_version" is always set internally to the lock version of
- # the object for which the field is being built and cannot be overridden.
- #
- # - :with is extended to include a "lock_version" parameter in the query
- # string so that the client side's idea of the current object's lock
- # version may be communicated to the server's attribute update action.
- # This is done internally; there is no need to set the option yourself.
- #
- # The editor options also support "is_boolean", which overrides the default
- # setting of whether or not the column value is considered to be a string
- # or a boolean quantity. This is provided just-in-case, with no current
- # known cases where the automatic detection isn't sufficient.
- #
- # The Prototype library getText function must be patched as described in
- # the README rationale; "application.js" is a good place to do this.
- #
- # Note an optional fifth parameter which if 'true' will prevent HTML
- # escaping of the value for values which are really meant to contain HTML
- # code. Be very, very careful with this.
- #
- def safe_in_place_editor_field( object, method, tag_options = {}, editor_options = {}, no_escape = false )
-
- # Allow a symbol or object instance to be passed. Since the symbol use
- # case involves accessing a 'magic' related instance variable name and
- # since there are lots of examples via Google of this confusing people,
- # raise a helpful error message if the relevant variable is missing.
-
- if ( object.instance_of?( Symbol ) )
- object_name = object
- var_name = "@#{ object_name }"
- if ( instance_variable_defined?( var_name ) )
- object = instance_variable_get( var_name )
- else
- raise( 'If passing \':foo\' to in_place_editor_field, \'@foo\' must refer to the object for which the field is being built' )
- end
- else
- object_name = object.class.name.underscore
- end
-
- # Pass the lock version in for optimistic locking support, should the
- # object support it. The update callback function must manually compare
- # the params[ :lock_version ] value against the lock_version.to_s()
- # value of the object that's being updated.
-
- if ( object.respond_to?( :lock_version ) )
- var = "#{ object_name }_#{ object.id }_safeInPlaceEditorLockVersion"
-
- editor_options[ :lock_version ] = object.lock_version.to_s
- editor_options[ :lock_var ] ||= var
- editor_options[ :with ] ||= "Form.serialize(form).replace(/\\+/g,'%20')"
- editor_options[ :with ] += " + '&lock_version=' + #{ var }"
- end
-
- # Escape the value unless told not to and construct the complete in-place
- # editor assembly. Check for boolean values too, allowing caller-override.
-
- column_value = object.send( method )
-
- is_boolean = ( editor_options[ :is_boolean ] || ( column_value.is_a? TrueClass ) || ( column_value.is_a? FalseClass ) )
-
- if ( is_boolean )
- editor_options[ :start_value ] = !! column_value
- column_value = column_value ? 'Yes' : 'No'
- else
- column_value = ERB::Util::html_escape( column_value ) unless ( no_escape )
- end
-
- tag_options = {
- :id => "#{object_name}_#{method}_#{object.id}_in_place_editor",
- :class => "in_place_editor_field"
- }.merge!( tag_options )
-
- editor_options[ :url ] ||= url_for( {
- :action => "set_#{object_name}_#{method}",
- :id => object.id
- } )
-
- # Update the boolean value flag, unless the caller had already set one.
-
- editor_options[ :is_boolean ] = is_boolean unless editor_options.has_key?( :is_boolean )
-
- return content_tag( :span, column_value.html_safe, tag_options ) +
- safe_in_place_editor( tag_options[ :id ], editor_options )
- end
-end