You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by fa...@apache.org on 2009/08/30 18:30:39 UTC

svn commit: r809371 [2/10] - in /labs/consite/trunk/conferences: ./ app/views/admin/con/dashboard/ app/views/layouts/ db/ db/migrate/ lib/ lib/tasks/ public/images/conferences/ vendor/plugins/active_scaffold/ vendor/plugins/active_scaffold/.git/ vendor...

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/CHANGELOG
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/CHANGELOG?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/CHANGELOG (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/CHANGELOG Sun Aug 30 16:30:26 2009
@@ -0,0 +1,152 @@
+= 1.2RC1
+
+== FEATURES
+
+- Added view helpers (active_scaffold_javascripts, active_scaffold_stylesheets, active_scaffold_ie_stylesheets) to help with asset cacheing (Alexander Semyonov)
+- Works with Rails 2.1 (2.0 / 1.2.x will continue to be supported by version 1.1)
+
+== FIXES
+
+- Javascript compatibility with FF3 / Safari 3.1 (Mike Dalessio)
+  see http://groups.google.com/group/activescaffold/browse_thread/thread/d37afa3f2ac687f2/b34ebf62d767bee3
+- Avoid ruby deprecation warning in config/list.rb (Dustin Sallings)
+- Fixes bug where template overrides are ignored when placed in Engines plugins (Mike Dalessio)
+- Fixed in_place_editor to work with latest control.js
+- Fixed infinite recursion bug when creating a new record with a new association
+- Subform action name conflict fix
+- Helpful warning message if record_select is not on a column with an association
+
+= 1.1.1
+
+== FIXES
+
+* rendering for rails 1.2.x
+
+= 1.1.0
+
+== FEATURES
+
+* `render :super' now accepts a :locals option
+* parameter-based conditions now support arrays of values (e.g. users?name[]=bob&name[]=fred becomes "name IN ('bob', 'fred')")
+
+== FIXES
+
+* `render :super' now works from active_scaffold_overrides without endlessly looping
+* `render :super' no longer assumes that the *immediate* caller was the override template file
+* `render :super' works better with windows file names (e.g. c:/...)
+* reload_if_empty() javascript now uses GET
+* inplace_edit now uses POST instead of GET
+* adding time and date fields to ignore list for determining whether subform row is empty. previously only datetime was ignored.
+* closed a potential internet explorer security issue in dhtml_history.js library
+
+= 1.1.0 RC1
+
+== FEATURES
+
+=== LIST
+* row class: new helper method (list_row_class) gets called for each record in the list and returns a CSS class.
+* automatically link to the :show action of singular associations. this is similar to the nested scaffolds for plural associations.
+* column.list_ui: good for when you want to render multiple columns the same way.
+* * built-in list interface options:
+* * * for inplace edits - checkbox
+* Support :joins_for_collection in column_calculation
+* inplace_edit option on list columns. currently works for text boxes and booleans
+
+=== CREATE/UPDATE
+* file uploads - largely taken care of by file_column bridge.
+* * automatically detects if FileColumn is installed.  If so, uses it, and sets the form_ui for file columns to be file upload fields
+* * sets multipart? on config.create and config.update if file_columns are used on the target model
+* * Posts through iframe to give ajax-style file uploads
+* * Image columns are recognized and previewed as such
+* * Ability to delete a file
+* form_ui
+* * form interface options are now supported through helper method named active_scaffold_input_#{form_ui}. if you want a different form interface than activescaffold normally provides, you may configure the form_ui for that column to use one of these methods. you can easily define your own, too.
+* * built-in form interface options:
+* * * for associations - singular_association, plural_association, select, record_select
+* * * others - select, checkbox, country, password, textarea, usa_state, virtual, boolean
+* * subforms respect form_ui settings. but if form_ui is empty, it will be set to :select to disable subform nesting.
+* boolean columns: when the database column allows nil, we now add a third option to the dropdown so you don't *have* to pick true or false.
+* new :params option for a column lets you specify additional parameters to accept when the given column is on the form. this is for when a column needs to submit multiple values to work.
+* improved support for associations in parameters. for simply selecting/deselecting associations, activescaffold will now recognize `:user => 5' or `:users => [1, 2, 5]'.
+* Supply a unique id from active_scaffold_input_options for form fields.
+* added after_update_save controller override method
+
+=== EMBEDDING
+* `render :active_scaffold' now accepts a :conditions option, which is a weaker but more flexible variation of :constraints
+* active_scaffold_includes now accepts a frontend name. this is necessary so you can include the proper assets even if active_scaffold isn't configured on the current controller (it's embedded).
+* polymorphic constraints are now supported, assuming params[:parent_model].to_s is the proper content for the polymorphic _type field.
+* Beefing up the constraint system so it can handle has_one/belongs_to. Specifically, it can now disassociate a previous relationship before setting a new one. For example, Bear has_one Den. If creating a new Den, constrained to a certain Bear, the constraints system will now disassociate any previous Den from the Bear before associating the new one.
+
+=== NESTING
+* :through associations may now be nested
+* nested#shallow_delete
+
+=== SEARCH
+* fieldsearch module handles booleans better - provides third option so you don't *have* to search on a boolean column
+* In field search lock_version is the only magic column. May want to search by :id or date fields.
+
+=== GENERAL
+* use #human_name for the column label when possible.
+* merge_conditions now supports hash conditions (and should forever support every conditions style that ActiveRecord supports)
+* action links may now remove an action link with #clear_link
+* action links have a new :controller option, so you don't have to sneak it into :params anymore
+* dhtml history may now be disabled
+* authorized_for? in ActiveRecordPermissions now calls respond_to? only as much as needed
+* removing an assert_valid_keys? call in active_record_permissions#authorized_for?. it just wasn't worth the CPU time.
+* render :super is now extension-agnostic. ex: `render :super` in list.html.erb will properly find list.rhtml as the "parent" template.
+* Auto-bridge loading mechanism.  Bridges integrated into core.
+* inherited_view_paths: ability to specify other folders to look for if missing view occurs
+
+== FIXES
+
+=== LIST
+* the calculation row now updates on edit/create/destroy.
+* list now returns to page 1 if the current page has no records.
+* list will now try to reload the scaffold on a previous page if you delete the last entry on the current page.
+* if there were no end-of-line record actions, then any column actions would not use ajax. this was because the loading indicator was missing, which messed up the action link javascript.
+* theme == :default no longer attempts to use Rico.Corner
+* column_empty? now treats any values equal to list.empty_field_text as empty, too.
+* better :method handling for action links.
+* the ' ' fix for ie6 was failing for value types that weren't nil and didn't respond to empty?
+* if someone sets singular columns to link to the 'nested' action, the link will now render with the appropriate id parameter.
+* do not propagate params[:search] through action links that link to other controllers. closes issue #447.
+* reworked rendering of pagination links for IE
+
+=== CREATE/UPDATE
+* constraints are now applied to a record during the #new action, in case any custom form rendering depends on the constrained column
+* the default options_for_association_conditions now returns nil for :through associations
+* will not update a record attribute if the value hasn't changed. this is a workaround for an activerecord bug with has_one associations.
+* attributes_hash_is_empty? didn't handle multi-parameter attribute names like 'created_at(5i)', which resulted in extra records being created from subforms.
+* Hide hidden column header labels  - like lock_version - in sub-forms.
+* configuring url_for to not escape ampersands for the add_new_url in association footers (the 'create another' button's url)
+* attribute_params.rb#attributes_hash_is_empty now checks defaults by converting them to strings to match the parameter values.
+
+=== NESTING
+* no longer trying to nest a polymorphic association (there's no consistent model to list)
+* fixed :conditions generation for nested/embedded scaffolds - was causing a bind variable mismatch.
+
+=== SEARCH
+* search/livesearch should no longer choke on virtual columns
+* the search/live_search forms will now ignore params[:search] when generating the submit url
+
+=== GENERAL
+* no longer blow up on data strings with unintentional % characters. as_() was sprintf'ing too frequently.
+* link_to no longer blows up on controller symbols
+* activescaffold no longer loses information on columns - `config.columns.add', `config.columns = [...]', and `config.columns.exclude' all now affect the *inheritability* of a column by the other modules (list, create, update, etc.), but all columns remain in config.columns. this also makes _id columns behave better.
+* dhtml history no longer saves null:null:null history bookmark.
+* if there aren't any columns to search on, then activescaffold no longer creates an empty WHERE clause
+* render :update was failing in some cases because activescaffold wasn't expecting blocks to the render call.
+* quoting the scaffold id for report_500_response()
+* adding :update_column => :post to the RESTful routing. closes issue #448.
+
+== MISC
+
+* reorganized the helpers and extensions
+* ui_type is now only an alias for form_ui
+* improvements to exception messages
+* when initializing in production mode, activescaffold now recovers gracefully if it can't copy asset files
+* RESTful routing is now accomplished in a way that'll let other add-ons extend the meaning of :active_scaffold => true.
+* fixes for edge rails compatibility
+* small improvements for localization accessibility
+* minor string renaming (will affect localization tables, though)
+* closed a few XSS holes
\ No newline at end of file

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/MIT-LICENSE
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/MIT-LICENSE?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/MIT-LICENSE (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/MIT-LICENSE Sun Aug 30 16:30:26 2009
@@ -0,0 +1,20 @@
+Copyright (c) 2006 Richard White
+
+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.

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/README
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/README?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/README (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/README Sun Aug 30 16:30:26 2009
@@ -0,0 +1,31 @@
+**********************************************************************************
+** For all documentation see the project website: http://www.ActiveScaffold.com **
+**********************************************************************************
+
+ActiveScaffold plugin by Scott Rutherford (scott@caronsoftware.com), Richard White (rrwhite@gmail.com), Lance Ivy (lance@cainlevy.net), Ed Moss, and Tim Harper
+
+Uses DhtmlHistory by Brad Neuberg (bkn3@columbia.edu)
+http://codinginparadise.org
+
+Uses Querystring by Adam Vandenberg
+http://adamv.com/dev/javascript/querystring
+
+Uses Paginator by Bruce Williams
+http://paginator.rubyforge.org/
+
+Supports RecordSelect by Lance Ivy
+http://code.google.com/p/recordselect/
+
+== Version Information
+
+Please note the following list of Active Scaffold branches and Rails versions. Master will not work with Rails < 2.2
+
+Rails master (edge): Active Scaffold master
+Rails 2.2.*: Active Scaffold rails-2.2
+Rails 2.1.*: Active Scaffold rails-2.1
+Rails < 2.1: Active Scaffold 1-1-stable (no guarantees)
+
+Since Rails 2.3, render_component plugin is needed for nested and embbeded scaffolds. It works with rails-2.3 branch from ewildgoose repository:
+script/plugin install git://github.com/ewildgoose/render_component.git -r rails-2.3
+
+Released under the MIT license (included)

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/README
------------------------------------------------------------------------------
    svn:eol-style = native

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/Rakefile
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/Rakefile?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/Rakefile (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/Rakefile Sun Aug 30 16:30:26 2009
@@ -0,0 +1,24 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/packagetask'
+require 'rake/rdoctask'
+require 'find'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test ActiveScaffold.'
+Rake::TestTask.new(:test) do |t|
+  t.libs << 'lib'
+  t.pattern = 'test/**/*_test.rb'
+  t.verbose = true
+end
+
+desc 'Generate documentation for ActiveScaffold.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+  rdoc.rdoc_dir = 'rdoc'
+  rdoc.title    = 'ActiveScaffold'
+  rdoc.options << '--line-numbers' << '--inline-source'
+  rdoc.rdoc_files.include('README')
+  rdoc.rdoc_files.include('lib/**/*.rb')
+end

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/environment.rb
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/environment.rb?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/environment.rb (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/environment.rb Sun Aug 30 16:30:26 2009
@@ -0,0 +1,17 @@
+require 'active_scaffold'
+
+# TODO: clean up extensions. some could be organized for autoloading, and others could be removed entirely.
+Dir["#{File.dirname __FILE__}/lib/extensions/*.rb"].each { |file| require file }
+
+ActionController::Base.send(:include, ActiveScaffold)
+ActionController::Base.send(:include, RespondsToParent)
+ActionController::Base.send(:include, ActiveScaffold::Helpers::ControllerHelpers)
+ActionView::Base.send(:include, ActiveScaffold::Helpers::ViewHelpers)
+
+ActionController::Base.class_eval {include ActiveRecordPermissions::ModelUserAccess::Controller}
+ActiveRecord::Base.class_eval     {include ActiveRecordPermissions::ModelUserAccess::Model}
+ActiveRecord::Base.class_eval     {include ActiveRecordPermissions::Permissions}
+
+require 'bridges/bridge.rb'
+
+I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'lib', 'active_scaffold', 'locale', '*.{rb,yml}')]

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/environment.rb
------------------------------------------------------------------------------
    svn:eol-style = native

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/add.gif
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/add.gif?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/add.gif
------------------------------------------------------------------------------
    svn:mime-type = image/gif

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/arrow_down.gif
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/arrow_down.gif?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/arrow_down.gif
------------------------------------------------------------------------------
    svn:mime-type = image/gif

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/arrow_up.gif
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/arrow_up.gif?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/arrow_up.gif
------------------------------------------------------------------------------
    svn:mime-type = image/gif

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/close.gif
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/close.gif?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/close.gif
------------------------------------------------------------------------------
    svn:mime-type = image/gif

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/cross.png
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/cross.png?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/cross.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/indicator-small.gif
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/indicator-small.gif?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/indicator-small.gif
------------------------------------------------------------------------------
    svn:mime-type = image/gif

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/indicator.gif
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/indicator.gif?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/indicator.gif
------------------------------------------------------------------------------
    svn:mime-type = image/gif

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/magnifier.png
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/magnifier.png?rev=809371&view=auto
==============================================================================
Binary file - no diff available.

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/images/magnifier.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/active_scaffold.js
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/active_scaffold.js?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/active_scaffold.js (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/active_scaffold.js Sun Aug 30 16:30:26 2009
@@ -0,0 +1,434 @@
+if (typeof Prototype == 'undefined')
+{
+  warning = "ActiveScaffold Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (e.g. <%= javascript_include_tag :defaults %>) *before* it includes active_scaffold.js (e.g. <%= active_scaffold_includes %>).";
+  alert(warning);
+}
+if (Prototype.Version.substring(0, 3) != '1.6')
+{
+  warning = "ActiveScaffold Error: Prototype version 1.6.x is required. Please update prototype.js (rake rails:update:javascripts).";
+  alert(warning);
+}
+
+/*
+ * Simple utility methods
+ */
+
+var ActiveScaffold = {
+  records_for: function(tbody_id) {
+    var rows = [];
+    var child = $(tbody_id).down('.record');
+    while (child) {
+      rows.push(child);
+      child = child.next('.record');
+    }
+    return rows;
+  },
+  stripe: function(tbody_id) {
+    var even = false;
+    var rows = this.records_for(tbody_id);
+    for (var i = 0; i < rows.length; i++) {
+      var child = rows[i];
+      //Make sure to skip rows that are create or edit rows or messages
+      if (child.tagName != 'SCRIPT'
+        && !child.hasClassName("create")
+        && !child.hasClassName("update")
+        && !child.hasClassName("inline-adapter")
+        && !child.hasClassName("active-scaffold-calculations")) {
+
+        if (even) child.addClassName("even-record");
+        else child.removeClassName("even-record");
+
+        even = !even;
+      }
+    }
+  },
+  hide_empty_message: function(tbody, empty_message_id) {
+    if (this.records_for(tbody).length != 0) {
+      $(empty_message_id).hide();
+    }
+  },
+  reload_if_empty: function(tbody, url) {
+    var content_container_id = tbody.replace('tbody', 'content');
+    if (this.records_for(tbody).length == 0) {
+      new Ajax.Updater($(content_container_id), url, {
+        method: 'get',
+        asynchronous: true,
+        evalScripts: true
+      });
+    }
+  },
+  removeSortClasses: function(scaffold_id) {
+    $$('#' + scaffold_id + ' td.sorted').each(function(element) {
+      element.removeClassName("sorted");
+    });
+    $$('#' + scaffold_id + ' th.sorted').each(function(element) {
+      element.removeClassName("sorted");
+      element.removeClassName("asc");
+      element.removeClassName("desc");
+    });
+  },
+  decrement_record_count: function(scaffold_id) {
+    // decrement the last record count, firsts record count are in nested lists
+    count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
+    count.innerHTML = parseInt(count.innerHTML) - 1;
+  },
+  increment_record_count: function(scaffold_id) {
+    // increment the last record count, firsts record count are in nested lists
+    count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
+    count.innerHTML = parseInt(count.innerHTML) + 1;
+  },
+
+  server_error_response: '',
+  report_500_response: function(active_scaffold_id) {
+    messages_container = $(active_scaffold_id).down('td.messages-container');
+    new Insertion.Top(messages_container, this.server_error_response);
+  }
+}
+
+/*
+ * DHTML history tie-in
+ */
+function addActiveScaffoldPageToHistory(url, active_scaffold_id) {
+  if (typeof dhtmlHistory == 'undefined') return; // it may not be loaded
+
+  var array = url.split('?');
+  var qs = new Querystring(array[1]);
+  var sort = qs.get('sort')
+  var dir = qs.get('sort_direction')
+  var page = qs.get('page')
+  if (sort || dir || page) dhtmlHistory.add(active_scaffold_id+":"+page+":"+sort+":"+dir, url);
+}
+
+/*
+ * Add-ons/Patches to Prototype
+ */
+
+/* patch to support replacing TR/TD/TBODY in Internet Explorer, courtesy of http://dev.rubyonrails.org/ticket/4273 */
+Element.replace = function(element, html) {
+  element = $(element);
+  if (element.outerHTML) {
+    try {
+    element.outerHTML = html.stripScripts();
+    } catch (e) {
+      var tn = element.tagName;
+      if(tn=='TBODY' || tn=='TR' || tn=='TD')
+      {
+              var tempDiv = document.createElement("div");
+              tempDiv.innerHTML = '<table id="tempTable" style="display: none">' + html.stripScripts() + '</table>';
+              element.parentNode.replaceChild(tempDiv.getElementsByTagName(tn).item(0), element);
+      }
+      else throw e;
+    }
+  } else {
+    var range = element.ownerDocument.createRange();
+    /* patch to fix <form> replaces in Firefox. see http://dev.rubyonrails.org/ticket/8010 */
+    range.selectNodeContents(element.parentNode);
+    element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
+  }
+  setTimeout(function() {html.evalScripts()}, 10);
+  return element;
+};
+
+/*
+ * URL modification support. Incomplete functionality.
+ */
+Object.extend(String.prototype, {
+  append_params: function(params) {
+    url = this;
+    if (url.indexOf('?') == -1) url += '?';
+    else if (url.lastIndexOf('&') != url.length) url += '&';
+
+    url += $H(params).collect(function(item) {
+      return item.key + '=' + item.value;
+    }).join('&');
+
+    return url;
+  }
+});
+
+/*
+ * Prototype's implementation was throwing an error instead of false
+ */
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = (t.names && t.names[attribute]) || attribute;
+    // Return false if we get an error here
+    try {
+      return $(element).getAttributeNode(attribute).specified;
+    } catch (e) {
+      return false;
+    }
+  }
+};
+
+/**
+ * A set of links. As a set, they can be controlled such that only one is "open" at a time, etc.
+ */
+ActiveScaffold.Actions = new Object();
+ActiveScaffold.Actions.Abstract = function(){}
+ActiveScaffold.Actions.Abstract.prototype = {
+  initialize: function(links, target, loading_indicator, options) {
+    this.target = $(target);
+    this.loading_indicator = $(loading_indicator);
+    this.options = options;
+    this.links = links.collect(function(link) {
+      return this.instantiate_link(link);
+    }.bind(this));
+  },
+
+  instantiate_link: function(link) {
+    throw 'unimplemented'
+  }
+}
+
+/**
+ * A DataStructures::ActionLink, represented in JavaScript.
+ * Concerned with AJAX-enabling a link and adapting the result for insertion into the table.
+ */
+ActiveScaffold.ActionLink = new Object();
+ActiveScaffold.ActionLink.Abstract = function(){}
+ActiveScaffold.ActionLink.Abstract.prototype = {
+  initialize: function(a, target, loading_indicator) {
+    this.tag = $(a);
+    this.url = this.tag.href;
+    this.method = 'get';
+    if(this.url.match('_method=delete')){
+      this.method = 'delete';
+    } else if(this.url.match('_method=post')){
+      this.method = 'post';
+    }
+    this.target = target;
+    this.loading_indicator = loading_indicator;
+    this.hide_target = false;
+    this.position = this.tag.getAttribute('position');
+		this.page_link = this.tag.getAttribute('page_link');
+
+    this.onclick = this.tag.onclick;
+    this.tag.onclick = null;
+    this.tag.observe('click', function(event) {
+      this.open();
+      Event.stop(event);
+    }.bind(this));
+
+    this.tag.action_link = this;
+  },
+
+  open: function() {
+    if (this.is_disabled()) return;
+
+    if (this.tag.hasAttribute( "dhtml_confirm")) {
+      if (this.onclick) this.onclick();
+      return;
+    } else {
+      if (this.onclick && !this.onclick()) return;//e.g. confirmation messages
+      this.open_action();
+    }
+  },
+
+	open_action: function() {
+		if (this.position) this.disable();
+
+		if (this.page_link) {
+			window.location = this.url;
+		} else {
+			if (this.loading_indicator) this.loading_indicator.style.visibility = 'visible';
+	    new Ajax.Request(this.url, {
+	      asynchronous: true,
+	      evalScripts: true,
+              method: this.method,
+	      onSuccess: function(request) {
+	        if (this.position) {
+	          this.insert(request.responseText);
+	          if (this.hide_target) this.target.hide();
+	        } else {
+	          request.evalResponse();
+	        }
+	      }.bind(this),
+
+	      onFailure: function(request) {
+	        ActiveScaffold.report_500_response(this.scaffold_id());
+	        if (this.position) this.enable()
+	      }.bind(this),
+
+	      onComplete: function(request) {
+	        if (this.loading_indicator) this.loading_indicator.style.visibility = 'hidden';
+	      }.bind(this)
+			});
+		}
+	},
+
+  insert: function(content) {
+    throw 'unimplemented'
+  },
+
+  close: function() {
+    this.enable();
+    this.adapter.remove();
+    if (this.hide_target) this.target.show();
+  },
+
+  register_cancel_hooks: function() {
+    // anything in the insert with a class of cancel gets the closer method, and a reference to this object for good measure
+    var self = this;
+    this.adapter.select('.cancel').each(function(elem) {
+      elem.observe('click', this.close_handler.bind(this));
+      elem.link = self;
+    }.bind(this))
+  },
+
+  reload: function() {
+    this.close();
+    this.open();
+  },
+
+  get_new_adapter_id: function() {
+    var id = 'adapter_';
+    var i = 0;
+    while ($(id + i)) i++;
+    return id + i;
+  },
+
+  enable: function() {
+    return this.tag.removeClassName('disabled');
+  },
+
+  disable: function() {
+    return this.tag.addClassName('disabled');
+  },
+
+  is_disabled: function() {
+    return this.tag.hasClassName('disabled');
+  },
+
+  scaffold_id: function() {
+    return this.tag.up('div.active-scaffold').id;
+  }
+}
+
+/**
+ * Concrete classes for record actions
+ */
+ActiveScaffold.Actions.Record = Class.create();
+ActiveScaffold.Actions.Record.prototype = Object.extend(new ActiveScaffold.Actions.Abstract(), {
+  instantiate_link: function(link) {
+    var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);
+    l.refresh_url = this.options.refresh_url;
+    if (link.hasClassName('delete')) {
+      l.url = l.url.replace(/\/delete(\?.*)?$/, '$1');
+      l.url = l.url.replace(/\/delete\/(.*)/, '/destroy/$1');
+    }
+    if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
+    l.set = this;
+    return l;
+  }
+});
+
+ActiveScaffold.ActionLink.Record = Class.create();
+ActiveScaffold.ActionLink.Record.prototype = Object.extend(new ActiveScaffold.ActionLink.Abstract(), {
+  close_previous_adapter: function() {
+    this.set.links.each(function(item) {
+      if (item.url != this.url && item.is_disabled() && item.adapter) item.close();
+    }.bind(this));
+  },
+
+  insert: function(content) {
+    this.close_previous_adapter();
+
+    if (this.position == 'replace') {
+      this.position = 'after';
+      this.hide_target = true;
+    }
+
+    if (this.position == 'after') {
+      new Insertion.After(this.target, content);
+      this.adapter = this.target.next();
+    }
+    else if (this.position == 'before') {
+      new Insertion.Before(this.target, content);
+      this.adapter = this.target.previous();
+    }
+    else {
+      return false;
+    }
+
+    this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
+    this.register_cancel_hooks();
+
+    new Effect.Highlight(this.adapter.down('td'));
+  },
+
+  close_handler: function(event) {
+    this.close_with_refresh();
+    if (event) Event.stop(event);
+  },
+
+  /* it might simplify things to just override the close function. then the Record and Table links could share more code ... wouldn't need custom close_handler functions, for instance */
+  close_with_refresh: function() {
+    new Ajax.Request(this.refresh_url, {
+      asynchronous: true,
+      evalScripts: true,
+      method: this.method,
+      onSuccess: function(request) {
+        Element.replace(this.target, request.responseText);
+        var new_target = $(this.target.id);
+        if (this.target.hasClassName('even-record')) new_target.addClassName('even-record');
+        this.target = new_target;
+        this.close();
+      }.bind(this),
+
+      onFailure: function(request) {
+        ActiveScaffold.report_500_response(this.scaffold_id());
+      }
+    });
+  },
+
+  enable: function() {
+    this.set.links.each(function(item) {
+      if (item.url != this.url) return;
+      item.tag.removeClassName('disabled');
+    }.bind(this));
+  },
+
+  disable: function() {
+    this.set.links.each(function(item) {
+      if (item.url != this.url) return;
+      item.tag.addClassName('disabled');
+    }.bind(this));
+  }
+});
+
+/**
+ * Concrete classes for table actions
+ */
+ActiveScaffold.Actions.Table = Class.create();
+ActiveScaffold.Actions.Table.prototype = Object.extend(new ActiveScaffold.Actions.Abstract(), {
+  instantiate_link: function(link) {
+    var l = new ActiveScaffold.ActionLink.Table(link, this.target, this.loading_indicator);
+    if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
+    return l;
+  }
+});
+
+ActiveScaffold.ActionLink.Table = Class.create();
+ActiveScaffold.ActionLink.Table.prototype = Object.extend(new ActiveScaffold.ActionLink.Abstract(), {
+  insert: function(content) {
+    if (this.position == 'top') {
+      new Insertion.Top(this.target, content);
+      this.adapter = this.target.immediateDescendants().first();
+    }
+    else {
+      throw 'Unknown position "' + this.position + '"'
+    }
+
+    this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
+    this.register_cancel_hooks();
+
+    new Effect.Highlight(this.adapter.down('td'));
+  },
+
+  close_handler: function(event) {
+    this.close();
+    if (event) Event.stop(event);
+  }
+});

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/active_scaffold.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js Sun Aug 30 16:30:26 2009
@@ -0,0 +1,867 @@
+/*
+Copyright (c) 2007 Brian Dillard and Brad Neuberg:
+Brian Dillard | Project Lead | bdillard@pathf.com | http://blogs.pathf.com/agileajax/
+Brad Neuberg | Original Project Creator | http://codinginparadise.org
+
+SVN r113 from http://code.google.com/p/reallysimplehistory
++ Changes by Ed Wildgoose - MailASail
++ Changed EncodeURIComponent -> EncodeURI
++ Changed DecodeURIComponent -> DecodeURI
++ Changed 'blank.html?' -> '/blank.html?'
+ 
+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.
+*/
+
+/*
+       dhtmlHistory: An object that provides history, history data, and bookmarking for DHTML and Ajax applications.
+       
+       dependencies:
+               * the historyStorage object included in this file.
+
+*/
+window.dhtmlHistory = {
+       
+       /*Public: User-agent booleans*/
+       isIE: false,
+       isOpera: false,
+       isSafari: false,
+       isKonquerer: false,
+       isGecko: false,
+       isSupported: false,
+       
+       /*Public: Create the DHTML history infrastructure*/
+       create: function(options) {
+               
+               /*
+                       options - object to store initialization parameters
+                       options.blankURL - string to override the default location of blank.html. Must end in "?"
+                       options.debugMode - boolean that causes hidden form fields to be shown for development purposes.
+                       options.toJSON - function to override default JSON stringifier
+                       options.fromJSON - function to override default JSON parser
+                       options.baseTitle - pattern for title changes; example: "Armchair DJ [@@@]" - @@@ will be replaced
+               */
+
+               var that = this;
+               
+               /*Set up the historyStorage object; pass in options bundle*/
+               window.historyStorage.setup(options);
+               
+               /*Set up our base title if one is passed in*/
+               if (options && options.baseTitle) {
+                       if (options.baseTitle.indexOf("@@@") < 0 && historyStorage.debugMode) {
+                               throw new Error("Programmer error: options.baseTitle must contain the replacement parameter"
+                               + " '@@@' to be useful.");
+                       }
+                       this.baseTitle = options.baseTitle;
+               }
+               
+               /*set user-agent flags*/
+               var UA = navigator.userAgent.toLowerCase();
+               var platform = navigator.platform.toLowerCase();
+               var vendor = navigator.vendor || "";
+               if (vendor === "KDE") {
+                       this.isKonqueror = true;
+                       this.isSupported = false;
+               } else if (typeof window.opera !== "undefined") {
+                       this.isOpera = true;
+                       this.isSupported = true;
+               } else if (typeof document.all !== "undefined") {
+                       this.isIE = true;
+                       this.isSupported = true;
+               } else if (vendor.indexOf("Apple Computer, Inc.") > -1) {
+                       this.isSafari = true;
+                       this.isSupported = (platform.indexOf("mac") > -1);
+               } else if (UA.indexOf("gecko") != -1) {
+                       this.isGecko = true;
+                       this.isSupported = true;
+               }
+
+               /*Create Safari/Opera-specific code*/
+               if (this.isSafari) {
+                       this.createSafari();
+               } else if (this.isOpera) {
+                       this.createOpera();
+               }
+               
+               /*Get our initial location*/
+               var initialHash = this.getCurrentLocation();
+
+               /*Save it as our current location*/
+               this.currentLocation = initialHash;
+
+               /*Now that we have a hash, create IE-specific code*/
+               if (this.isIE) {
+                       /*Optionally override the URL of IE's blank HTML file*/
+                       if (options && options.blankURL) {
+                               var u = options.blankURL;
+                               /*assign the value, adding the trailing ? if it's not passed in*/
+                               this.blankURL = (u.indexOf("?") != u.length - 1
+                                       ? u + "?"
+                                       : u
+                               );
+                       }
+                       this.createIE(initialHash);
+               }
+
+               /*Add an unload listener for the page; this is needed for FF 1.5+ because this browser caches all dynamic updates to the
+               page, which can break some of our logic related to testing whether this is the first instance a page has loaded or whether
+               it is being pulled from the cache*/
+
+               var unloadHandler = function() {
+                       that.firstLoad = null;
+               };
+               
+               this.addEventListener(window,'unload',unloadHandler);          
+
+               /*Determine if this is our first page load; for IE, we do this in this.iframeLoaded(), which is fired on pageload. We do it
+               there because we have no historyStorage at this point, which only exists after the page is finished loading in IE*/
+               if (this.isIE) {
+                       /*The iframe will get loaded on page load, and we want to ignore this fact*/
+                       this.ignoreLocationChange = true;
+               } else {
+                       if (!historyStorage.hasKey(this.PAGELOADEDSTRING)) {
+                               /*This is our first page load, so ignore the location change and add our special history entry*/
+                               this.ignoreLocationChange = true;
+                               this.firstLoad = true;
+                               historyStorage.put(this.PAGELOADEDSTRING, true);
+                       } else {
+                               /*This isn't our first page load, so indicate that we want to pay attention to this location change*/
+                               this.ignoreLocationChange = false;
+                               this.firstLoad = false;
+                               /*For browsers other than IE, fire a history change event; on IE, the event will be thrown automatically when its
+                               hidden iframe reloads on page load. Unfortunately, we don't have any listeners yet; indicate that we want to fire
+                               an event when a listener is added.*/
+                               this.fireOnNewListener = true;
+                       }
+               }
+
+               /*Other browsers can use a location handler that checks at regular intervals as their primary mechanism; we use it for IE as
+               well to handle an important edge case; see checkLocation() for details*/
+               var locationHandler = function() {
+                       that.checkLocation();
+               };
+               setInterval(locationHandler, 100);
+       },      
+       
+       /*Public: Initialize our DHTML history. You must call this after the page is finished loading. Optionally, you can pass your listener in
+       here so you don't need to make a separate call to addListener*/
+       initialize: function(listener) {
+
+               /*save original document title to plug in when we hit a null-key history point*/
+               this.originalTitle = document.title;
+               
+               /*IE needs to be explicitly initialized. IE doesn't autofill form data until the page is finished loading, so we have to wait*/
+               if (this.isIE) {
+                       /*If this is the first time this page has loaded*/
+                       if (!historyStorage.hasKey(this.PAGELOADEDSTRING)) {
+                               /*For IE, we do this in initialize(); for other browsers, we do it in create()*/
+                               this.fireOnNewListener = false;
+                               this.firstLoad = true;
+                               historyStorage.put(this.PAGELOADEDSTRING, true);
+                       }
+                       /*Else if this is a fake onload event*/
+                       else {
+                               this.fireOnNewListener = true;
+                               this.firstLoad = false;  
+                       }
+               }
+               /*optional convenience to save a separate call to addListener*/
+               if (listener) {
+                       this.addListener(listener);
+               }
+       },
+
+       /*Public: Adds a history change listener. Only one listener is supported at this time.*/
+       addListener: function(listener) {
+               this.listener = listener;
+               /*If the page was just loaded and we should not ignore it, fire an event to our new listener now*/
+               if (this.fireOnNewListener) {
+                       this.fireHistoryEvent(this.currentLocation);
+                       this.fireOnNewListener = false;
+               }
+       },
+       
+       /*Public: Change the current HTML title*/
+       changeTitle: function(historyData) {
+               var winTitle = (historyData && historyData.newTitle
+                       /*Plug the new title into the pattern*/
+                       ? this.baseTitle.replace('@@@', historyData.newTitle)
+                       /*Otherwise, if there is no new title, use the original document title. This is useful when some
+                       history changes have title changes and some don't; we can automatically return to the original
+                       title rather than leaving a misleading title in the title bar. The same goes for our "virgin"
+                       (hashless) page state.*/
+                       : this.originalTitle
+               );
+               /*No need to do anything if the title isn't changing*/
+               if (document.title == winTitle) {
+                       return;
+               }
+
+
+               /*Now change the DOM*/
+               document.title = winTitle;
+               /*Change it in the iframe, too, for IE*/
+               if (this.isIE) {
+                       this.iframe.contentWindow.document.title = winTitle;
+               }
+               
+               /*If non-IE, reload the hash so the new title "sticks" in the browser history object*/
+               if (!this.isIE && !this.isOpera) {
+                       var hash = decodeURI(document.location.hash);
+                       if (hash != "") {
+                               var encodedHash = encodeURI(this.removeHash(hash));
+                               document.location.hash = encodedHash;
+                       } else {
+                               //document.location.hash = "#";
+                       }
+               }
+       },
+       
+       /*Public: Add a history point. Parameters available:
+       * newLocation (required):
+               This will be the #hash value in the URL. Users can bookmark it. It will persist across sessions, so
+               your application should be able to restore itself to a specific state based on just this value. It
+               should be either a simple keyword for a viewstate or else a pseudo-querystring.
+       * historyData (optional):
+               This is for complex data that is relevant only to the current browsing session. It will be available
+               to your application until the browser is closed. If the user comes back to a bookmarked history point
+               during a later session, this data will no longer be available. Don't rely on it for application
+               re-initialization from a bookmark.
+       * historyData.newTitle (optional):
+               This will swap out the html <title> attribute with a new value. If you have set a baseTitle using the
+               options bundle, the value will be plugged into the baseTitle by swapping out the @@@ replacement param.
+       */
+       add: function(newLocation, historyData) {
+               
+               var that = this;
+               
+               /*Escape the location and remove any leading hash symbols*/
+               var encodedLocation = encodeURI(this.removeHash(newLocation));
+               
+               if (this.isSafari) {
+
+                       /*Store the history data into history storage - pass in unencoded newLocation since
+                       historyStorage does its own encoding*/
+                       historyStorage.put(newLocation, historyData);
+
+                       /*Save this as our current location*/
+                       this.currentLocation = encodedLocation;
+       
+                       /*Change the browser location*/
+                       window.location.hash = encodedLocation;
+               
+                       /*Save this to the Safari form field*/
+                       this.putSafariState(encodedLocation);
+
+                       this.changeTitle(historyData);
+
+               } else {
+                       
+                       /*Most browsers require that we wait a certain amount of time before changing the location, such
+                       as 200 MS; rather than forcing external callers to use window.setTimeout to account for this,
+                       we internally handle it by putting requests in a queue.*/
+                       var addImpl = function() {
+                               
+                               /*Indicate that the current wait time is now less*/
+                               if (that.currentWaitTime > 0) {
+                                       that.currentWaitTime = that.currentWaitTime - that.waitTime;
+                               }
+
+                               /*IE has a strange bug; if the encodedLocation is the same as _any_ preexisting id in the
+                               document, then the history action gets recorded twice; throw a programmer exception if
+                               there is an element with this ID*/
+                               if (document.getElementById(encodedLocation) && that.debugMode) {
+                                       var e = "Exception: History locations can not have the same value as _any_ IDs that might be in the document,"
+                                       + " due to a bug in IE; please ask the developer to choose a history location that does not match any HTML"
+                                       + " IDs in this document. The following ID is already taken and cannot be a location: " + newLocation;
+                                       throw new Error(e);
+                               }
+
+                               /*Store the history data into history storage - pass in unencoded newLocation since
+                               historyStorage does its own encoding*/
+                               historyStorage.put(newLocation, historyData);
+
+                               /*Indicate to the browser to ignore this upcomming location change since we're making it programmatically*/
+                               that.ignoreLocationChange = true;
+
+                               /*Indicate to IE that this is an atomic location change block*/
+                               that.ieAtomicLocationChange = true;
+
+                               /*Save this as our current location*/
+                               that.currentLocation = encodedLocation;
+                               
+                               /*Change the browser location*/
+                               window.location.hash = encodedLocation;
+
+                               /*Change the hidden iframe's location if on IE*/
+                               if (that.isIE) {
+                                       that.iframe.src = that.blankURL + encodedLocation;
+                               }
+
+                               /*End of atomic location change block for IE*/
+                               that.ieAtomicLocationChange = false;
+                               
+                               that.changeTitle(historyData);
+                               
+                       };
+
+                       /*Now queue up this add request*/
+                       window.setTimeout(addImpl, this.currentWaitTime);
+
+                       /*Indicate that the next request will have to wait for awhile*/
+                       this.currentWaitTime = this.currentWaitTime + this.waitTime;
+               }
+       },
+
+       /*Public*/
+       isFirstLoad: function() {
+               return this.firstLoad;
+       },
+
+       /*Public*/
+       getVersion: function() {
+               return this.VERSIONNUMBER;
+       },
+       
+       /*- - - - - - - - - - - -*/
+       
+       /*Private: Constant for our own internal history event called when the page is loaded*/
+       PAGELOADEDSTRING: "DhtmlHistory_pageLoaded",
+       
+       VERSIONNUMBER: "0.8",
+       
+       /*
+               Private: Pattern for title changes. Example: "Armchair DJ [@@@]" where @@@ will be relaced by values passed to add();
+               Default is just the title itself, hence "@@@"
+       */
+       baseTitle: "@@@",
+       
+       /*Private: Placeholder variable for the original document title; will be set in ititialize()*/
+       originalTitle: null,
+       
+       /*Private: URL for the blank html file we use for IE; can be overridden via the options bundle. Otherwise it must be served
+       in same directory as this library*/
+       blankURL: "/blank.html?",
+       
+       /*Private: Our history change listener.*/
+       listener: null,
+
+       /*Private: MS to wait between add requests - will be reset for certain browsers*/
+       waitTime: 200,
+       
+       /*Private: MS before an add request can execute*/
+       currentWaitTime: 0,
+
+       /*Private: Our current hash location, without the "#" symbol.*/
+       currentLocation: null,
+
+       /*Private: Hidden iframe used to IE to detect history changes*/
+       iframe: null,
+
+       /*Private: Flags and DOM references used only by Safari*/
+       safariHistoryStartPoint: null,
+       safariStack: null,
+       safariLength: null,
+
+       /*Private: Flag used to keep checkLocation() from doing anything when it discovers location changes we've made ourselves
+       programmatically with the add() method. Basically, add() sets this to true. When checkLocation() discovers it's true,
+       it refrains from firing our listener, then resets the flag to false for next cycle. That way, our listener only gets fired on
+       history change events triggered by the user via back/forward buttons and manual hash changes. This flag also helps us set up
+       IE's special iframe-based method of handling history changes.*/
+       ignoreLocationChange: null,
+
+       /*Private: A flag that indicates that we should fire a history change event when we are ready, i.e. after we are initialized and
+       we have a history change listener. This is needed due to an edge case in browsers other than IE; if you leave a page entirely
+       then return, we must fire this as a history change event. Unfortunately, we have lost all references to listeners from earlier,
+       because JavaScript clears out.*/
+       fireOnNewListener: null,
+
+       /*Private: A variable that indicates whether this is the first time this page has been loaded. If you go to a web page, leave it
+       for another one, and then return, the page's onload listener fires again. We need a way to differentiate between the first page
+       load and subsequent ones. This variable works hand in hand with the pageLoaded variable we store into historyStorage.*/
+       firstLoad: null,
+
+       /*Private: A variable to handle an important edge case in IE. In IE, if a user manually types an address into their browser's
+       location bar, we must intercept this by calling checkLocation() at regular intervals. However, if we are programmatically
+       changing the location bar ourselves using the add() method, we need to ignore these changes in checkLocation(). Unfortunately,
+       these changes take several lines of code to complete, so for the duration of those lines of code, we set this variable to true.
+       That signals to checkLocation() to ignore the change-in-progress. Once we're done with our chunk of location-change code in
+       add(), we set this back to false. We'll do the same thing when capturing user-entered address changes in checkLocation itself.*/
+       ieAtomicLocationChange: null,
+       
+       /*Private: Generic utility function for attaching events*/
+       addEventListener: function(o,e,l) {
+               if (o.addEventListener) {
+                       o.addEventListener(e,l,false);
+               } else if (o.attachEvent) {
+                       o.attachEvent('on'+e,function() {
+                               l(window.event);
+                       });
+               }
+       },
+
+
+       /*Private: Create IE-specific DOM nodes and overrides*/
+       createIE: function(initialHash) {
+               /*write out a hidden iframe for IE and set the amount of time to wait between add() requests*/
+               this.waitTime = 400;/*IE needs longer between history updates*/
+               var styles = (historyStorage.debugMode
+                       ? 'width: 800px;height:80px;border:1px solid black;'
+                       : historyStorage.hideStyles
+               );
+               var iframeID = "rshHistoryFrame";
+               var iframeHTML = '<iframe frameborder="0" id="' + iframeID + '" style="' + styles + '" src="' + this.blankURL + initialHash + '"></iframe>';
+               document.write(iframeHTML);
+               this.iframe = document.getElementById(iframeID);
+       },
+       
+       /*Private: Create Opera-specific DOM nodes and overrides*/
+       createOpera: function() {
+               this.waitTime = 400;/*Opera needs longer between history updates*/
+               var imgHTML = '<img src="javascript:location.href=\'javascript:dhtmlHistory.checkLocation();\';" style="' + historyStorage.hideStyles + '" />';
+               document.write(imgHTML);
+       },
+       
+       /*Private: Create Safari-specific DOM nodes and overrides*/
+       createSafari: function() {
+               var formID = "rshSafariForm";
+               var stackID = "rshSafariStack";
+               var lengthID = "rshSafariLength";
+               var formStyles = historyStorage.debugMode ? historyStorage.showStyles : historyStorage.hideStyles;
+               var stackStyles = (historyStorage.debugMode
+                       ? 'width: 800px;height:80px;border:1px solid black;'
+                       : historyStorage.hideStyles
+               );
+               var lengthStyles = (historyStorage.debugMode
+                       ? 'width:800px;height:20px;border:1px solid black;margin:0;padding:0;'
+                       : historyStorage.hideStyles
+               );
+               var safariHTML = '<form id="' + formID + '" style="' + formStyles + '">'
+                       + '<textarea style="' + stackStyles + '" id="' + stackID + '">[]</textarea>'
+                       + '<input type="text" style="' + lengthStyles + '" id="' + lengthID + '" value=""/>'
+               + '</form>';
+               document.write(safariHTML);
+               this.safariStack = document.getElementById(stackID);
+               this.safariLength = document.getElementById(lengthID);
+               if (!historyStorage.hasKey(this.PAGELOADEDSTRING)) {
+                       this.safariHistoryStartPoint = history.length;
+                       this.safariLength.value = this.safariHistoryStartPoint;
+               } else {
+                       this.safariHistoryStartPoint = this.safariLength.value;
+               }
+       },
+       
+       /*TODO: make this public again?*/
+       /*Private: Get browser's current hash location; for Safari, read value from a hidden form field*/
+       getCurrentLocation: function() {
+               var r = (this.isSafari
+                       ? this.getSafariState()
+                       : this.getCurrentHash()
+               );
+               return r;
+       },
+       
+       /*TODO: make this public again?*/
+       /*Private: Manually parse the current url for a hash; tip of the hat to YUI*/
+   getCurrentHash: function() {
+               var r = window.location.href;
+               var i = r.indexOf("#");
+               return (i >= 0
+                       ? r.substr(i+1)
+                       : ""
+               );
+   },
+       
+       /*Private: Safari method to read the history stack from a hidden form field*/
+       getSafariStack: function() {
+               var r = this.safariStack.value;
+               return historyStorage.fromJSON(r);
+       },
+       /*Private: Safari method to read from the history stack*/
+       getSafariState: function() {
+               var stack = this.getSafariStack();
+               var state = stack[history.length - this.safariHistoryStartPoint - 1];
+               return state;
+       },                      
+       /*Private: Safari method to write the history stack to a hidden form field*/
+       putSafariState: function(newLocation) {
+           var stack = this.getSafariStack();
+           stack[history.length - this.safariHistoryStartPoint] = newLocation;
+           this.safariStack.value = historyStorage.toJSON(stack);
+       },
+
+       /*Private: Notify the listener of new history changes.*/
+       fireHistoryEvent: function(newHash) {
+               var decodedHash = decodeURI(newHash)
+               /*extract the value from our history storage for this hash*/
+               var historyData = historyStorage.get(decodedHash);
+               this.changeTitle(historyData);
+               /*call our listener*/
+               this.listener.call(null, decodedHash, historyData);
+       },
+       
+       /*Private: See if the browser has changed location. This is the primary history mechanism for Firefox. For IE, we use this to
+       handle an important edge case: if a user manually types in a new hash value into their IE location bar and press enter, we want to
+       to intercept this and notify any history listener.*/
+       checkLocation: function() {
+               
+               /*Ignore any location changes that we made ourselves for browsers other than IE*/
+               if (!this.isIE && this.ignoreLocationChange) {
+                       this.ignoreLocationChange = false;
+                       return;
+               }
+
+               /*If we are dealing with IE and we are in the middle of making a location change from an iframe, ignore it*/
+               if (!this.isIE && this.ieAtomicLocationChange) {
+                       return;
+               }
+               
+               /*Get hash location*/
+               var hash = this.getCurrentLocation();
+               
+               /*Do nothing if there's been no change*/
+               if (hash == this.currentLocation) {
+                       return;
+               }
+               
+               /*In IE, users manually entering locations into the browser; we do this by comparing the browser's location against the
+               iframe's location; if they differ, we are dealing with a manual event and need to place it inside our history, otherwise
+               we can return*/
+               this.ieAtomicLocationChange = true;
+
+               if (this.isIE && this.getIframeHash() != hash) {
+                       this.iframe.src = this.blankURL + hash;
+               }
+               else if (this.isIE) {
+                       /*the iframe is unchanged*/
+                       return;
+               }
+
+               /*Save this new location*/
+               this.currentLocation = hash;
+
+               this.ieAtomicLocationChange = false;
+
+               /*Notify listeners of the change*/
+               this.fireHistoryEvent(hash);
+       },
+
+       /*Private: Get the current location of IE's hidden iframe.*/
+       getIframeHash: function() {
+               var doc = this.iframe.contentWindow.document;
+               var hash = String(doc.location.search);
+               if (hash.length == 1 && hash.charAt(0) == "?") {
+                       hash = "";
+               }
+               else if (hash.length >= 2 && hash.charAt(0) == "?") {
+                       hash = hash.substring(1);
+               }
+               return hash;
+       },
+
+       /*Private: Remove any leading hash that might be on a location.*/
+       removeHash: function(hashValue) {
+               var r;
+               if (hashValue === null || hashValue === undefined) {
+                       r = null;
+               }
+               else if (hashValue === "") {
+                       r = "";
+               }
+               else if (hashValue.length == 1 && hashValue.charAt(0) == "#") {
+                       r = "";
+               }
+               else if (hashValue.length > 1 && hashValue.charAt(0) == "#") {
+                       r = hashValue.substring(1);
+               }
+               else {
+                       r = hashValue;
+               }
+               return r;
+       },
+
+       /*Private: For IE, tell when the hidden iframe has finished loading.*/
+       iframeLoaded: function(newLocation) {
+               /*ignore any location changes that we made ourselves*/
+               if (this.ignoreLocationChange) {
+                       this.ignoreLocationChange = false;
+                       return;
+               }
+
+               /*Get the new location*/
+               var hash = String(newLocation.search);
+               if (hash.length == 1 && hash.charAt(0) == "?") {
+                       hash = "";
+               }
+               else if (hash.length >= 2 && hash.charAt(0) == "?") {
+                       hash = hash.substring(1);
+               }
+               /*Keep the browser location bar in sync with the iframe hash*/
+               window.location.hash = hash;
+
+               /*Notify listeners of the change*/
+               this.fireHistoryEvent(hash);
+       }
+
+
+};
+
+/*
+       historyStorage: An object that uses a hidden form to store history state across page loads. The mechanism for doing so relies on
+       the fact that browsers save the text in form data for the life of the browser session, which means the text is still there when
+       the user navigates back to the page. This object can be used independently of the dhtmlHistory object for caching of Ajax
+       session information.
+       
+       dependencies:
+               * json2007.js (included in a separate file) or alternate JSON methods passed in through an options bundle.
+*/
+window.historyStorage = {
+       
+       /*Public: Set up our historyStorage object for use by dhtmlHistory or other objects*/
+       setup: function(options) {
+               
+               /*
+                       options - object to store initialization parameters - passed in from dhtmlHistory or directly into historyStorage
+                       options.debugMode - boolean that causes hidden form fields to be shown for development purposes.
+                       options.toJSON - function to override default JSON stringifier
+                       options.fromJSON - function to override default JSON parser
+               */
+               
+               /*process init parameters*/
+               if (typeof options !== "undefined") {
+                       if (options.debugMode) {
+                               this.debugMode = options.debugMode;
+                       }
+                       if (options.toJSON) {
+                               this.toJSON = options.toJSON;
+                       }
+                       if (options.fromJSON) {
+                               this.fromJSON = options.fromJSON;
+                       }
+               }              
+               
+               /*write a hidden form and textarea into the page; we'll stow our history stack here*/
+               var formID = "rshStorageForm";
+               var textareaID = "rshStorageField";
+               var formStyles = this.debugMode ? historyStorage.showStyles : historyStorage.hideStyles;
+               var textareaStyles = (historyStorage.debugMode
+                       ? 'width: 800px;height:80px;border:1px solid black;'
+                       : historyStorage.hideStyles
+               );
+               var textareaHTML = '<form id="' + formID + '" style="' + formStyles + '">'
+                       + '<textarea id="' + textareaID + '" style="' + textareaStyles + '"></textarea>'
+               + '</form>';
+               document.write(textareaHTML);
+               this.storageField = document.getElementById(textareaID);
+               if (typeof window.opera !== "undefined") {
+                       this.storageField.focus();/*Opera needs to focus this element before persisting values in it*/
+               }
+       },
+       
+       /*Public*/
+       put: function(key, value) {
+               
+               var encodedKey = encodeURI(key);
+               
+               this.assertValidKey(encodedKey);
+               /*if we already have a value for this, remove the value before adding the new one*/
+               if (this.hasKey(key)) {
+                       this.remove(key);
+               }
+               /*store this new key*/
+               this.storageHash[encodedKey] = value;
+               /*save and serialize the hashtable into the form*/
+               this.saveHashTable();
+       },
+
+       /*Public*/
+       get: function(key) {
+
+               var encodedKey = encodeURI(key);
+               
+               this.assertValidKey(encodedKey);
+               /*make sure the hash table has been loaded from the form*/
+               this.loadHashTable();
+               var value = this.storageHash[encodedKey];
+               if (value === undefined) {
+                       value = null;
+               }
+               return value;
+       },
+
+       /*Public*/
+       remove: function(key) {
+               
+               var encodedKey = encodeURI(key);
+
+               this.assertValidKey(encodedKey);
+               /*make sure the hash table has been loaded from the form*/
+               this.loadHashTable();
+               /*delete the value*/
+               delete this.storageHash[encodedKey];
+               /*serialize and save the hash table into the form*/
+               this.saveHashTable();
+       },
+
+       /*Public: Clears out all saved data.*/
+       reset: function() {
+               this.storageField.value = "";
+               this.storageHash = {};
+       },
+
+       /*Public*/
+       hasKey: function(key) {
+               
+               var encodedKey = encodeURI(key);
+
+               this.assertValidKey(encodedKey);
+               /*make sure the hash table has been loaded from the form*/
+               this.loadHashTable();
+               return (typeof this.storageHash[encodedKey] !== "undefined");
+       },
+
+       /*Public*/
+       isValidKey: function(key) {
+               return (typeof key === "string");
+               //TODO - should we ban hash signs and other special characters?
+       },
+       
+       /*- - - - - - - - - - - -*/
+
+       /*Private - CSS strings utilized by both objects to hide or show behind-the-scenes DOM elements*/
+       showStyles: 'border:0;margin:0;padding:0;',
+       hideStyles: 'left:-1000px;top:-1000px;width:1px;height:1px;border:0;position:absolute;',
+       
+       /*Private - debug mode flag*/
+       debugMode: false,
+
+       /*Private: Our hash of key name/values.*/
+       storageHash: {},
+
+       /*Private: If true, we have loaded our hash table out of the storage form.*/
+       hashLoaded: false,
+
+       /*Private: DOM reference to our history field*/
+       storageField: null,
+
+       /*Private: Assert that a key is valid; throw an exception if it not.*/
+       assertValidKey: function(key) {
+               var isValid = this.isValidKey(key);
+               if (!isValid && this.debugMode) {
+                       throw new Error("Please provide a valid key for window.historyStorage. Invalid key = " + key + ".");
+               }
+       },
+
+       /*Private: Load the hash table up from the form.*/
+       loadHashTable: function() {
+               if (!this.hashLoaded) {
+                       var serializedHashTable = this.storageField.value;
+                       if (serializedHashTable !== "" && serializedHashTable !== null) {
+                               this.storageHash = this.fromJSON(serializedHashTable);
+                               this.hashLoaded = true;
+                       }
+               }
+       },
+       /*Private: Save the hash table into the form.*/
+       saveHashTable: function() {
+               this.loadHashTable();
+               var serializedHashTable = this.toJSON(this.storageHash);
+               this.storageField.value = serializedHashTable;
+       },
+       /*Private: Bridges for our JSON implementations - both rely on 2007 JSON.org library - can be overridden by options bundle*/
+       toJSON: function(o) {
+               return o.toJSONString();
+       },
+       fromJSON: function(s) {
+               return s.parseJSON();
+       }
+};
+
+
+/*******************************************************************/
+/** QueryString Object from http://adamv.com/dev/javascript/querystring */
+/* Client-side access to querystring name=value pairs
+	Version 1.3
+	28 May 2008
+	
+	License (Simplified BSD):
+	http://adamv.com/dev/javascript/qslicense.txt
+*/
+function Querystring(qs) { // optionally pass a querystring to parse
+	this.params = {};
+	
+	if (qs == null) qs = location.search.substring(1, location.search.length);
+	if (qs.length == 0) return;
+
+// Turn <plus> back to <space>
+// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
+	qs = qs.replace(/\+/g, ' ');
+	var args = qs.split('&'); // parse out name/value pairs separated via &
+	
+// split out each name=value pair
+	for (var i = 0; i < args.length; i++) {
+		var pair = args[i].split('=');
+		var name = decodeURI(pair[0]);
+		
+		var value = (pair.length==2)
+			? decodeURI(pair[1])
+			: name;
+		
+		this.params[name] = value;
+	}
+}
+
+Querystring.prototype.get = function(key, default_) {
+	var value = this.params[key];
+	return (value != null) ? value : default_;
+}
+
+Querystring.prototype.contains = function(key) {
+	var value = this.params[key];
+	return (value != null);
+}
+
+/*******************************************************************/
+/* Added by Ed Wildgoose - MailASail */
+/* Initialise the library and add our history callback */
+/*******************************************************************/
+window.dhtmlHistory.create({
+        toJSON: function(o) {
+                return Object.toJSON(o);
+        }
+        , fromJSON: function(s) {
+                return s.evalJSON();
+        }
+        
+        // Enable this to assist with debugging
+//        , debugMode: true
+
+        // dhtmlHistory has been modified not to need the next line
+        // But left in for robustness when updating dhtmlHistory
+        , blankURL: '/blank.html?'
+});
+
+/** Our callback to receive history
+    change events. */
+var handleHistoryChange = function(pageId, pageData) {
+  if (!pageData) return;
+  var info = pageId.split(':');
+  var id = info[0];
+  pageData += '&_method=get';
+  new Ajax.Updater(id+'-content', pageData, {asynchronous:true, evalScripts:true, method: 'get', onLoading:function(request){Element.show(id+'-pagination-loading-indicator');}});
+}
+
+window.onload = function() {
+        dhtmlHistory.initialize(handleHistoryChange);
+};
+

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js
------------------------------------------------------------------------------
    svn:executable = *

Added: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/form_enhancements.js
URL: http://svn.apache.org/viewvc/labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/form_enhancements.js?rev=809371&view=auto
==============================================================================
--- labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/form_enhancements.js (added)
+++ labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/form_enhancements.js Sun Aug 30 16:30:26 2009
@@ -0,0 +1,114 @@
+
+// TODO Change to dropping the name property off the input element when in example mode
+TextFieldWithExample = Class.create();
+TextFieldWithExample.prototype = {
+	initialize: function(inputElementId, defaultText, options) {
+	  this.setOptions(options);
+
+		this.input = $(inputElementId);
+		this.name = this.input.name;
+		this.defaultText = defaultText;
+		this.createHiddenInput();
+
+		this.checkAndShowExample();
+
+		Event.observe(this.input, "blur", this.onBlur.bindAsEventListener(this));
+		Event.observe(this.input, "focus", this.onFocus.bindAsEventListener(this));
+		Event.observe(this.input, "select", this.onFocus.bindAsEventListener(this));
+		Event.observe(this.input, "keydown", this.onKeyPress.bindAsEventListener(this));
+		Event.observe(this.input, "click", this.onClick.bindAsEventListener(this));
+	},
+	createHiddenInput: function() {
+		this.hiddenInput = document.createElement("input");
+		this.hiddenInput.type = "hidden";
+		this.hiddenInput.value = "";
+		this.input.parentNode.appendChild(this.hiddenInput);
+	},
+	setOptions: function(options) {
+    	this.options = { exampleClassName: 'example' };
+    	Object.extend(this.options, options || {});
+  	},
+	onKeyPress: function(event) {
+		if (!event) var event = window.event;
+	 	var code = (event.which) ? event.which : event.keyCode
+	 	if (this.isAlphanumeric(code)) {
+	 		this.removeExample();
+	 	}
+	},
+	onBlur: function(event) {
+		this.checkAndShowExample();
+	},
+	onFocus: function(event) {
+		if (this.exampleShown()) {
+		    this.removeExample();
+	  	}
+	},
+	onClick: function(event) {
+		this.removeExample();
+	},
+	isAlphanumeric: function(keyCode) {
+		return keyCode >= 40 && keyCode <= 90;
+	},
+	checkAndShowExample: function() {
+		if (this.input.value == '') {
+			this.input.value = this.defaultText;
+			this.input.name = null;
+			this.hiddenInput.name = this.name;
+			Element.addClassName(this.input, this.options.exampleClassName);
+		}
+	},
+  removeExample: function() {
+		if (this.exampleShown()) {
+			this.input.value = '';
+			this.input.name = this.name;
+			this.hiddenInput.name = null;
+			Element.removeClassName(this.input, this.options.exampleClassName);
+		}
+	},
+	exampleShown: function() {
+		return Element.hasClassName(this.input, this.options.exampleClassName);
+	}
+}
+
+Form.disable = function(form) {
+    var elements = this.getElements(form);
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      try { element.blur(); } catch (e) {}
+      element.disabled = 'disabled';
+      Element.addClassName(element, 'disabled');
+    }
+  }
+Form.enable = function(form) {
+    var elements = this.getElements(form);
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      element.disabled = '';
+      Element.removeClassName(element, 'disabled');
+    }
+  }
+
+DraggableLists = Class.create({
+  initialize: function(list) {
+    list = $(list).addClassName('draggable-list');
+    var list_selected = list.cloneNode(false).addClassName('selected');
+    list_selected.id += '_seleted';
+    list.select('input[type=checkbox]').each(function(item) {
+      var li = item.up('li');
+      li.down('label').htmlFor = null;
+      new Draggable(li, {revert: 'failure', ghosting: true});
+      if (item.checked) list_selected.insert(li.remove());
+    });
+    list.insert({after: list_selected});
+    Droppables.add(list, {hoverclass: 'hover', containment: list_selected.id, onDrop: this.drop_to_list});
+    Droppables.add(list_selected, {hoverclass: 'hover', containment: list.id, onDrop: this.drop_to_list});
+    list.undoPositioned(); // undo positioned to fix dragging from elements with overflow auto
+    list_selected.undoPositioned();
+  },
+
+  drop_to_list: function(draggable, droppable, event) {
+    droppable.insert(draggable.remove());
+    draggable.setStyle({left: '0px', top: '0px'});
+    draggable.down('input').checked = droppable.hasClassName('selected');
+  }
+});

Propchange: labs/consite/trunk/conferences/vendor/plugins/active_scaffold/frontends/default/javascripts/form_enhancements.js
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org