Diff
Modified: branches/datasets/README (2857 => 2858)
--- branches/datasets/README 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/README 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,15 +1,15 @@
== Welcome to Rails
-Rails is a web-application and persistence framework that includes everything
-needed to create database-backed web-applications according to the
-Model-View-Control pattern of separation. This pattern splits the view (also
-called the presentation) into "dumb" templates that are primarily responsible
-for inserting pre-built data in between HTML tags. The model contains the
-"smart" domain objects (such as Account, Product, Person, Post) that holds all
-the business logic and knows how to persist themselves to a database. The
-controller handles the incoming requests (such as Save New Account, Update
-Product, Show Post) by manipulating the model and directing data to the view.
+Rails is a web-application framework that includes everything needed to create
+database-backed web applications according to the Model-View-Control pattern.
+This pattern splits the view (also called the presentation) into "dumb" templates
+that are primarily responsible for inserting pre-built data in between HTML tags.
+The model contains the "smart" domain objects (such as Account, Product, Person,
+Post) that holds all the business logic and knows how to persist themselves to
+a database. The controller handles the incoming requests (such as Save New Account,
+Update Product, Show Post) by manipulating the model and directing data to the view.
+
In Rails, the model is handled by what's called an object-relational mapping
layer entitled Active Record. This layer allows you to present the data from
database rows as objects and embellish these data objects with business logic
@@ -25,73 +25,132 @@
link:files/vendor/rails/actionpack/README.html.
-== Getting started
+== Getting Started
-1. At the command prompt, start a new rails application using the rails command
+1. At the command prompt, start a new Rails application using the <tt>rails</tt> command
and your application name. Ex: rails myapp
- (If you've downloaded rails in a complete tgz or zip, this step is already done)
2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
-3. Go to http://localhost:3000/ and get "Welcome aboard: You’re riding the Rails!"
+3. Go to http://localhost:3000/ and get "Welcome aboard: You're riding the Rails!"
4. Follow the guidelines to start developing your application
== Web Servers
-By default, Rails will try to use Mongrel and lighttpd if they are installed, otherwise
-Rails will use the WEBrick, the webserver that ships with Ruby. When you run script/server,
-Rails will check if Mongrel exists, then lighttpd and finally fall back to WEBrick. This ensures
-that you can always get up and running quickly.
+By default, Rails will try to use Mongrel if it's are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails
+with a variety of other web servers.
-Mongrel is a Ruby-based webserver with a C-component (which requires compilation) that is
+Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is
suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
More info at: http://mongrel.rubyforge.org
-If Mongrel is not installed, Rails will look for lighttpd. It's considerably faster than
-Mongrel and WEBrick and also suited for production use, but requires additional
-installation and currently only works well on OS X/Unix (Windows users are encouraged
-to start with Mongrel). We recommend version 1.4.11 and higher. You can download it from
-http://www.lighttpd.net.
+Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or
+Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use
+FCGI or proxy to a pack of Mongrels/Thin/Ebb servers.
-And finally, if neither Mongrel or lighttpd are installed, Rails will use the built-in Ruby
-web server, WEBrick. WEBrick is a small Ruby web server suitable for development, but not
-for production.
+== Apache .htaccess example for FCGI/CGI
-But of course its also possible to run Rails on any platform that supports FCGI.
-Apache, LiteSpeed, IIS are just a few. For more information on FCGI,
-please visit: http://wiki.rubyonrails.com/rails/pages/FastCGI
+# General Apache options
+AddHandler fastcgi-script .fcgi
+AddHandler cgi-script .cgi
+Options +FollowSymLinks +ExecCGI
+# If you don't want Rails to look in certain directories,
+# use the following rewrite rules so that Apache won't rewrite certain requests
+#
+# Example:
+# RewriteCond %{REQUEST_URI} ^/notrails.*
+# RewriteRule .* - [L]
+# Redirect all requests not available on the filesystem to Rails
+# By default the cgi dispatcher is used which is very slow
+#
+# For better performance replace the dispatcher with the fastcgi one
+#
+# Example:
+# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
+RewriteEngine On
+
+# If your Rails application is accessed via an Alias directive,
+# then you MUST also set the RewriteBase in this htaccess file.
+#
+# Example:
+# Alias /myrailsapp /path/to/myrailsapp/public
+# RewriteBase /myrailsapp
+
+RewriteRule ^$ index.html [QSA]
+RewriteRule ^([^.]+)$ $1.html [QSA]
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
+
+# In case Rails experiences terminal errors
+# Instead of displaying this message you can supply a file here which will be rendered instead
+#
+# Example:
+# ErrorDocument 500 /500.html
+
+ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
+
+
== Debugging Rails
-Have "tail -f" commands running on the server.log and development.log. Rails will
-automatically display debugging and runtime information to these files. Debugging
-info will also be shown in the browser on requests from 127.0.0.1.
+Sometimes your application goes wrong. Fortunately there are a lot of tools that
+will help you debug it and get it back on the rails.
+First area to check is the application log files. Have "tail -f" commands running
+on the server.log and development.log. Rails will automatically display debugging
+and runtime information to these files. Debugging info will also be shown in the
+browser on requests from 127.0.0.1.
-== Breakpoints
+You can also log your own messages directly into the log file from your code using
+the Ruby logger class from inside your controllers. Example:
-Breakpoint support is available through the script/breakpointer client. This
-means that you can break out of execution at any point in the code, investigate
-and change the model, AND then resume execution! Example:
+ class WeblogController < ActionController::Base
+ def destroy
+ @weblog = Weblog.find(params[:id])
+ @weblog.destroy
+ logger.info("#{Time.now} Destroyed Weblog ID address@hidden")
+ end
+ end
+The result will be a message in your log file along the lines of:
+
+ Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1
+
+More information on how to use the logger is at http://www.ruby-doc.org/core/
+
+Also, Ruby documentation can be found at http://www.ruby-lang.org/ including:
+
+* The Learning Ruby (Pickaxe) Book: http://www.ruby-doc.org/docs/ProgrammingRuby/
+* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
+
+These two online (and free) books will bring you up to speed on the Ruby language
+and also on programming in general.
+
+
+== Debugger
+
+Debugger support is available through the debugger command when you start your Mongrel or
+Webrick server with --debugger. This means that you can break out of execution at any point
+in the code, investigate and change the model, AND then resume execution!
+You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'
+Example:
+
class WeblogController < ActionController::Base
def index
@posts = Post.find(:all)
- breakpoint "Breaking out from the list"
+ debugger
end
end
So the controller will accept the action, run the first line, then present you
-with a IRB prompt in the breakpointer window. Here you can do things like:
+with a IRB prompt in the server window. Here you can do things like:
-Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint'
-
>> @posts.inspect
=> "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
#<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
- >> @posts.first.title = "hello from a breakpoint"
- => "hello from a breakpoint"
+ >> @posts.first.title = "hello from a debugger"
+ => "hello from a debugger"
...and even better is that you can examine how your runtime objects actually work:
@@ -100,7 +159,7 @@
>> f.
Display all 152 possibilities? (y or n)
-Finally, when you're ready to resume execution, you press CTRL-D
+Finally, when you're ready to resume execution, you enter "cont"
== Console
@@ -113,12 +172,16 @@
To reload your controllers and models after launching the console run <tt>reload!</tt>
-To reload your controllers and models after launching the console run <tt>reload!</tt>
+== dbconsole
+You can go to the command line of your database directly through <tt>script/dbconsole</tt>.
+You would be connected to the database with the credentials defined in database.yml.
+Starting the script without arguments will connect you to the development database. Passing an
+argument will connect you to a different database, like <tt>script/dbconsole production</tt>.
+Currently works for mysql, postgresql and sqlite.
+== Description of Contents
-== Description of contents
-
app
Holds all the code that's specific to this particular application.
@@ -133,13 +196,13 @@
app/views
Holds the template files for the view that should be named like
- weblogs/index.rhtml for the WeblogsController#index action. All views use eRuby
+ weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
syntax.
app/views/layouts
Holds the template files for layouts to be used with views. This models the common
header/footer method of wrapping views. In your views, define a layout using the
- <tt>layout :default</tt> and create a file named default.rhtml. Inside default.rhtml,
+ <tt>layout :default</tt> and create a file named default.html.erb. Inside default.html.erb,
call <% yield %> to render the view using this layout.
app/helpers
@@ -150,9 +213,6 @@
config
Configuration files for the Rails environment, the routing map, the database, and other dependencies.
-components
- Self-contained mini-applications that can bundle together controllers, models, and views.
-
db
Contains the database schema in schema.rb. db/migrate contains all
the sequence of Migrations for your schema.
@@ -179,4 +239,5 @@
vendor
External libraries that the application depends on. Also includes the plugins subdirectory.
+ If the app has frozen rails, those gems also go here, under vendor/rails/.
This directory is in the load path.
Modified: branches/datasets/app/controllers/announcements_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/announcements_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/announcements_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -15,7 +15,7 @@
respond_to do |format|
format.html # index.rhtml
format.rss do
- render :action ="" 'index.rxml', :layout => false
+ render :action ="" 'feed.rxml', :layout => false
end
end
end
@@ -27,9 +27,9 @@
format.html {
@lod_nir = announcement_url(@announcement)
- @lod_html = formatted_announcement_url(:id => @announcement.id, :format => 'html')
- @lod_rdf = formatted_announcement_url(:id => @announcement.id, :format => 'rdf')
- @lod_xml = formatted_announcement_url(:id => @announcement.id, :format => 'xml')
+ @lod_html = announcement_url(:id => @announcement.id, :format => 'html')
+ @lod_rdf = announcement_url(:id => @announcement.id, :format => 'rdf')
+ @lod_xml = announcement_url(:id => @announcement.id, :format => 'xml')
#
# show.rhtml
}
Deleted: branches/datasets/app/controllers/application.rb (2857 => 2858)
--- branches/datasets/app/controllers/application.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/application.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,1194 +0,0 @@
-# myExperiment: app/controllers/application.rb
-#
-# Copyright (c) 2007 University of Manchester and the University of Southampton.
-# See license.txt for details.
-
-# Filters added to this controller apply to all controllers in the application.
-# Likewise, all the methods added will be available for all controllers.
-
-class ApplicationController < ActionController::Base
-
- filter_parameter_logging :password
-
- WhiteListHelper.tags.merge %w(table tr td th div span)
-
- #before_filter :set_configuration
-
- include AuthenticatedSystem
- before_filter :login_from_cookie
- before_filter :oauth_required
-
- include ActionView::Helpers::NumberHelper
-
- # Pick a unique cookie name to distinguish our session data from others'
- session :session_key => '_m2_session_id'
-
- def base_host
- request.host_with_port
- end
-
-
- # if "referer" in the HTTP header contains "myexperiment", we know
- # that current action was accessed from myExperiment website; if
- # referer is not set OR doesn't contain the search string, access
- # was initiated from other location
- def accessed_from_website?
- res = false
-
- referer = request.env['HTTP_REFERER']
- unless referer.nil? || referer.match("^#{Conf.base_uri}").nil?
- res = true
- end
-
- return res
- end
-
- def set_configuration
- Conf.set_configuration(request, session)
- end
-
- def formatted_timespan(time_period)
- # Takes a period of time in seconds and returns it in human-readable form (down to minutes)
- # from (http://www.postal-code.com/binarycode/category/devruby/)
- out_str = ""
-
- interval_array = [ [:weeks, 604800], [:days, 86400], [:hours, 3600], [:minutes, 60] ]
- interval_array.each do |sub|
- if time_period >= sub[1]
- time_val, time_period = time_period.divmod(sub[1])
-
- time_val == 1 ? name = sub[0].to_s.singularize : name = sub[0].to_s
-
- ( sub[0] != :minutes ? out_str += ", " : out_str += " and " ) if out_str != ''
- out_str += time_val.to_s + " #{name}"
- end
- end
-
- return out_str
- end
-
-
- # this method is only intended to check if entry
- # in "viewings" or "downloads" table needs to be
- # created for current access - and this is *only*
- # supposed to be working for *contributables*
- #
- # NB! The input parameter is the actual contributable OR
- # the version of it (currently only workflows are versioned)
- def allow_statistics_logging(contributable_or_version)
-
- # check if the current viewing/download is to be logged
- # (i.e. request is sent not by a bot and is legitimate)
- allow_logging = true
- Conf.bot_ignore_list.each do |pattern|
- if request.env['HTTP_USER_AGENT'] and request.env['HTTP_USER_AGENT'].match(pattern)
- allow_logging = false
- break
- end
- end
-
- # disallow logging of events referring to contributables / versions of them
- # that have been uploaded by current user;
- #
- # however, if there are newer versions of contributable (uploaded not by the original uploader),
- # we do want to record viewings/downloads of this newer version by the original uploader
- if allow_logging && current_user != 0
- allow_logging = false if (contributable_or_version.contributor_type == "User" && contributable_or_version.contributor_id == current_user.id)
- end
-
- return allow_logging
- end
-
-
- # Safe HTML - http://www.anyexample.com/webdev/rails/how_to_allow_some_safe_html_in_rails_projects.xml
- # Note: should only be used for text that doesn't need updating later.
- def ae_some_html(s)
- return '' if s.nil?
-
- # converting newlines
- s.gsub!(/\r\n?/, "\n")
-
- # escaping HTML to entities
- s = s.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>')
-
- # blockquote tag support
- s.gsub!(/\n?<blockquote>\n*(.+?)\n*<\/blockquote>/im, "<blockquote>\\1</blockquote>")
-
- # other tags: b, i, em, strong, u
- %w(b i em strong u).each { |x|
- s.gsub!(Regexp.new('<(' + x + ')>(.+?)</('+x+')>',
- Regexp::MULTILINE|Regexp::IGNORECASE),
- "<\\1>\\2</\\1>")
- }
-
- # A tag support
- # href="" attribute auto-adds http://
- s = s.gsub(/<a.+?href\s*=\s*['"](.+?)["'].*?>(.+?)<\/a>/im) { |x|
- '<a href="" + ($1.index('://') ? $1 : 'http://'+$1) + "\">" + $2 + "</a>"
- }
-
- # replacing newlines to <br> ans <p> tags
- # wrapping text into paragraph
- s = "<p>" + s.gsub(/\n\n+/, "</p>\n\n<p>").
- gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') + "</p>"
-
- s
- end
-
- # This method takes a comma seperated list of tags (where multiple words don't need to be in quote marks)
- # and formats it into a new comma seperated list where multiple words ARE in quote marks.
- # (Note: it will actually put quote marks around all the words and then out commas).
- # eg:
- # this, is a, tag
- # becomes:
- # "this","is a","tag"
- #
- # This is so we can map the tags entered in by users to the format required by the act_as_taggable_redux gem.
- def convert_tags_to_gem_format(tags_string)
- list = parse_comma_seperated_string(tags_string)
- converted = ''
-
- list.each do |s|
- converted = converted + '"' + s.strip + '",'
- end
-
- return converted
- end
-
- helper_method :ae_some_html
-
- # This method converts a comma seperated string of values into a collection of those values.
- # Note: currently does not cater for values in quotation marks and does not remove empty values
- # (although it does ignore a trailing comma)
- def parse_comma_seperated_string(s)
- list = s.split(',')
- end
-
- def update_policy(contributable, params)
-
- # this method will return an error message is something goes wrong (empty string in case of success)
- error_msg = ""
-
-
- # BEGIN validation and initialisation
-
- # This variable will hold current settings of the policy in case something
- # goes wrong and a revert would be needed at some point
- last_saved_policy = nil
-
- return if params[:sharing].nil? or params[:sharing][:class_id].blank?
-
- sharing_class = params[:sharing][:class_id]
- updating_class = (params[:updating] and !params[:updating][:class_id].blank?) ? params[:updating][:class_id] : "6"
-
- # Check allowed sharing_class values
- return unless [ "0", "1", "2", "3", "4", "7" ].include? sharing_class
-
- # Check allowed updating_class values
- return unless [ "0", "1", "5", "6" ].include? updating_class
-
- view_protected = 0
- view_public = 0
- download_protected = 0
- download_public = 0
- edit_protected = 0
- edit_public = 0
-
- # BEGIN initialisation and validation
-
- unless contributable.contribution.policy
- last_saved_policy = Policy._default(current_user, nil) # second parameter ensures that this policy is not applied anywhere
-
- policy = Policy.new(:name => 'auto',
- :contributor_type => 'User', :contributor_id => current_user.id,
- :share_mode => sharing_class,
- :update_mode => updating_class)
- contributable.contribution.policy = policy # by doing this the new policy object is saved implicitly too
- contributable.contribution.save
- else
- policy = contributable.contribution.policy
- last_saved_policy = policy.clone # clone required, not 'dup' (which still works through reference, so the values in both get changed anyway - which is not what's needed here)
-
- policy.share_mode = sharing_class
- policy.update_mode = updating_class
- policy.save
- end
-
-
- # Process 'update' permissions for "Some of my Friends"
-
- if updating_class == "5"
- if params[:updating_somefriends]
- # Delete old User permissions
- policy.delete_all_user_permissions
-
- # Now create new User permissions, if required
- params[:updating_somefriends].each do |f|
- Permission.new(:policy => policy,
- :contributor => (User.find f[1].to_i),
- :view => 1, :download => 1, :edit => 1).save
- end
- else # none of the 'some of my friends' were selected, error
- # revert changes made to policy (however any permissions updated will preserve the state)
- policy.copy_values_from( last_saved_policy )
- policy.save
- error_msg += "You have selected to set 'update' permissions for 'Some of your Friends', but didn't select any from the list.</br>Previous (if any) or default sharing permissions have been set."
- return error_msg
- end
- else
- # Delete all User permissions - as this isn't mode 5 (i.e. the mode has changed),
- # where some explicit permissions to friends are set
- policy.delete_all_user_permissions
- end
-
-
- # Process explicit Group permissions now
- if params[:group_sharing]
-
- # First delete any Permission objects that don't have a checked entry in the form
- policy.permissions.each do |p|
- params[:group_sharing].each do |n|
- # If a hash value with key 'id' wasn't returned then that means the checkbox was unchecked.
- unless n[1][:id]
- if p.contributor_type == 'Network' and p.contributor_id == n[0].to_i
- p.destroy
- end
- end
- end
- end
-
- # Now create or update Permissions
- params[:group_sharing].each do |n|
-
- # Note: n[1] is used because n is an array and n[1] returns it's value (which in turn is a hash)
- # In this hash, is a value with key 'id' is present then the checkbox for that group was checked.
- if n[1][:id]
-
- n_id = n[1][:id].to_i
- level = n[1][:level]
-
- unless (perm = Permission.find(:first, :conditions => ["policy_id = ? AND contributor_type = ? AND contributor_id = ?", policy.id, 'Network', n_id]))
- # Only create new Permission if it doesn't already exist
- p = Permission.new(:policy => policy, :contributor => (Network.find(n_id)))
- p.set_level!(level) if level
- else
- # Update the 'level' on the existing permission
- perm.set_level!(level) if level
- end
-
- else
-
- n_id = n[0].to_i
-
- # Delete permission if it exists (because this one is unchecked)
- if (perm = Permission.find(:first, :conditions => ["policy_id = ? AND contributor_type = ? AND contributor_id = ?", policy.id, 'Network', n_id]))
- perm.destroy
- end
-
- end
-
- end
- end
-
- logger.debug("------ Workflow create summary ------------------------------------")
- logger.debug("current_user = #{current_user.id}")
- logger.debug("updating_class = #{updating_class}")
- logger.debug("sharing_class = #{sharing_class}")
- logger.debug("policy = #{policy}")
- logger.debug("group_sharing = #{params[:group_sharing]}")
- logger.debug("-------------------------------------------------------------------")
-
- # returns some message in case of errors (or empty string in case of success)
- return error_msg
- end
-
- def update_credits(creditable, params)
-
- # First delete old creditations:
- creditable.creditors.each do |c|
- c.destroy
- end
-
- # Then create new creditations:
-
- # Current user
- if (params[:credits_me].downcase == 'true')
- c = Creditation.new(:creditor_type => 'User', :creditor_id => current_user.id, :creditable_type => creditable.class.to_s, :creditable_id => creditable.id)
- c.save
- end
-
- # Friends + other users
- user_ids = parse_comma_seperated_string(params[:credits_users])
- user_ids.each do |id|
- c = Creditation.new(:creditor_type => 'User', :creditor_id => id, :creditable_type => creditable.class.to_s, :creditable_id => creditable.id)
- c.save
- end
-
- # Networks (aka Groups)
- network_ids = parse_comma_seperated_string(params[:credits_groups])
- network_ids.each do |id|
- c = Creditation.new(:creditor_type => 'Network', :creditor_id => id, :creditable_type => creditable.class.to_s, :creditable_id => creditable.id)
- c.save
- end
-
- end
-
- def update_attributions(attributable, params)
-
- # First delete old attributions:
- attributable.attributors.each do |a|
- a.destroy
- end
-
- # Then create new attributions:
-
- # Workflows
- attributor_workflow_ids = parse_comma_seperated_string(params[:attributions_workflows])
- attributor_type = 'Workflow'
- attributor_workflow_ids.each do |id|
- a = Attribution.new(:attributor_type => attributor_type, :attributor_id => id, :attributable_type => attributable.class.to_s, :attributable_id => attributable.id)
- a.save
- end
-
- # Files
- attributor_file_ids = parse_comma_seperated_string(params[:attributions_files])
- attributor_type = 'Blob'
- attributor_file_ids.each do |id|
- a = Attribution.new(:attributor_type => attributor_type, :attributor_id => id, :attributable_type => attributable.class.to_s, :attributable_id => attributable.id)
- a.save
- end
-
- end
-
- # helper function to determine the context of a polymorphic nested resource
-
- def extract_resource_context(params)
- (Conf.contributor_models + Conf.contributable_models).each do |model_name|
- id_param = "#{Conf.to_visible(model_name.underscore)}_id"
- return Object.const_get(model_name).find_by_id(params[id_param]) if params[id_param]
- end
-
- nil
- end
-
- def deep_clone(ob)
- case ob.class.name
- when "Array"
- ob.map do |x| deep_clone(x) end
- when "Hash"
- hash = {}
- ob.each do |k, v| hash[deep_clone(k)] = deep_clone(v) end
- hash
- when "Symbol"
- ob
- else
- ob.clone
- end
- end
-
- def send_cached_data(file_name, *opts)
-
- if !File.exists?(file_name)
- FileUtils.mkdir_p(File.dirname(file_name))
- File.open(file_name, "wb+") { |f| f.write(yield) }
- end
-
- send_file(file_name, *opts)
- end
-
- # Pivot code
-
- def pivot_options
- {
- :order =>
- [
- {
- :option => 'rank',
- :label => 'Rank',
- :order => 'contributions.rank DESC'
- },
-
- {
- :option => 'title',
- :label => 'Title',
- :order => 'contributions.label, contributions.rank DESC'
- },
-
- {
- :option => 'latest',
- :label => 'Latest',
- :order => 'contributions.created_at DESC, contributions.rank DESC'
- },
-
- {
- :option => 'last_updated',
- :label => 'Last updated',
- :order => 'contributions.updated_at DESC, contributions.rank DESC'
- },
-
- {
- :option => 'rating',
- :label => 'Community rating',
- :order => 'contributions.rating DESC, contributions.rank DESC'
- },
-
- {
- :option => 'viewings',
- :label => 'Most viewed',
- :order => 'contributions.site_viewings_count DESC, contributions.rank DESC'
- },
-
- {
- :option => 'downloads',
- :label => 'Most downloaded',
- :order => 'contributions.site_downloads_count DESC, contributions.rank DESC'
- },
-
- {
- :option => 'type',
- :label => 'Type',
- :joins => [ :content_types ],
- :order => 'content_types.title, contributions.rank DESC'
- },
-
- {
- :option => 'licence',
- :label => 'Licence',
- :joins => [ :licences ],
- :order => 'licenses.title, contributions.rank DESC'
- },
-
- {
- :option => 'topic',
- :label => 'Topic',
- :joins => [ :topic_workflow_map ],
- :order => 'topic_workflow_map.probability, rank DESC'
- }
- ],
-
- :num_options => ['10', '20', '25', '50', '100'],
-
- :filters =>
- [
- {
- :title => 'category',
- :query_option => 'CATEGORY',
- :id_column => :auth_type,
- :label_column => :auth_type,
- :visible_name => true
- },
-
- {
- :title => 'type',
- :query_option => 'TYPE_ID',
- :id_column => 'content_types.id',
- :label_column => 'content_types.title',
- :joins => [ :content_types ],
- :not_null => true
- },
-
- {
- :title => 'tag',
- :query_option => 'TAG_ID',
- :id_column => 'tags.id',
- :label_column => 'tags.name',
- :joins => [ :taggings, :tags ]
- },
-
- {
- :title => 'user',
- :query_option => 'USER_ID',
- :id_column => 'users.id',
- :label_column => 'users.name',
- :joins => [ :users ]
- },
-
- {
- :title => 'licence',
- :query_option => 'LICENSE_ID',
- :id_column => 'licenses.id',
- :label_column => 'licenses.unique_name',
- :joins => [ :licences ],
- :not_null => true
- },
-
- {
- :title => 'group',
- :query_option => 'GROUP_ID',
- :id_column => 'networks.id',
- :label_column => 'networks.title',
- :joins => [ :networks ]
- },
-
- {
- :title => 'wsdl',
- :query_option => 'WSDL_ENDPOINT',
- :id_column => 'workflow_processors.wsdl',
- :label_column => 'workflow_processors.wsdl',
- :joins => [ :workflow_processors ],
- :not_null => true
- },
-
- {
- :title => 'curation',
- :query_option => 'CURATION_EVENT',
- :id_column => 'curation_events.category',
- :label_column => 'curation_events.category',
- :joins => [ :curation_events ],
- :capitalize => true
- },
-
- {
- :title => 'provider',
- :query_option => 'SERVICE_PROVIDER',
- :id_column => 'service_providers.id',
- :label_column => 'service_providers.name',
- :joins => [ :services, :service_providers ]
- },
-
- {
- :title => 'country',
- :query_option => 'SERVICE_COUNTRY',
- :id_column => 'services.country',
- :label_column => 'services.country',
- :joins => [ :services ]
- },
-
- {
- :title => 'service status',
- :query_option => 'SERVICE_STATUS',
- :id_column => 'services.monitor_label',
- :label_column => 'services.monitor_label',
- :joins => [ :services ]
- },
-
-
- ],
-
- :joins =>
- {
- :content_types => "LEFT OUTER JOIN content_types ON contributions.content_type_id = content_types.id",
- :licences => "LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id",
- :users => "INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id",
- :taggings => "LEFT OUTER JOIN taggings ON AUTH_TYPE = taggings.taggable_type AND AUTH_ID = taggings.taggable_id",
- :tags => "INNER JOIN tags ON taggings.tag_id = tags.id",
- :networks => "INNER JOIN networks ON permissions.contributor_type = 'Network' AND permissions.contributor_id = networks.id",
- :credits => "INNER JOIN creditations ON creditations.creditable_type = AUTH_TYPE AND creditations.creditable_id = AUTH_ID",
- :curation_events => "INNER JOIN curation_events ON curation_events.object_type = AUTH_TYPE AND curation_events.object_id = AUTH_ID",
- :workflow_processors => "INNER JOIN workflow_processors ON AUTH_TYPE = 'Workflow' AND workflow_processors.workflow_id = AUTH_ID",
- :search => "RIGHT OUTER JOIN search_results ON search_results.result_type = AUTH_TYPE AND search_results.result_id = AUTH_ID",
- :topic_workflow_map => "INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id",
- :services => "INNER JOIN services ON AUTH_TYPE = 'Service' AND AUTH_ID = services.id",
- :service_providers => "INNER JOIN service_providers ON AUTH_TYPE = 'Service' AND service_providers.uri = services.provider_uri",
- }
- }
- end
-
- TOKEN_UNKNOWN = 0x0000
- TOKEN_AND = 0x0001
- TOKEN_OR = 0x0002
- TOKEN_WORD = 0x0003
- TOKEN_OPEN = 0x0004
- TOKEN_CLOSE = 0x0005
- TOKEN_STRING = 0x0006
- TOKEN_EOS = 0x00ff
-
- NUM_TOKENS = 6
-
- STATE_INITIAL = 0x0000
- STATE_EXPECT_OPEN = 0x0100
- STATE_EXPECT_STR = 0x0200
- STATE_EXPECT_EXPR_END = 0x0300
- STATE_EXPECT_END = 0x0400
- STATE_COMPLETE = 0x0500
-
- def parse_filter_expression(expr)
-
- def unescape_string(str)
- str.match(/^"(.*)"$/)[1].gsub(/\\"/, '"')
- end
-
- state = STATE_INITIAL
- data = ""
-
- begin
-
- tokens = expr.match(/^
-
- \s* (\sAND\s) | # AND operator
- \s* (\sOR\s) | # OR operator
- \s* (\w+) | # a non-keyword word
- \s* (\() | # an open paranthesis
- \s* (\)) | # a close paranthesis
- \s* ("(\\.|[^\\"])*") # double quoted string with backslash escapes
-
- /ix)
-
- if tokens.nil?
- token = TOKEN_UNKNOWN
- else
- (1..NUM_TOKENS).each do |i|
- token = i if tokens[i]
- end
- end
-
- if token == TOKEN_UNKNOWN
- token = TOKEN_EOS if expr.strip.empty?
- end
-
- case state | token
- when STATE_INITIAL | TOKEN_WORD : state = STATE_EXPECT_OPEN ; data << { :name => tokens[0], :expr => [] }
- when STATE_EXPECT_OPEN | TOKEN_OPEN : state = STATE_EXPECT_STR
- when STATE_EXPECT_STR | TOKEN_STRING : state = STATE_EXPECT_EXPR_END ; data.last[:expr] << tokens[0]
- when STATE_EXPECT_EXPR_END | TOKEN_AND : state = STATE_EXPECT_STR ; data.last[:expr] << :and
- when STATE_EXPECT_EXPR_END | TOKEN_OR : state = STATE_EXPECT_STR ; data.last[:expr] << :or
- when STATE_EXPECT_EXPR_END | TOKEN_CLOSE : state = STATE_EXPECT_END
- when STATE_EXPECT_END | TOKEN_AND : state = STATE_INITIAL ; data << :and
- when STATE_EXPECT_END | TOKEN_OR : state = STATE_INITIAL ; data << :or
- when STATE_EXPECT_END | TOKEN_EOS : state = STATE_COMPLETE
-
- else raise "Error parsing query _expression_"
- end
-
- expr = tokens.post_match unless state == STATE_COMPLETE
-
- end while state != STATE_COMPLETE
-
- # validate and reduce expressions to current capabilities
-
- valid_filters = pivot_options[:filters].map do |f| f[:query_option] end
-
- data.each do |category|
- case category
- when :or
- raise "Unsupported query _expression_"
- when :and
- # Fine
- else
- raise "Unknown filter category" unless valid_filters.include?(category[:name])
-
- counts = { :and => 0, :or => 0 }
-
- category[:expr].each do |bit|
- counts[bit] = counts[bit] + 1 if bit.class == Symbol
- end
-
- raise "Unsupported query _expression_" if counts[:and] > 0 && counts[:or] > 0
-
- # haven't implemented 'and' within a particular filter yet
- raise "Unsupported query _expression_" if counts[:and] > 0
-
- if category[:expr].length == 1
- category[:expr] = { :terms => [unescape_string(category[:expr].first)] }
- else
- category[:expr] = {
- :operator => category[:expr][1],
- :terms => category[:expr].select do |t|
- t.class == String
- end.map do |t|
- unescape_string(t)
- end
- }
- end
- end
- end
-
- data
- end
-
- def contributions_list(klass = nil, params = nil, user = nil, opts = {})
-
- def escape_sql(str)
- str.gsub(/\\/, '\&\&').gsub(/'/, "''")
- end
-
- def build_url(params, opts, expr, parts, extra = {})
-
- query = {}
-
- if parts.include?(:filter)
- bits = []
- pivot_options[:filters].each do |filter|
- if !opts[:lock_filter] || opts[:lock_filter][filter[:query_option]].nil?
- if find_filter(expr, filter[:query_option])
- bits << filter[:query_option] + "(\"" + find_filter(expr, filter[:query_option])[:expr][:terms].map do |t| t.gsub(/"/, '\"') end.join("\" OR \"") + "\")"
- end
- end
- end
-
- if bits.length > 0
- query["filter"] = bits.join(" AND ")
- end
- end
-
- query["query"] = params[:query] if params[:query]
- query["order"] = params[:order] if parts.include?(:order)
- query["filter_query"] = params[:filter_query] if parts.include?(:filter_query)
-
- query.merge!(extra)
-
- query
- end
-
- def comparison(lhs, rhs)
- if rhs.length == 1
- "#{lhs} = '#{escape_sql(rhs.first)}'"
- else
- "#{lhs} IN ('#{rhs.map do |bit| escape_sql(bit) end.join("', '")}')"
- end
- end
-
- def create_search_results_table(search_query, models)
-
- begin
- solr_results = models.first.multi_solr_search(search_query,
- :models => models,
- :results_format => :ids,
- :limit => Conf.max_search_size)
- rescue
- return false
- end
-
- conn = ActiveRecord::Base.connection
-
- conn.execute("CREATE TEMPORARY TABLE search_results (id INT AUTO_INCREMENT UNIQUE KEY, result_type VARCHAR(255), result_id INT)")
-
- # This next part converts the search results to SQL values
- #
- # from: { "id" => "Workflow:4" }, { "id" => "Pack:6" }, ...
- # to: "(NULL, 'Workflow', '4'), (NULL, 'Pack', '6'), ..."
-
- if solr_results.results.length > 0
- insert_part = solr_results.results.map do |result|
- "(NULL, " + result["id"].split(":").map do |bit|
- "'#{bit}'"
- end.join(", ") + ")"
- end.join(", ")
-
- conn.execute("INSERT INTO search_results VALUES #{insert_part}")
- end
-
- true
- end
-
- def drop_search_results_table
- ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS search_results")
- end
-
- def calculate_having_clause(filter, opts)
-
- having_bits = []
-
- pivot_options[:filters].each do |f|
- if f != filter
-# if opts[:filters][f[:query_option]] && opts[:filters]["and_#{f[:query_option]}"] == "yes"
-# having_bits << "(GROUP_CONCAT(DISTINCT #{f[:id_column]} ORDER BY #{f[:id_column]}) = '#{escape_sql(opts[:filters][f[:query_option]])}')"
-# end
- end
- end
-
- return nil if having_bits.empty?
-
- "HAVING " + having_bits.join(" OR ")
- end
-
- def column(column, opts)
- if column == :auth_type
- if opts[:auth_type]
- opts[:auth_type]
- else
- "contributions.contributable_type"
- end
- else
- column
- end
- end
-
- def calculate_filter(params, filter, user, opts = {})
-
- # apply all the joins and conditions except for the current filter
-
- joins = []
- conditions = []
-
- pivot_options[:filters].each do |other_filter|
- if filter_list = find_filter(opts[:filters], other_filter[:query_option])
- unless opts[:inhibit_other_conditions]
- conditions << comparison(column(other_filter[:id_column], opts), filter_list[:expr][:terms]) unless other_filter == filter
- end
- joins += other_filter[:joins] if other_filter[:joins]
- end
- end
-
- filter_id_column = column(filter[:id_column], opts)
- filter_label_column = column(filter[:label_column], opts)
-
- joins += filter[:joins] if filter[:joins]
- conditions << "#{filter_id_column} IS NOT NULL" if filter[:not_null]
-
- unless opts[:inhibit_filter_query]
- if params[:filter_query]
- conditions << "(#{filter_label_column} LIKE '%#{escape_sql(params[:filter_query])}%')"
- end
- end
-
- joins.push(:search) if params[:query] && !opts[:arbitrary_models]
-
- current = find_filter(opts[:filters], filter[:query_option]) ? find_filter(opts[:filters], filter[:query_option])[:expr][:terms] : []
-
- if opts[:ids].nil?
- limit = 10
- else
- conditions << "(#{filter_id_column} IN ('#{opts[:ids].map do |id| escape_sql(id) end.join("','")}'))"
- limit = nil
- end
-
- conditions = conditions.length.zero? ? nil : conditions.join(" AND ")
-
- if opts[:auth_type] && opts[:auth_id]
- count_expr = "COUNT(DISTINCT #{opts[:auth_type]}, #{opts[:auth_id]})"
- else
- count_expr = "COUNT(DISTINCT contributions.contributable_type, contributions.contributable_id)"
- end
-
- objects = Authorization.authorised_index(params[:query] && opts[:arbitrary_models] ? SearchResult : Contribution,
- :all,
- :include_permissions => true,
- :select => "#{filter_id_column} AS filter_id, #{filter_label_column} AS filter_label, #{count_expr} AS filter_count",
- :arbitrary_models => opts[:arbitrary_models],
- :auth_type => opts[:auth_type],
- :auth_id => opts[:auth_id],
- :joins => merge_joins(joins, :auth_type => opts[:auth_type], :auth_id => opts[:auth_id]),
- :conditions => conditions,
- :group => "#{filter_id_column} #{calculate_having_clause(filter, opts)}",
- :limit => limit,
- :order => "#{count_expr} DESC, #{filter_label_column}",
- :authorised_user => user)
-
- objects = objects.select do |x| !x[:filter_id].nil? end
-
- objects = objects.map do |object|
-
- value = object.filter_id.to_s
- selected = current.include?(value)
-
- label_expr = deep_clone(opts[:filters])
- label_expr -= [find_filter(label_expr, filter[:query_option])] if find_filter(label_expr, filter[:query_option])
-
- unless selected && current.length == 1
- label_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
- end
-
- checkbox_expr = deep_clone(opts[:filters])
-
- if expr_filter = find_filter(checkbox_expr, filter[:query_option])
-
- if selected
- expr_filter[:expr][:terms] -= [value]
- else
- expr_filter[:expr][:terms] += [value]
- end
-
- checkbox_expr -= [expr_filter] if expr_filter[:expr][:terms].empty?
-
- else
- checkbox_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
- end
-
- label_uri = build_url(params, opts, label_expr, [:filter, :order], "page" => nil)
-
- checkbox_uri = build_url(params, opts, checkbox_expr, [:filter, :order], "page" => nil)
-
- label = object.filter_label.clone
- label = visible_name(label) if filter[:visible_name]
- label = label.capitalize if filter[:capitalize]
-
- plain_label = object.filter_label
-
- if params[:filter_query]
- label.sub!(Regexp.new("(#{params[:filter_query]})", Regexp::IGNORECASE), '<b>\1</b>')
- end
-
- {
- :object => object,
- :value => value,
- :label => label,
- :plain_label => plain_label,
- :count => object.filter_count,
- :checkbox_uri => checkbox_uri,
- :label_uri => label_uri,
- :selected => selected
- }
- end
-
- [current, objects]
- end
-
- def calculate_filters(params, opts, user)
-
- # produce the filter list
-
- filters = pivot_options[:filters].clone
- cancel_filter_query_url = nil
-
- filters.each do |filter|
-
- # calculate the top n items of the list
-
- filter[:current], filter[:objects] = calculate_filter(params, filter, user, opts)
-
- # calculate which active filters are missing (because they weren't in the
- # top part of the list or have a count of zero)
-
- missing_filter_ids = filter[:current] - filter[:objects].map do |ob| ob[:value] end
-
- if missing_filter_ids.length > 0
- filter[:objects] += calculate_filter(params, filter, user, opts.merge(:ids => missing_filter_ids))[1]
- end
-
- # calculate which active filters are still missing (because they have a
- # count of zero)
-
- missing_filter_ids = filter[:current] - filter[:objects].map do |ob| ob[:value] end
-
- if missing_filter_ids.length > 0
- zero_list = calculate_filter(params, filter, user, opts.merge(:ids => missing_filter_ids, :inhibit_other_conditions => true))[1]
-
- zero_list.each do |x| x[:count] = 0 end
-
- zero_list.sort! do |a, b| a[:label] <=> b[:label] end
-
- filter[:objects] += zero_list
- end
- end
-
- [filters, cancel_filter_query_url]
- end
-
- def find_filter(filters, name)
- filters.find do |f|
- f[:name] == name
- end
- end
-
- def merge_joins(joins, opts = {})
-
- opts[:auth_type] ||= 'contributions.contributable_type'
- opts[:auth_id] ||= 'contributions.contributable_id'
-
- if joins.length.zero?
- nil
- else
- joins.uniq.map do |j|
- text = pivot_options[:joins][j]
- text.gsub!(/AUTH_TYPE/, opts[:auth_type])
- text.gsub!(/AUTH_ID/, opts[:auth_id])
- text
- end.join(" ")
- end
- end
-
- joins = []
- conditions = []
-
- # parse the filter _expression_ if provided. convert filter _expression_ to
- # the old format. this will need to be replaced eventually
-
- opts[:filters] ||= []
-
- include_reset_url = opts[:filters].length > 0
-
- # filter out top level logic operators for now
-
- opts[:filters] = opts[:filters].select do |bit|
- bit.class == Hash
- end
-
- # apply locked filters
-
- if opts[:lock_filter]
- opts[:lock_filter].each do |filter, value|
- opts[:filters] << { :name => filter, :expr => { :terms => [value] } }
- end
- end
-
- # perform search if requested
-
- group_by = "contributions.contributable_type, contributions.contributable_id"
-
- query_problem = false
-
- if params["query"]
- drop_search_results_table
- if create_search_results_table(params["query"], [Workflow, Blob, Pack, User, Network, Service])
- joins.push(:search) unless opts[:arbitrary_models]
- else
- params["query"] = nil
- query_problem = true
- end
- end
-
- if opts[:arbitrary_models] && params[:query]
- klass = SearchResult
- contribution_records = false
- auth_type = "search_results.result_type"
- auth_id = "search_results.result_id"
- group_by = "search_results.result_type, search_results.result_id"
- else
- contribution_records = true
- end
-
- # determine joins, conditions and order for the main results
-
- pivot_options[:filters].each do |filter|
- if filter_list = find_filter(opts[:filters], filter[:query_option])
- conditions << comparison(column(filter[:id_column], opts.merge( { :auth_type => auth_type, :auth_id => auth_id } )), filter_list[:expr][:terms])
- joins += filter[:joins] if filter[:joins]
- end
- end
-
- order_options = pivot_options[:order].find do |x|
- x[:option] == params[:order]
- end
-
- order_options ||= pivot_options[:order].first
-
- joins += order_options[:joins] if order_options[:joins]
-
- having_bits = []
-
-# pivot_options[:filters].each do |filter|
-# if params["and_#{filter[:query_option]}"]
-# having_bits << "GROUP_CONCAT(DISTINCT #{filter[:id_column]} ORDER BY #{filter[:id_column]}) = \"#{escape_sql(opts[:filters][filter[:query_option]])}\""
-# end
-# end
-
- having_clause = ""
-
- if having_bits.length > 0
- having_clause = "HAVING #{having_bits.join(' AND ')}"
- end
-
- # perform the results query
-
- results = Authorization.authorised_index(klass,
- :all,
- :authorised_user => user,
- :include_permissions => true,
- :contribution_records => contribution_records,
- :arbitrary_models => opts[:arbitrary_models],
- :auth_type => auth_type,
- :auth_id => auth_id,
- :page => { :size => params["num"] ? params["num"].to_i : nil, :current => params["page"] },
- :joins => merge_joins(joins, :auth_type => auth_type, :auth_id => auth_id),
- :conditions => conditions.length.zero? ? nil : conditions.join(" AND "),
- :group => "#{group_by} #{having_clause}",
- :order => order_options[:order])
-
- # produce a query hash to match the current filters
-
- opts[:filter_params] = {}
-
- pivot_options[:filters].each do |filter|
- if params[filter[:query_option]]
- next if opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
- opts[:filter_params][filter[:query_option]] = params[filter[:query_option]]
- end
- end
-
- # produce the filter list
-
- opts_for_filter_query = opts.merge( { :auth_type => auth_type,
- :auth_id => auth_id, :group_by => group_by } )
-
- filters, cancel_filter_query_url = calculate_filters(params, opts_for_filter_query, user)
-
- # produce the summary. If a filter query is specified, then we need to
- # recalculate the filters without the query to get all of them.
-
- if params[:filter_query]
- filters2 = calculate_filters(params, opts_for_filter_query.merge( { :inhibit_filter_query => true } ), user)[0]
- else
- filters2 = filters
- end
-
- summary = ""
-
- filters2.select do |filter|
-
- next if opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
-
- selected = filter[:objects].select do |x| x[:selected] end
- current = selected.map do |x| x[:value] end
-
- if selected.length > 0
- selected_labels = selected.map do |x|
-
- expr = deep_clone(opts[:filters])
-
- f = find_filter(expr, filter[:query_option])
-
- expr -= f[:expr][:terms] -= [x[:value]]
- expr -= [f] if f[:expr][:terms].empty?
-
- x[:plain_label] + ' <a href="" + url_for(build_url(params, opts, expr,
- [:filter, :filter_query, :order])) +
- '">' + " <img src='' /></a>"
-
- end
-
- bits = selected_labels.map do |label| label end.join(" <i>or</i> ")
-
- summary << '<span class="filter-in-use"><b>' + filter[:title].capitalize + "</b>: " + bits + "</span> "
- end
- end
-
- if params[:filter_query]
- cancel_filter_query_url = build_url(params, opts, opts[:filters], [:filter, :order])
- end
-
- if include_reset_url
- reset_filters_url = build_url(params, opts, opts[:filters], [:order])
- end
-
- # remove filters that do not help in narrowing down the result set
-
- filters = filters.select do |filter|
- if filter[:objects].empty?
- false
- elsif opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
- false
- else
- true
- end
- end
-
- {
- :results => results,
- :filters => filters,
- :reset_filters_url => reset_filters_url,
- :cancel_filter_query_url => cancel_filter_query_url,
- :filter_query_url => build_url(params, opts, opts[:filters], [:filter]),
- :summary => summary,
- :query_problem => query_problem
- }
- end
-
- #Applies the layout for the Network with the given network_id to the object (contributable)
- def update_layout(object,network_id)
- if network_id.blank?
- object.contribution.layout = nil
- object.contribution.save
- else
- network = Network.find(network_id.to_i)
- # Have to call .reload on permissions or the cached permissions from before "update_policy" was called are used
- if network && find_permission_for_contributor(object.contribution.policy.permissions.reload, "Network", network_id.to_i)
- object.contribution.layout = network.layout_name
- object.contribution.save
- else
- object.errors.add_to_base("You may only choose layouts for groups that this #{object.class.name.downcase} is shared with.")
- end
- end
-
- end
-end
Copied: branches/datasets/app/controllers/application_controller.rb (from rev 2857, trunk/app/controllers/application_controller.rb) (0 => 2858)
--- branches/datasets/app/controllers/application_controller.rb (rev 0)
+++ branches/datasets/app/controllers/application_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,1194 @@
+# myExperiment: app/controllers/application.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+class ApplicationController < ActionController::Base
+ helper :all # include all helpers, all the time
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
+
+ # Scrub sensitive parameters from your log
+ filter_parameter_logging :password
+
+ WhiteListHelper.tags.merge %w(table tr td th div span)
+
+ #before_filter :set_configuration
+
+ include AuthenticatedSystem
+ before_filter :login_from_cookie
+ before_filter :oauth_required
+
+ include ActionView::Helpers::NumberHelper
+
+ def base_host
+ request.host_with_port
+ end
+
+
+ # if "referer" in the HTTP header contains "myexperiment", we know
+ # that current action was accessed from myExperiment website; if
+ # referer is not set OR doesn't contain the search string, access
+ # was initiated from other location
+ def accessed_from_website?
+ res = false
+
+ referer = request.env['HTTP_REFERER']
+ unless referer.nil? || referer.match("^#{Conf.base_uri}").nil?
+ res = true
+ end
+
+ return res
+ end
+
+ def set_configuration
+ Conf.set_configuration(request, session)
+ end
+
+ def formatted_timespan(time_period)
+ # Takes a period of time in seconds and returns it in human-readable form (down to minutes)
+ # from (http://www.postal-code.com/binarycode/category/devruby/)
+ out_str = ""
+
+ interval_array = [ [:weeks, 604800], [:days, 86400], [:hours, 3600], [:minutes, 60] ]
+ interval_array.each do |sub|
+ if time_period >= sub[1]
+ time_val, time_period = time_period.divmod(sub[1])
+
+ time_val == 1 ? name = sub[0].to_s.singularize : name = sub[0].to_s
+
+ ( sub[0] != :minutes ? out_str += ", " : out_str += " and " ) if out_str != ''
+ out_str += time_val.to_s + " #{name}"
+ end
+ end
+
+ return out_str
+ end
+
+
+ # this method is only intended to check if entry
+ # in "viewings" or "downloads" table needs to be
+ # created for current access - and this is *only*
+ # supposed to be working for *contributables*
+ #
+ # NB! The input parameter is the actual contributable OR
+ # the version of it (currently only workflows are versioned)
+ def allow_statistics_logging(contributable_or_version)
+
+ # check if the current viewing/download is to be logged
+ # (i.e. request is sent not by a bot and is legitimate)
+ allow_logging = true
+ Conf.bot_ignore_list.each do |pattern|
+ if request.env['HTTP_USER_AGENT'] and request.env['HTTP_USER_AGENT'].match(pattern)
+ allow_logging = false
+ break
+ end
+ end
+
+ # disallow logging of events referring to contributables / versions of them
+ # that have been uploaded by current user;
+ #
+ # however, if there are newer versions of contributable (uploaded not by the original uploader),
+ # we do want to record viewings/downloads of this newer version by the original uploader
+ if allow_logging && current_user != 0
+ allow_logging = false if (contributable_or_version.contributor_type == "User" && contributable_or_version.contributor_id == current_user.id)
+ end
+
+ return allow_logging
+ end
+
+
+ # Safe HTML - http://www.anyexample.com/webdev/rails/how_to_allow_some_safe_html_in_rails_projects.xml
+ # Note: should only be used for text that doesn't need updating later.
+ def ae_some_html(s)
+ return '' if s.nil?
+
+ # converting newlines
+ s.gsub!(/\r\n?/, "\n")
+
+ # escaping HTML to entities
+ s = s.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>')
+
+ # blockquote tag support
+ s.gsub!(/\n?<blockquote>\n*(.+?)\n*<\/blockquote>/im, "<blockquote>\\1</blockquote>")
+
+ # other tags: b, i, em, strong, u
+ %w(b i em strong u).each { |x|
+ s.gsub!(Regexp.new('<(' + x + ')>(.+?)</('+x+')>',
+ Regexp::MULTILINE|Regexp::IGNORECASE),
+ "<\\1>\\2</\\1>")
+ }
+
+ # A tag support
+ # href="" attribute auto-adds http://
+ s = s.gsub(/<a.+?href\s*=\s*['"](.+?)["'].*?>(.+?)<\/a>/im) { |x|
+ '<a href="" + ($1.index('://') ? $1 : 'http://'+$1) + "\">" + $2 + "</a>"
+ }
+
+ # replacing newlines to <br> ans <p> tags
+ # wrapping text into paragraph
+ s = "<p>" + s.gsub(/\n\n+/, "</p>\n\n<p>").
+ gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') + "</p>"
+
+ s
+ end
+
+ # This method takes a comma seperated list of tags (where multiple words don't need to be in quote marks)
+ # and formats it into a new comma seperated list where multiple words ARE in quote marks.
+ # (Note: it will actually put quote marks around all the words and then out commas).
+ # eg:
+ # this, is a, tag
+ # becomes:
+ # "this","is a","tag"
+ #
+ # This is so we can map the tags entered in by users to the format required by the act_as_taggable_redux gem.
+ def convert_tags_to_gem_format(tags_string)
+ list = parse_comma_seperated_string(tags_string)
+ converted = ''
+
+ list.each do |s|
+ converted = converted + '"' + s.strip + '",'
+ end
+
+ return converted
+ end
+
+ helper_method :ae_some_html
+
+ # This method converts a comma seperated string of values into a collection of those values.
+ # Note: currently does not cater for values in quotation marks and does not remove empty values
+ # (although it does ignore a trailing comma)
+ def parse_comma_seperated_string(s)
+ list = s.split(',')
+ end
+
+ def update_policy(contributable, params)
+
+ # this method will return an error message is something goes wrong (empty string in case of success)
+ error_msg = ""
+
+
+ # BEGIN validation and initialisation
+
+ # This variable will hold current settings of the policy in case something
+ # goes wrong and a revert would be needed at some point
+ last_saved_policy = nil
+
+ return if params[:sharing].nil? or params[:sharing][:class_id].blank?
+
+ sharing_class = params[:sharing][:class_id]
+ updating_class = (params[:updating] and !params[:updating][:class_id].blank?) ? params[:updating][:class_id] : "6"
+
+ # Check allowed sharing_class values
+ return unless [ "0", "1", "2", "3", "4", "7" ].include? sharing_class
+
+ # Check allowed updating_class values
+ return unless [ "0", "1", "5", "6" ].include? updating_class
+
+ view_protected = 0
+ view_public = 0
+ download_protected = 0
+ download_public = 0
+ edit_protected = 0
+ edit_public = 0
+
+ # BEGIN initialisation and validation
+
+ unless contributable.contribution.policy
+ last_saved_policy = Policy._default(current_user, nil) # second parameter ensures that this policy is not applied anywhere
+
+ policy = Policy.new(:name => 'auto',
+ :contributor_type => 'User', :contributor_id => current_user.id,
+ :share_mode => sharing_class,
+ :update_mode => updating_class)
+ contributable.contribution.policy = policy # by doing this the new policy object is saved implicitly too
+ contributable.contribution.save
+ else
+ policy = contributable.contribution.policy
+ last_saved_policy = policy.clone # clone required, not 'dup' (which still works through reference, so the values in both get changed anyway - which is not what's needed here)
+
+ policy.share_mode = sharing_class
+ policy.update_mode = updating_class
+ policy.save
+ end
+
+
+ # Process 'update' permissions for "Some of my Friends"
+
+ if updating_class == "5"
+ if params[:updating_somefriends]
+ # Delete old User permissions
+ policy.delete_all_user_permissions
+
+ # Now create new User permissions, if required
+ params[:updating_somefriends].each do |f|
+ Permission.new(:policy => policy,
+ :contributor => (User.find f[1].to_i),
+ :view => 1, :download => 1, :edit => 1).save
+ end
+ else # none of the 'some of my friends' were selected, error
+ # revert changes made to policy (however any permissions updated will preserve the state)
+ policy.copy_values_from( last_saved_policy )
+ policy.save
+ error_msg += "You have selected to set 'update' permissions for 'Some of your Friends', but didn't select any from the list.</br>Previous (if any) or default sharing permissions have been set."
+ return error_msg
+ end
+ else
+ # Delete all User permissions - as this isn't mode 5 (i.e. the mode has changed),
+ # where some explicit permissions to friends are set
+ policy.delete_all_user_permissions
+ end
+
+
+ # Process explicit Group permissions now
+ if params[:group_sharing]
+
+ # First delete any Permission objects that don't have a checked entry in the form
+ policy.permissions.each do |p|
+ params[:group_sharing].each do |n|
+ # If a hash value with key 'id' wasn't returned then that means the checkbox was unchecked.
+ unless n[1][:id]
+ if p.contributor_type == 'Network' and p.contributor_id == n[0].to_i
+ p.destroy
+ end
+ end
+ end
+ end
+
+ # Now create or update Permissions
+ params[:group_sharing].each do |n|
+
+ # Note: n[1] is used because n is an array and n[1] returns it's value (which in turn is a hash)
+ # In this hash, is a value with key 'id' is present then the checkbox for that group was checked.
+ if n[1][:id]
+
+ n_id = n[1][:id].to_i
+ level = n[1][:level]
+
+ unless (perm = Permission.find(:first, :conditions => ["policy_id = ? AND contributor_type = ? AND contributor_id = ?", policy.id, 'Network', n_id]))
+ # Only create new Permission if it doesn't already exist
+ p = Permission.new(:policy => policy, :contributor => (Network.find(n_id)))
+ p.set_level!(level) if level
+ else
+ # Update the 'level' on the existing permission
+ perm.set_level!(level) if level
+ end
+
+ else
+
+ n_id = n[0].to_i
+
+ # Delete permission if it exists (because this one is unchecked)
+ if (perm = Permission.find(:first, :conditions => ["policy_id = ? AND contributor_type = ? AND contributor_id = ?", policy.id, 'Network', n_id]))
+ perm.destroy
+ end
+
+ end
+
+ end
+ end
+
+ logger.debug("------ Workflow create summary ------------------------------------")
+ logger.debug("current_user = #{current_user.id}")
+ logger.debug("updating_class = #{updating_class}")
+ logger.debug("sharing_class = #{sharing_class}")
+ logger.debug("policy = #{policy}")
+ logger.debug("group_sharing = #{params[:group_sharing]}")
+ logger.debug("-------------------------------------------------------------------")
+
+ # returns some message in case of errors (or empty string in case of success)
+ return error_msg
+ end
+
+ def update_credits(creditable, params)
+
+ # First delete old creditations:
+ creditable.creditors.each do |c|
+ c.destroy
+ end
+
+ # Then create new creditations:
+
+ # Current user
+ if (params[:credits_me].downcase == 'true')
+ c = Creditation.new(:creditor_type => 'User', :creditor_id => current_user.id, :creditable_type => creditable.class.to_s, :creditable_id => creditable.id)
+ c.save
+ end
+
+ # Friends + other users
+ user_ids = parse_comma_seperated_string(params[:credits_users])
+ user_ids.each do |id|
+ c = Creditation.new(:creditor_type => 'User', :creditor_id => id, :creditable_type => creditable.class.to_s, :creditable_id => creditable.id)
+ c.save
+ end
+
+ # Networks (aka Groups)
+ network_ids = parse_comma_seperated_string(params[:credits_groups])
+ network_ids.each do |id|
+ c = Creditation.new(:creditor_type => 'Network', :creditor_id => id, :creditable_type => creditable.class.to_s, :creditable_id => creditable.id)
+ c.save
+ end
+
+ end
+
+ def update_attributions(attributable, params)
+
+ # First delete old attributions:
+ attributable.attributors.each do |a|
+ a.destroy
+ end
+
+ # Then create new attributions:
+
+ # Workflows
+ attributor_workflow_ids = parse_comma_seperated_string(params[:attributions_workflows])
+ attributor_type = 'Workflow'
+ attributor_workflow_ids.each do |id|
+ a = Attribution.new(:attributor_type => attributor_type, :attributor_id => id, :attributable_type => attributable.class.to_s, :attributable_id => attributable.id)
+ a.save
+ end
+
+ # Files
+ attributor_file_ids = parse_comma_seperated_string(params[:attributions_files])
+ attributor_type = 'Blob'
+ attributor_file_ids.each do |id|
+ a = Attribution.new(:attributor_type => attributor_type, :attributor_id => id, :attributable_type => attributable.class.to_s, :attributable_id => attributable.id)
+ a.save
+ end
+
+ end
+
+ # helper function to determine the context of a polymorphic nested resource
+
+ def extract_resource_context(params)
+ (Conf.contributor_models + Conf.contributable_models).each do |model_name|
+ id_param = "#{Conf.to_visible(model_name.underscore)}_id"
+ return Object.const_get(model_name).find_by_id(params[id_param]) if params[id_param]
+ end
+
+ nil
+ end
+
+ def deep_clone(ob)
+ case ob.class.name
+ when "Array"
+ ob.map do |x| deep_clone(x) end
+ when "Hash"
+ hash = {}
+ ob.each do |k, v| hash[deep_clone(k)] = deep_clone(v) end
+ hash
+ when "Symbol"
+ ob
+ else
+ ob.clone
+ end
+ end
+
+ def send_cached_data(file_name, *opts)
+
+ if !File.exists?(file_name)
+ FileUtils.mkdir_p(File.dirname(file_name))
+ File.open(file_name, "wb+") { |f| f.write(yield) }
+ end
+
+ send_file(file_name, *opts)
+ end
+
+ # Pivot code
+
+ def pivot_options
+ {
+ :order =>
+ [
+ {
+ :option => 'rank',
+ :label => 'Rank',
+ :order => 'contributions.rank DESC'
+ },
+
+ {
+ :option => 'title',
+ :label => 'Title',
+ :order => 'contributions.label, contributions.rank DESC'
+ },
+
+ {
+ :option => 'latest',
+ :label => 'Latest',
+ :order => 'contributions.created_at DESC, contributions.rank DESC'
+ },
+
+ {
+ :option => 'last_updated',
+ :label => 'Last updated',
+ :order => 'contributions.updated_at DESC, contributions.rank DESC'
+ },
+
+ {
+ :option => 'rating',
+ :label => 'Community rating',
+ :order => 'contributions.rating DESC, contributions.rank DESC'
+ },
+
+ {
+ :option => 'viewings',
+ :label => 'Most viewed',
+ :order => 'contributions.site_viewings_count DESC, contributions.rank DESC'
+ },
+
+ {
+ :option => 'downloads',
+ :label => 'Most downloaded',
+ :order => 'contributions.site_downloads_count DESC, contributions.rank DESC'
+ },
+
+ {
+ :option => 'type',
+ :label => 'Type',
+ :joins => [ :content_types ],
+ :order => 'content_types.title, contributions.rank DESC'
+ },
+
+ {
+ :option => 'licence',
+ :label => 'Licence',
+ :joins => [ :licences ],
+ :order => 'licenses.title, contributions.rank DESC'
+ },
+
+ {
+ :option => 'topic',
+ :label => 'Topic',
+ :joins => [ :topic_workflow_map ],
+ :order => 'topic_workflow_map.probability, rank DESC'
+ }
+ ],
+
+ :num_options => ['10', '20', '25', '50', '100'],
+
+ :filters =>
+ [
+ {
+ :title => 'category',
+ :query_option => 'CATEGORY',
+ :id_column => :auth_type,
+ :label_column => :auth_type,
+ :visible_name => true
+ },
+
+ {
+ :title => 'type',
+ :query_option => 'TYPE_ID',
+ :id_column => 'content_types.id',
+ :label_column => 'content_types.title',
+ :joins => [ :content_types ],
+ :not_null => true
+ },
+
+ {
+ :title => 'tag',
+ :query_option => 'TAG_ID',
+ :id_column => 'tags.id',
+ :label_column => 'tags.name',
+ :joins => [ :taggings, :tags ]
+ },
+
+ {
+ :title => 'user',
+ :query_option => 'USER_ID',
+ :id_column => 'users.id',
+ :label_column => 'users.name',
+ :joins => [ :users ]
+ },
+
+ {
+ :title => 'licence',
+ :query_option => 'LICENSE_ID',
+ :id_column => 'licenses.id',
+ :label_column => 'licenses.unique_name',
+ :joins => [ :licences ],
+ :not_null => true
+ },
+
+ {
+ :title => 'group',
+ :query_option => 'GROUP_ID',
+ :id_column => 'networks.id',
+ :label_column => 'networks.title',
+ :joins => [ :networks ]
+ },
+
+ {
+ :title => 'wsdl',
+ :query_option => 'WSDL_ENDPOINT',
+ :id_column => 'workflow_processors.wsdl',
+ :label_column => 'workflow_processors.wsdl',
+ :joins => [ :workflow_processors ],
+ :not_null => true
+ },
+
+ {
+ :title => 'curation',
+ :query_option => 'CURATION_EVENT',
+ :id_column => 'curation_events.category',
+ :label_column => 'curation_events.category',
+ :joins => [ :curation_events ],
+ :capitalize => true
+ },
+
+ {
+ :title => 'provider',
+ :query_option => 'SERVICE_PROVIDER',
+ :id_column => 'service_providers.id',
+ :label_column => 'service_providers.name',
+ :joins => [ :services, :service_providers ]
+ },
+
+ {
+ :title => 'country',
+ :query_option => 'SERVICE_COUNTRY',
+ :id_column => 'services.country',
+ :label_column => 'services.country',
+ :joins => [ :services ]
+ },
+
+ {
+ :title => 'service status',
+ :query_option => 'SERVICE_STATUS',
+ :id_column => 'services.monitor_label',
+ :label_column => 'services.monitor_label',
+ :joins => [ :services ]
+ },
+
+
+ ],
+
+ :joins =>
+ {
+ :content_types => "LEFT OUTER JOIN content_types ON contributions.content_type_id = content_types.id",
+ :licences => "LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id",
+ :users => "INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id",
+ :taggings => "LEFT OUTER JOIN taggings ON AUTH_TYPE = taggings.taggable_type AND AUTH_ID = taggings.taggable_id",
+ :tags => "INNER JOIN tags ON taggings.tag_id = tags.id",
+ :networks => "INNER JOIN networks ON permissions.contributor_type = 'Network' AND permissions.contributor_id = networks.id",
+ :credits => "INNER JOIN creditations ON creditations.creditable_type = AUTH_TYPE AND creditations.creditable_id = AUTH_ID",
+ :curation_events => "INNER JOIN curation_events ON curation_events.object_type = AUTH_TYPE AND curation_events.object_id = AUTH_ID",
+ :workflow_processors => "INNER JOIN workflow_processors ON AUTH_TYPE = 'Workflow' AND workflow_processors.workflow_id = AUTH_ID",
+ :search => "RIGHT OUTER JOIN search_results ON search_results.result_type = AUTH_TYPE AND search_results.result_id = AUTH_ID",
+ :topic_workflow_map => "INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id",
+ :services => "INNER JOIN services ON AUTH_TYPE = 'Service' AND AUTH_ID = services.id",
+ :service_providers => "INNER JOIN service_providers ON AUTH_TYPE = 'Service' AND service_providers.uri = services.provider_uri",
+ }
+ }
+ end
+
+ TOKEN_UNKNOWN = 0x0000
+ TOKEN_AND = 0x0001
+ TOKEN_OR = 0x0002
+ TOKEN_WORD = 0x0003
+ TOKEN_OPEN = 0x0004
+ TOKEN_CLOSE = 0x0005
+ TOKEN_STRING = 0x0006
+ TOKEN_EOS = 0x00ff
+
+ NUM_TOKENS = 6
+
+ STATE_INITIAL = 0x0000
+ STATE_EXPECT_OPEN = 0x0100
+ STATE_EXPECT_STR = 0x0200
+ STATE_EXPECT_EXPR_END = 0x0300
+ STATE_EXPECT_END = 0x0400
+ STATE_COMPLETE = 0x0500
+
+ def parse_filter_expression(expr)
+
+ def unescape_string(str)
+ str.match(/^"(.*)"$/)[1].gsub(/\\"/, '"')
+ end
+
+ state = STATE_INITIAL
+ data = ""
+
+ begin
+
+ tokens = expr.match(/^
+
+ \s* (\sAND\s) | # AND operator
+ \s* (\sOR\s) | # OR operator
+ \s* (\w+) | # a non-keyword word
+ \s* (\() | # an open paranthesis
+ \s* (\)) | # a close paranthesis
+ \s* ("(\\.|[^\\"])*") # double quoted string with backslash escapes
+
+ /ix)
+
+ if tokens.nil?
+ token = TOKEN_UNKNOWN
+ else
+ (1..NUM_TOKENS).each do |i|
+ token = i if tokens[i]
+ end
+ end
+
+ if token == TOKEN_UNKNOWN
+ token = TOKEN_EOS if expr.strip.empty?
+ end
+
+ case state | token
+ when STATE_INITIAL | TOKEN_WORD : state = STATE_EXPECT_OPEN ; data << { :name => tokens[0], :expr => [] }
+ when STATE_EXPECT_OPEN | TOKEN_OPEN : state = STATE_EXPECT_STR
+ when STATE_EXPECT_STR | TOKEN_STRING : state = STATE_EXPECT_EXPR_END ; data.last[:expr] << tokens[0]
+ when STATE_EXPECT_EXPR_END | TOKEN_AND : state = STATE_EXPECT_STR ; data.last[:expr] << :and
+ when STATE_EXPECT_EXPR_END | TOKEN_OR : state = STATE_EXPECT_STR ; data.last[:expr] << :or
+ when STATE_EXPECT_EXPR_END | TOKEN_CLOSE : state = STATE_EXPECT_END
+ when STATE_EXPECT_END | TOKEN_AND : state = STATE_INITIAL ; data << :and
+ when STATE_EXPECT_END | TOKEN_OR : state = STATE_INITIAL ; data << :or
+ when STATE_EXPECT_END | TOKEN_EOS : state = STATE_COMPLETE
+
+ else raise "Error parsing query _expression_"
+ end
+
+ expr = tokens.post_match unless state == STATE_COMPLETE
+
+ end while state != STATE_COMPLETE
+
+ # validate and reduce expressions to current capabilities
+
+ valid_filters = pivot_options[:filters].map do |f| f[:query_option] end
+
+ data.each do |category|
+ case category
+ when :or
+ raise "Unsupported query _expression_"
+ when :and
+ # Fine
+ else
+ raise "Unknown filter category" unless valid_filters.include?(category[:name])
+
+ counts = { :and => 0, :or => 0 }
+
+ category[:expr].each do |bit|
+ counts[bit] = counts[bit] + 1 if bit.class == Symbol
+ end
+
+ raise "Unsupported query _expression_" if counts[:and] > 0 && counts[:or] > 0
+
+ # haven't implemented 'and' within a particular filter yet
+ raise "Unsupported query _expression_" if counts[:and] > 0
+
+ if category[:expr].length == 1
+ category[:expr] = { :terms => [unescape_string(category[:expr].first)] }
+ else
+ category[:expr] = {
+ :operator => category[:expr][1],
+ :terms => category[:expr].select do |t|
+ t.class == String
+ end.map do |t|
+ unescape_string(t)
+ end
+ }
+ end
+ end
+ end
+
+ data
+ end
+
+ def contributions_list(klass = nil, params = nil, user = nil, opts = {})
+
+ def escape_sql(str)
+ str.gsub(/\\/, '\&\&').gsub(/'/, "''")
+ end
+
+ def build_url(params, opts, expr, parts, extra = {})
+
+ query = {}
+
+ if parts.include?(:filter)
+ bits = []
+ pivot_options[:filters].each do |filter|
+ if !opts[:lock_filter] || opts[:lock_filter][filter[:query_option]].nil?
+ if find_filter(expr, filter[:query_option])
+ bits << filter[:query_option] + "(\"" + find_filter(expr, filter[:query_option])[:expr][:terms].map do |t| t.gsub(/"/, '\"') end.join("\" OR \"") + "\")"
+ end
+ end
+ end
+
+ if bits.length > 0
+ query["filter"] = bits.join(" AND ")
+ end
+ end
+
+ query["query"] = params[:query] if params[:query]
+ query["order"] = params[:order] if parts.include?(:order)
+ query["filter_query"] = params[:filter_query] if parts.include?(:filter_query)
+
+ query.merge!(extra)
+
+ query
+ end
+
+ def comparison(lhs, rhs)
+ if rhs.length == 1
+ "#{lhs} = '#{escape_sql(rhs.first)}'"
+ else
+ "#{lhs} IN ('#{rhs.map do |bit| escape_sql(bit) end.join("', '")}')"
+ end
+ end
+
+ def create_search_results_table(search_query, models)
+
+ begin
+ solr_results = models.first.multi_solr_search(search_query,
+ :models => models,
+ :results_format => :ids,
+ :limit => Conf.max_search_size)
+ rescue
+ return false
+ end
+
+ conn = ActiveRecord::Base.connection
+
+ conn.execute("CREATE TEMPORARY TABLE search_results (id INT AUTO_INCREMENT UNIQUE KEY, result_type VARCHAR(255), result_id INT)")
+
+ # This next part converts the search results to SQL values
+ #
+ # from: { "id" => "Workflow:4" }, { "id" => "Pack:6" }, ...
+ # to: "(NULL, 'Workflow', '4'), (NULL, 'Pack', '6'), ..."
+
+ if solr_results.results.length > 0
+ insert_part = solr_results.results.map do |result|
+ "(NULL, " + result["id"].split(":").map do |bit|
+ "'#{bit}'"
+ end.join(", ") + ")"
+ end.join(", ")
+
+ conn.execute("INSERT INTO search_results VALUES #{insert_part}")
+ end
+
+ true
+ end
+
+ def drop_search_results_table
+ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS search_results")
+ end
+
+ def calculate_having_clause(filter, opts)
+
+ having_bits = []
+
+ pivot_options[:filters].each do |f|
+ if f != filter
+# if opts[:filters][f[:query_option]] && opts[:filters]["and_#{f[:query_option]}"] == "yes"
+# having_bits << "(GROUP_CONCAT(DISTINCT #{f[:id_column]} ORDER BY #{f[:id_column]}) = '#{escape_sql(opts[:filters][f[:query_option]])}')"
+# end
+ end
+ end
+
+ return nil if having_bits.empty?
+
+ "HAVING " + having_bits.join(" OR ")
+ end
+
+ def column(column, opts)
+ if column == :auth_type
+ if opts[:auth_type]
+ opts[:auth_type]
+ else
+ "contributions.contributable_type"
+ end
+ else
+ column
+ end
+ end
+
+ def calculate_filter(params, filter, user, opts = {})
+
+ # apply all the joins and conditions except for the current filter
+
+ joins = []
+ conditions = []
+
+ pivot_options[:filters].each do |other_filter|
+ if filter_list = find_filter(opts[:filters], other_filter[:query_option])
+ unless opts[:inhibit_other_conditions]
+ conditions << comparison(column(other_filter[:id_column], opts), filter_list[:expr][:terms]) unless other_filter == filter
+ end
+ joins += other_filter[:joins] if other_filter[:joins]
+ end
+ end
+
+ filter_id_column = column(filter[:id_column], opts)
+ filter_label_column = column(filter[:label_column], opts)
+
+ joins += filter[:joins] if filter[:joins]
+ conditions << "#{filter_id_column} IS NOT NULL" if filter[:not_null]
+
+ unless opts[:inhibit_filter_query]
+ if params[:filter_query]
+ conditions << "(#{filter_label_column} LIKE '%#{escape_sql(params[:filter_query])}%')"
+ end
+ end
+
+ joins.push(:search) if params[:query] && !opts[:arbitrary_models]
+
+ current = find_filter(opts[:filters], filter[:query_option]) ? find_filter(opts[:filters], filter[:query_option])[:expr][:terms] : []
+
+ if opts[:ids].nil?
+ limit = 10
+ else
+ conditions << "(#{filter_id_column} IN ('#{opts[:ids].map do |id| escape_sql(id) end.join("','")}'))"
+ limit = nil
+ end
+
+ conditions = conditions.length.zero? ? nil : conditions.join(" AND ")
+
+ if opts[:auth_type] && opts[:auth_id]
+ count_expr = "COUNT(DISTINCT #{opts[:auth_type]}, #{opts[:auth_id]})"
+ else
+ count_expr = "COUNT(DISTINCT contributions.contributable_type, contributions.contributable_id)"
+ end
+
+ objects = Authorization.authorised_index(params[:query] && opts[:arbitrary_models] ? SearchResult : Contribution,
+ :all,
+ :include_permissions => true,
+ :select => "#{filter_id_column} AS filter_id, #{filter_label_column} AS filter_label, #{count_expr} AS filter_count",
+ :arbitrary_models => opts[:arbitrary_models],
+ :auth_type => opts[:auth_type],
+ :auth_id => opts[:auth_id],
+ :joins => merge_joins(joins, :auth_type => opts[:auth_type], :auth_id => opts[:auth_id]),
+ :conditions => conditions,
+ :group => "#{filter_id_column} #{calculate_having_clause(filter, opts)}",
+ :limit => limit,
+ :order => "#{count_expr} DESC, #{filter_label_column}",
+ :authorised_user => user)
+
+ objects = objects.select do |x| !x[:filter_id].nil? end
+
+ objects = objects.map do |object|
+
+ value = object.filter_id.to_s
+ selected = current.include?(value)
+
+ label_expr = deep_clone(opts[:filters])
+ label_expr -= [find_filter(label_expr, filter[:query_option])] if find_filter(label_expr, filter[:query_option])
+
+ unless selected && current.length == 1
+ label_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
+ end
+
+ checkbox_expr = deep_clone(opts[:filters])
+
+ if expr_filter = find_filter(checkbox_expr, filter[:query_option])
+
+ if selected
+ expr_filter[:expr][:terms] -= [value]
+ else
+ expr_filter[:expr][:terms] += [value]
+ end
+
+ checkbox_expr -= [expr_filter] if expr_filter[:expr][:terms].empty?
+
+ else
+ checkbox_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
+ end
+
+ label_uri = build_url(params, opts, label_expr, [:filter, :order], "page" => nil)
+
+ checkbox_uri = build_url(params, opts, checkbox_expr, [:filter, :order], "page" => nil)
+
+ label = object.filter_label.clone
+ label = visible_name(label) if filter[:visible_name]
+ label = label.capitalize if filter[:capitalize]
+
+ plain_label = object.filter_label
+
+ if params[:filter_query]
+ label.sub!(Regexp.new("(#{params[:filter_query]})", Regexp::IGNORECASE), '<b>\1</b>')
+ end
+
+ {
+ :object => object,
+ :value => value,
+ :label => label,
+ :plain_label => plain_label,
+ :count => object.filter_count,
+ :checkbox_uri => checkbox_uri,
+ :label_uri => label_uri,
+ :selected => selected
+ }
+ end
+
+ [current, objects]
+ end
+
+ def calculate_filters(params, opts, user)
+
+ # produce the filter list
+
+ filters = pivot_options[:filters].clone
+ cancel_filter_query_url = nil
+
+ filters.each do |filter|
+
+ # calculate the top n items of the list
+
+ filter[:current], filter[:objects] = calculate_filter(params, filter, user, opts)
+
+ # calculate which active filters are missing (because they weren't in the
+ # top part of the list or have a count of zero)
+
+ missing_filter_ids = filter[:current] - filter[:objects].map do |ob| ob[:value] end
+
+ if missing_filter_ids.length > 0
+ filter[:objects] += calculate_filter(params, filter, user, opts.merge(:ids => missing_filter_ids))[1]
+ end
+
+ # calculate which active filters are still missing (because they have a
+ # count of zero)
+
+ missing_filter_ids = filter[:current] - filter[:objects].map do |ob| ob[:value] end
+
+ if missing_filter_ids.length > 0
+ zero_list = calculate_filter(params, filter, user, opts.merge(:ids => missing_filter_ids, :inhibit_other_conditions => true))[1]
+
+ zero_list.each do |x| x[:count] = 0 end
+
+ zero_list.sort! do |a, b| a[:label] <=> b[:label] end
+
+ filter[:objects] += zero_list
+ end
+ end
+
+ [filters, cancel_filter_query_url]
+ end
+
+ def find_filter(filters, name)
+ filters.find do |f|
+ f[:name] == name
+ end
+ end
+
+ def merge_joins(joins, opts = {})
+
+ opts[:auth_type] ||= 'contributions.contributable_type'
+ opts[:auth_id] ||= 'contributions.contributable_id'
+
+ if joins.length.zero?
+ nil
+ else
+ joins.uniq.map do |j|
+ text = pivot_options[:joins][j]
+ text.gsub!(/AUTH_TYPE/, opts[:auth_type])
+ text.gsub!(/AUTH_ID/, opts[:auth_id])
+ text
+ end.join(" ")
+ end
+ end
+
+ joins = []
+ conditions = []
+
+ # parse the filter _expression_ if provided. convert filter _expression_ to
+ # the old format. this will need to be replaced eventually
+
+ opts[:filters] ||= []
+
+ include_reset_url = opts[:filters].length > 0
+
+ # filter out top level logic operators for now
+
+ opts[:filters] = opts[:filters].select do |bit|
+ bit.class == Hash
+ end
+
+ # apply locked filters
+
+ if opts[:lock_filter]
+ opts[:lock_filter].each do |filter, value|
+ opts[:filters] << { :name => filter, :expr => { :terms => [value] } }
+ end
+ end
+
+ # perform search if requested
+
+ group_by = "contributions.contributable_type, contributions.contributable_id"
+
+ query_problem = false
+
+ if params["query"]
+ drop_search_results_table
+ if create_search_results_table(params["query"], [Workflow, Blob, Pack, User, Network, Service])
+ joins.push(:search) unless opts[:arbitrary_models]
+ else
+ params["query"] = nil
+ query_problem = true
+ end
+ end
+
+ if opts[:arbitrary_models] && params[:query]
+ klass = SearchResult
+ contribution_records = false
+ auth_type = "search_results.result_type"
+ auth_id = "search_results.result_id"
+ group_by = "search_results.result_type, search_results.result_id"
+ else
+ contribution_records = true
+ end
+
+ # determine joins, conditions and order for the main results
+
+ pivot_options[:filters].each do |filter|
+ if filter_list = find_filter(opts[:filters], filter[:query_option])
+ conditions << comparison(column(filter[:id_column], opts.merge( { :auth_type => auth_type, :auth_id => auth_id } )), filter_list[:expr][:terms])
+ joins += filter[:joins] if filter[:joins]
+ end
+ end
+
+ order_options = pivot_options[:order].find do |x|
+ x[:option] == params[:order]
+ end
+
+ order_options ||= pivot_options[:order].first
+
+ joins += order_options[:joins] if order_options[:joins]
+
+ having_bits = []
+
+# pivot_options[:filters].each do |filter|
+# if params["and_#{filter[:query_option]}"]
+# having_bits << "GROUP_CONCAT(DISTINCT #{filter[:id_column]} ORDER BY #{filter[:id_column]}) = \"#{escape_sql(opts[:filters][filter[:query_option]])}\""
+# end
+# end
+
+ having_clause = ""
+
+ if having_bits.length > 0
+ having_clause = "HAVING #{having_bits.join(' AND ')}"
+ end
+
+ # perform the results query
+
+ results = Authorization.authorised_index(klass,
+ :all,
+ :authorised_user => user,
+ :include_permissions => true,
+ :contribution_records => contribution_records,
+ :arbitrary_models => opts[:arbitrary_models],
+ :auth_type => auth_type,
+ :auth_id => auth_id,
+ :page => { :size => params["num"] ? params["num"].to_i : nil, :current => params["page"] },
+ :joins => merge_joins(joins, :auth_type => auth_type, :auth_id => auth_id),
+ :conditions => conditions.length.zero? ? nil : conditions.join(" AND "),
+ :group => "#{group_by} #{having_clause}",
+ :order => order_options[:order])
+
+ # produce a query hash to match the current filters
+
+ opts[:filter_params] = {}
+
+ pivot_options[:filters].each do |filter|
+ if params[filter[:query_option]]
+ next if opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
+ opts[:filter_params][filter[:query_option]] = params[filter[:query_option]]
+ end
+ end
+
+ # produce the filter list
+
+ opts_for_filter_query = opts.merge( { :auth_type => auth_type,
+ :auth_id => auth_id, :group_by => group_by } )
+
+ filters, cancel_filter_query_url = calculate_filters(params, opts_for_filter_query, user)
+
+ # produce the summary. If a filter query is specified, then we need to
+ # recalculate the filters without the query to get all of them.
+
+ if params[:filter_query]
+ filters2 = calculate_filters(params, opts_for_filter_query.merge( { :inhibit_filter_query => true } ), user)[0]
+ else
+ filters2 = filters
+ end
+
+ summary = ""
+
+ filters2.select do |filter|
+
+ next if opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
+
+ selected = filter[:objects].select do |x| x[:selected] end
+ current = selected.map do |x| x[:value] end
+
+ if selected.length > 0
+ selected_labels = selected.map do |x|
+
+ expr = deep_clone(opts[:filters])
+
+ f = find_filter(expr, filter[:query_option])
+
+ expr -= f[:expr][:terms] -= [x[:value]]
+ expr -= [f] if f[:expr][:terms].empty?
+
+ x[:plain_label] + ' <a href="" + url_for(build_url(params, opts, expr,
+ [:filter, :filter_query, :order])) +
+ '">' + " <img src='' /></a>"
+
+ end
+
+ bits = selected_labels.map do |label| label end.join(" <i>or</i> ")
+
+ summary << '<span class="filter-in-use"><b>' + filter[:title].capitalize + "</b>: " + bits + "</span> "
+ end
+ end
+
+ if params[:filter_query]
+ cancel_filter_query_url = build_url(params, opts, opts[:filters], [:filter, :order])
+ end
+
+ if include_reset_url
+ reset_filters_url = build_url(params, opts, opts[:filters], [:order])
+ end
+
+ # remove filters that do not help in narrowing down the result set
+
+ filters = filters.select do |filter|
+ if filter[:objects].empty?
+ false
+ elsif opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
+ false
+ else
+ true
+ end
+ end
+
+ {
+ :results => results,
+ :filters => filters,
+ :reset_filters_url => reset_filters_url,
+ :cancel_filter_query_url => cancel_filter_query_url,
+ :filter_query_url => build_url(params, opts, opts[:filters], [:filter]),
+ :summary => summary,
+ :query_problem => query_problem
+ }
+ end
+
+ #Applies the layout for the Network with the given network_id to the object (contributable)
+ def update_layout(object,network_id)
+ if network_id.blank?
+ object.contribution.layout = nil
+ object.contribution.save
+ else
+ network = Network.find(network_id.to_i)
+ # Have to call .reload on permissions or the cached permissions from before "update_policy" was called are used
+ if network && find_permission_for_contributor(object.contribution.policy.permissions.reload, "Network", network_id.to_i)
+ object.contribution.layout = network.layout_name
+ object.contribution.save
+ else
+ object.errors.add_to_base("You may only choose layouts for groups that this #{object.class.name.downcase} is shared with.")
+ end
+ end
+
+ end
+end
Modified: branches/datasets/app/controllers/blobs_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/blobs_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/blobs_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -88,9 +88,9 @@
format.html {
@lod_nir = file_url(@blob)
- @lod_html = formatted_file_url(:id => @blob.id, :format => 'html')
- @lod_rdf = formatted_file_url(:id => @blob.id, :format => 'rdf')
- @lod_xml = formatted_file_url(:id => @blob.id, :format => 'xml')
+ @lod_html = file_url(:id => @blob.id, :format => 'html')
+ @lod_rdf = file_url(:id => @blob.id, :format => 'rdf')
+ @lod_xml = file_url(:id => @blob.id, :format => 'xml')
# show.rhtml
}
@@ -309,14 +309,12 @@
else
if logged_in?
error("File not found (id not authorized)", "is invalid (not authorized)")
- return false
else
find_blob_auth if login_required
end
end
rescue ActiveRecord::RecordNotFound
error("File not found", "is invalid")
- return false
end
end
Modified: branches/datasets/app/controllers/citations_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/citations_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/citations_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -100,7 +100,6 @@
end
rescue ActiveRecord::RecordNotFound
error("Workflow not found", "is invalid")
- return false
end
end
Modified: branches/datasets/app/controllers/comments_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/comments_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/comments_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -69,16 +69,20 @@
@context = extract_resource_context(params)
@comment = Comment.find_by_id(params[:id])
- return false if @comment.nil? || @context.nil? || @comment.commentable != @context
- return false if Authorization.is_authorized?('view', nil, @context, current_user) == false
+ return error if @comment.nil? || @context.nil? || @comment.commentable != @context
+ return error if Authorization.is_authorized?('view', nil, @context, current_user) == false
end
def find_resource_context
@context = extract_resource_context(params)
- return false if @context.nil?
- return false if Authorization.is_authorized?('view', nil, @context, current_user) == false
+ return error if @context.nil?
+ return error if Authorization.is_authorized?('view', nil, @context, current_user) == false
end
+
+ def error
+ render :text => 'Error.'
+ end
end
Modified: branches/datasets/app/controllers/content_types_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/content_types_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/content_types_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -27,9 +27,9 @@
format.html {
@lod_nir = content_type_url(@content_type)
- @lod_html = formatted_content_type_url(:id => @content_type.id, :format => 'html')
- @lod_rdf = formatted_content_type_url(:id => @content_type.id, :format => 'rdf')
- @lod_xml = formatted_content_type_url(:id => @content_type.id, :format => 'xml')
+ @lod_html = content_type_url(:id => @content_type.id, :format => 'html')
+ @lod_rdf = content_type_url(:id => @content_type.id, :format => 'rdf')
+ @lod_xml = content_type_url(:id => @content_type.id, :format => 'xml')
# show.rhtml
}
@@ -74,7 +74,6 @@
if @content_type.nil?
error("Content type not found", "is invalid")
- return false
end
end
Modified: branches/datasets/app/controllers/contributions_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/contributions_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/contributions_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -25,18 +25,20 @@
@contributable = Object.const_get(klass_name).find_by_id(params[:contributable_id])
# Abort if the contributable does not exist
- return false if @contributable.nil?
+ return error if @contributable.nil?
# Abort if we're not allowed to see this contributable
- return false unless Authorization.check(:action ="" 'view', :object => @contributable, :user => current_user)
+ return error unless Authorization.check(:action ="" 'view', :object => @contributable, :user => current_user)
rescue
# In case the const_get doesn't find anything
- return false
+ return error
end
+ end
- return true
+ def error
+ render :text => 'Error.'
end
end
Modified: branches/datasets/app/controllers/experiments_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/experiments_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/experiments_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -21,9 +21,9 @@
format.html {
@lod_nir = experiment_url(@experiment)
- @lod_html = formatted_experiment_url(:id => @experiment.id, :format => 'html')
- @lod_rdf = formatted_experiment_url(:id => @experiment.id, :format => 'rdf')
- @lod_xml = formatted_experiment_url(:id => @experiment.id, :format => 'xml')
+ @lod_html = experiment_url(:id => @experiment.id, :format => 'html')
+ @lod_rdf = experiment_url(:id => @experiment.id, :format => 'rdf')
+ @lod_xml = experiment_url(:id => @experiment.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/friendships_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/friendships_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/friendships_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -41,7 +41,7 @@
respond_to do |format|
if @friendship.accept!
flash[:notice] = 'Friendship was successfully accepted.'
- format.html { redirect_to friendships_url(current_user.id) }
+ format.html { redirect_to user_friendships_url(current_user.id) }
else
error("Friendship already accepted", "already accepted")
end
@@ -128,7 +128,7 @@
respond_to do |format|
if @friendship.update_attributes(params[:friendship])
flash[:notice] = 'Friendship was successfully updated.'
- format.html { redirect_to friendship_url(@friendship.user_id, @friendship) }
+ format.html { redirect_to user_friendship_url(@friendship.user_id, @friendship) }
else
format.html { render :action ="" "edit" }
end
@@ -185,8 +185,7 @@
def check_user_present
if params[:user_id].blank?
flash.now[:error] = "Invalid URL"
- redirect_to friendships_url(current_user.id)
- return false
+ redirect_to user_friendships_url(current_user.id)
end
end
@@ -269,7 +268,7 @@
(err = Friendship.new.errors).add(:id, message)
respond_to do |format|
- format.html { redirect_to friendships_url(current_user.id) }
+ format.html { redirect_to user_friendships_url(current_user.id) }
end
end
end
Modified: branches/datasets/app/controllers/group_announcements_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/group_announcements_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/group_announcements_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -20,7 +20,7 @@
respond_to do |format|
format.html # index.rhtml
format.rss do
- render :action ="" 'index.rxml', :layout => false
+ render :action ="" 'feed.rxml', :layout => false
end
end
end
@@ -31,9 +31,9 @@
format.html {
@lod_nir = group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id)
- @lod_html = formatted_group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id, :format => 'html')
- @lod_rdf = formatted_group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id, :format => 'rdf')
- @lod_xml = formatted_group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id, :format => 'xml')
+ @lod_html = group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id, :format => 'html')
+ @lod_rdf = group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id, :format => 'rdf')
+ @lod_xml = group_announcement_url(:id => @announcement.id, :group_id => @announcement.network_id, :format => 'xml')
# show.rhtml
}
@@ -103,7 +103,6 @@
@group = Network.find(params[:group_id])
rescue ActiveRecord::RecordNotFound
error("Group couldn't be found")
- return false
end
end
@@ -111,7 +110,6 @@
def check_admin
unless @group.administrator?(current_user.id)
error("Only group administrators are allowed to create new announcements")
- return false
end
end
Modified: branches/datasets/app/controllers/jobs_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/jobs_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/jobs_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -41,9 +41,9 @@
format.html {
@lod_nir = experiment_job_url(:id => @job.id, :experiment_id => @experiment.id)
- @lod_html = formatted_experiment_job_url(:id => @job.id, :experiment_id => @experiment.id, :format => 'html')
- @lod_rdf = formatted_experiment_job_url(:id => @job.id, :experiment_id => @experiment.id, :format => 'rdf')
- @lod_xml = formatted_experiment_job_url(:id => @job.id, :experiment_id => @experiment.id, :format => 'xml')
+ @lod_html = experiment_job_url(:id => @job.id, :experiment_id => @experiment.id, :format => 'html')
+ @lod_rdf = experiment_job_url(:id => @job.id, :experiment_id => @experiment.id, :format => 'rdf')
+ @lod_xml = experiment_job_url(:id => @job.id, :experiment_id => @experiment.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/licenses_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/licenses_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/licenses_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -16,9 +16,9 @@
format.html {
@lod_nir = license_url(@license)
- @lod_html = formatted_license_url(:id => @license.id, :format => 'html')
- @lod_rdf = formatted_license_url(:id => @license.id, :format => 'rdf')
- @lod_xml = formatted_license_url(:id => @license.id, :format => 'xml')
+ @lod_html = license_url(:id => @license.id, :format => 'html')
+ @lod_rdf = license_url(:id => @license.id, :format => 'rdf')
+ @lod_xml = license_url(:id => @license.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/memberships_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/memberships_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/memberships_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -104,9 +104,9 @@
format.html {
@lod_nir = user_membership_url(:id => @membership, :user_id => @membership.user_id)
- @lod_html = formatted_user_membership_url(:id => @membership.id, :user_id => @membership.user_id, :format => 'html')
- @lod_rdf = formatted_user_membership_url(:id => @membership.id, :user_id => @membership.user_id, :format => 'rdf')
- @lod_xml = formatted_user_membership_url(:id => @membership.id, :user_id => @membership.user_id, :format => 'xml')
+ @lod_html = user_membership_url(:id => @membership.id, :user_id => @membership.user_id, :format => 'html')
+ @lod_rdf = user_membership_url(:id => @membership.id, :user_id => @membership.user_id, :format => 'rdf')
+ @lod_xml = user_membership_url(:id => @membership.id, :user_id => @membership.user_id, :format => 'xml')
# show.rhtml
}
@@ -205,7 +205,7 @@
respond_to do |format|
if @membership.update_attributes(params[:membership])
flash[:notice] = 'Membership was successfully updated.'
- format.html { redirect_to membership_url(@membership.user_id, @membership) }
+ format.html { redirect_to user_membership_url(@membership.user_id, @membership) }
else
format.html { render :action ="" "edit" }
end
@@ -336,7 +336,6 @@
if params[:user_id].blank?
flash.now[:error] = "Invalid URL"
redirect_to user_memberships_url(current_user.id)
- return false
end
end
@@ -435,7 +434,7 @@
(err = Membership.new.errors).add(attr, message)
respond_to do |format|
- format.html { redirect_to memberships_url(current_user.id) }
+ format.html { redirect_to user_memberships_url(current_user.id) }
end
end
Modified: branches/datasets/app/controllers/messages_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/messages_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/messages_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -69,9 +69,9 @@
format.html {
@lod_nir = message_url(@message)
- @lod_html = formatted_message_url(:id => @message.id, :format => 'html')
- @lod_rdf = formatted_message_url(:id => @message.id, :format => 'rdf')
- @lod_xml = formatted_message_url(:id => @message.id, :format => 'xml')
+ @lod_html = message_url(:id => @message.id, :format => 'html')
+ @lod_rdf = message_url(:id => @message.id, :format => 'rdf')
+ @lod_xml = message_url(:id => @message.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/networks_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/networks_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/networks_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -335,9 +335,9 @@
format.html {
@lod_nir = group_url(@network)
- @lod_html = formatted_group_url(:id => @network.id, :format => 'html')
- @lod_rdf = formatted_group_url(:id => @network.id, :format => 'rdf')
- @lod_xml = formatted_group_url(:id => @network.id, :format => 'xml')
+ @lod_html = group_url(:id => @network.id, :format => 'html')
+ @lod_rdf = group_url(:id => @network.id, :format => 'rdf')
+ @lod_xml = group_url(:id => @network.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/oauth_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/oauth_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/oauth_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -172,11 +172,9 @@
@client_application = client_app
else
error("Client Application not found (id not authorized)", "is invalid (not authorized)")
- return false
end
rescue ActiveRecord::RecordNotFound
error("Client Application not found", "is invalid")
- return false
end
end
Modified: branches/datasets/app/controllers/packs_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/packs_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/packs_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -61,9 +61,9 @@
format.html {
@lod_nir = pack_url(@pack)
- @lod_html = formatted_pack_url(:id => @pack.id, :format => 'html')
- @lod_rdf = formatted_pack_url(:id => @pack.id, :format => 'rdf')
- @lod_xml = formatted_pack_url(:id => @pack.id, :format => 'xml')
+ @lod_html = pack_url(:id => @pack.id, :format => 'html')
+ @lod_rdf = pack_url(:id => @pack.id, :format => 'rdf')
+ @lod_xml = pack_url(:id => @pack.id, :format => 'xml')
# show.rhtml
}
@@ -427,11 +427,9 @@
@base_host = base_host
else
error("You are not authorised to perform this action", "is not authorized")
- return false
end
rescue ActiveRecord::RecordNotFound
error("Pack not found", "is invalid")
- return false
end
end
Modified: branches/datasets/app/controllers/previews_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/previews_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/previews_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -84,11 +84,14 @@
def find_context
@context = extract_resource_context(params)
- return false unless @context
+ return error unless @context
@context = @context.find_version(params[:version]) if params[:version]
- return false unless @context
+ return error unless @context
end
+ def error
+ render :text => 'Error.'
+ end
end
Modified: branches/datasets/app/controllers/redirects_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/redirects_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/redirects_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,11 +1,6 @@
class RedirectsController < ApplicationController
- # Antoon's survey
- def exercise
- redirect_to 'http://www.cs.man.ac.uk/~goderisa/exercise'
- end
-
# For Antoon
def google
redirect_to 'http://www.google.com/coop/cse?cx=006491099109873764573%3Ahtaex4vgqqg'
Modified: branches/datasets/app/controllers/relationships_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/relationships_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/relationships_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -68,8 +68,8 @@
@context = extract_resource_context(params)
@relationship = Relationship.find_by_id(params[:id])
- return false if @relationship.nil? || @context.nil? || @relationship.context != @context
- return false if Authorization.is_authorized?('view', nil, @context, current_user) == false
+ return error if @relationship.nil? || @context.nil? || @relationship.context != @context
+ return error if Authorization.is_authorized?('view', nil, @context, current_user) == false
end
def find_resource_context
@@ -80,5 +80,8 @@
return false if Authorization.is_authorized?('view', nil, @context, current_user) == false
end
+ def error
+ render :text => 'Error.'
+ end
end
Modified: branches/datasets/app/controllers/reviews_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/reviews_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/reviews_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -32,9 +32,9 @@
format.html {
@lod_nir = workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id)
- @lod_html = formatted_workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id, :format => 'html')
- @lod_rdf = formatted_workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id, :format => 'rdf')
- @lod_xml = formatted_workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id, :format => 'xml')
+ @lod_html = workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id, :format => 'html')
+ @lod_rdf = workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id, :format => 'rdf')
+ @lod_xml = workflow_review_url(:id => @review.id, :workflow_id => @reviewable.id, :format => 'xml')
# show.rhtml
}
@@ -135,14 +135,14 @@
else
if logged_in?
error("Workflow not found (id not authorized)", "is invalid (not authorized)")
- return false
+ return
else
login_required
end
end
rescue ActiveRecord::RecordNotFound
error("Workflow not found", "is invalid")
- return false
+ return
end
end
@@ -159,7 +159,7 @@
@review = review
else
error("Review not found", "is invalid")
- return false
+ return
end
end
@@ -168,7 +168,7 @@
@review = review
else
error("Review not found or action not authorized", "is invalid (not authorized)")
- return false
+ return
end
end
Modified: branches/datasets/app/controllers/runners_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/runners_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/runners_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -23,9 +23,9 @@
format.html {
@lod_nir = runner_url(@runner)
- @lod_html = formatted_runner_url(:id => @runner.id, :format => 'html')
- @lod_rdf = formatted_runner_url(:id => @runner.id, :format => 'rdf')
- @lod_xml = formatted_runner_url(:id => @runner.id, :format => 'xml')
+ @lod_html = runner_url(:id => @runner.id, :format => 'html')
+ @lod_rdf = runner_url(:id => @runner.id, :format => 'rdf')
+ @lod_xml = runner_url(:id => @runner.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/search_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/search_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/search_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -21,7 +21,7 @@
if !Conf.search_categories.include?(@type)
error(@type)
- return false
+ return
end
if Conf.model_aliases.key?(@type.camelize.singularize)
Modified: branches/datasets/app/controllers/services_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/services_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/services_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -85,7 +85,6 @@
rescue ActiveRecord::RecordNotFound
error("Service not found", "is invalid")
- return false
end
end
Deleted: branches/datasets/app/controllers/session_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/session_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/session_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,153 +0,0 @@
-# myExperiment: app/controllers/session_controller.rb
-#
-# Copyright (c) 2007 University of Manchester and the University of Southampton.
-# See license.txt for details.
-
-require 'uri'
-require 'openid'
-require 'openid/store/filesystem'
-
-class SessionController < ApplicationController
-
- # declare sweepers and which actions should invoke them
- cache_sweeper :user_sweeper, : [ :create ]
-
- # GET /session/new
- # new renders new.rhtml
-
- # POST /session
- def create
- # record return_to address if required
- session[:return_to] = request.env['HTTP_REFERER'] unless session[:return_to] and !session[:return_to].empty?
-
- if using_open_id?
- open_id_authentication
- else
- password_authentication
- end
- end
-
- # DELETE /session
- def destroy
- self.current_user.forget_me if logged_in?
- cookies.delete :auth_token
- reset_session # clears session[:return_to]
- #flash[:notice] = "You have been logged out. Thank you for using #{Conf.sitename}!"
- redirect_to ''
- end
-
- # handle the openid server response
- def complete
-
- current_url = url_for(:action ="" 'complete', : false)
- parameters = params.reject{|k,v|request.path_parameters[k]}
-
- response = consumer.complete(parameters, current_url)
-
- if response.class == OpenID::Consumer::FailureResponse
-
- if response.identity_url
- failed_login("Verification of \"#{response.identity_url}\" failed.")
- else
- failed_login("Verification failed.")
- end
-
- return
- end
-
- redirect_to_edit_user = false
-
- # create user object if one does not exist
- unless @user = User.find(:first, :conditions => ["openid_url = ?", response.identity_url])
- @user = User.new(:openid_url => response.identity_url, :name => response.identity_url, :activated_at => Time.now, :last_seen_at => Time.now)
- redirect_to_edit_user = @user.save
- end
-
- # storing both the openid_url and user id in the session for for quick
- # access to both bits of information. Change as needed.
- self.current_user = @user
-
- flash[:notice] = "Logged in as address@hidden"
-
- if redirect_to_edit_user == true
- redirect_to url_for(:controller => 'users', :action ="" 'edit', :id => self.current_user)
- else
- successful_login(self.current_user)
- end
- end
-
- protected
-
- def password_authentication
- if params[:session]
- login, password = params[:session][:username], params[:session][:password]
-
- self.current_user = User.authenticate(login, password)
- if logged_in?
- if params[:session][:remember_me] == "1"
- self.current_user.remember_me
- cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
- end
- successful_login(self.current_user)
- else
- failed_login('Invalid username or password')
- end
- else
- failed_login('Invalid request')
- end
- end
-
- def open_id_authentication
- openid_url = params[:openid_url]
-
- begin
- if request.post?
- request = consumer.begin(openid_url)
-
- return_to = url_for(:action="" 'complete')
- trust_root = url_for(:controller=>'')
-
- url = "" return_to)
- redirect_to(url)
- return
- end
- rescue OpenID::DiscoveryFailure
- failed_login("Couldn't locate the OpenID server. Please check your OpenID URL.")
- rescue RuntimeError, Timeout::Error => e
- if e.class == Timeout::Error
- failed_login("Could not contact your OpenID server.")
- else
- failed_login("An unknown error occurred. Please check your OpenID url and that you are connected to the internet.")
- end
- end
- end
-
- private
-
- def successful_login(user)
- # update "last seen" attribute
- user.update_attribute(:last_seen_at, Time.now)
- respond_to do |format|
- flash[:notice] = "Logged in successfully. Welcome to #{Conf.sitename}!"
- home_url = url_for(:controller => 'home')
- format.html { session[:return_to] and URI.parse(session[:return_to]).path == '/' ? redirect_to(home_url) : redirect_back_or_default(home_url) }
- end
- end
-
- def failed_login(message)
- respond_to do |format|
- flash.now[:error] = message
- format.html { render :action ="" 'new' }
- end
- end
-
- # Get the OpenID::Consumer object.
- def consumer
- # create the OpenID store for storing associations and nonces,
- # putting it in your app's db directory
- store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
- store = OpenID::Store::Filesystem.new(store_dir)
-
- return OpenID::Consumer.new(session, store)
- end
-end
Copied: branches/datasets/app/controllers/sessions_controller.rb (from rev 2857, trunk/app/controllers/sessions_controller.rb) (0 => 2858)
--- branches/datasets/app/controllers/sessions_controller.rb (rev 0)
+++ branches/datasets/app/controllers/sessions_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,153 @@
+# myExperiment: app/controllers/sessions_controller.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+require 'uri'
+require 'openid'
+require 'openid/store/filesystem'
+
+class SessionsController < ApplicationController
+
+ # declare sweepers and which actions should invoke them
+ cache_sweeper :user_sweeper, : [ :create ]
+
+ # GET /session/new
+ # new renders new.rhtml
+
+ # POST /session
+ def create
+ # record return_to address if required
+ session[:return_to] = request.env['HTTP_REFERER'] unless session[:return_to] and !session[:return_to].empty?
+
+ if using_open_id?
+ open_id_authentication
+ else
+ password_authentication
+ end
+ end
+
+ # DELETE /session
+ def destroy
+ self.current_user.forget_me if logged_in?
+ cookies.delete :auth_token
+ reset_session # clears session[:return_to]
+ #flash[:notice] = "You have been logged out. Thank you for using #{Conf.sitename}!"
+ redirect_to ''
+ end
+
+ # handle the openid server response
+ def complete
+
+ current_url = url_for(:action ="" 'complete', : false)
+ parameters = params.reject{|k,v|request.path_parameters[k]}
+
+ response = consumer.complete(parameters, current_url)
+
+ if response.class == OpenID::Consumer::FailureResponse
+
+ if response.identity_url
+ failed_login("Verification of \"#{response.identity_url}\" failed.")
+ else
+ failed_login("Verification failed.")
+ end
+
+ return
+ end
+
+ redirect_to_edit_user = false
+
+ # create user object if one does not exist
+ unless @user = User.find(:first, :conditions => ["openid_url = ?", response.identity_url])
+ @user = User.new(:openid_url => response.identity_url, :name => response.identity_url, :activated_at => Time.now, :last_seen_at => Time.now)
+ redirect_to_edit_user = @user.save
+ end
+
+ # storing both the openid_url and user id in the session for for quick
+ # access to both bits of information. Change as needed.
+ self.current_user = @user
+
+ flash[:notice] = "Logged in as address@hidden"
+
+ if redirect_to_edit_user == true
+ redirect_to url_for(:controller => 'users', :action ="" 'edit', :id => self.current_user)
+ else
+ successful_login(self.current_user)
+ end
+ end
+
+ protected
+
+ def password_authentication
+ if params[:session]
+ login, password = params[:session][:username], params[:session][:password]
+
+ self.current_user = User.authenticate(login, password)
+ if logged_in?
+ if params[:session][:remember_me] == "1"
+ self.current_user.remember_me
+ cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
+ end
+ successful_login(self.current_user)
+ else
+ failed_login('Invalid username or password')
+ end
+ else
+ failed_login('Invalid request')
+ end
+ end
+
+ def open_id_authentication
+ openid_url = params[:openid_url]
+
+ begin
+ if request.post?
+ request = consumer.begin(openid_url)
+
+ return_to = url_for(:action="" 'complete')
+ trust_root = url_for(:controller=>'')
+
+ url = "" return_to)
+ redirect_to(url)
+ return
+ end
+ rescue OpenID::DiscoveryFailure
+ failed_login("Couldn't locate the OpenID server. Please check your OpenID URL.")
+ rescue RuntimeError, Timeout::Error => e
+ if e.class == Timeout::Error
+ failed_login("Could not contact your OpenID server.")
+ else
+ failed_login("An unknown error occurred. Please check your OpenID url and that you are connected to the internet.")
+ end
+ end
+ end
+
+ private
+
+ def successful_login(user)
+ # update "last seen" attribute
+ user.update_attribute(:last_seen_at, Time.now)
+ respond_to do |format|
+ flash[:notice] = "Logged in successfully. Welcome to #{Conf.sitename}!"
+ home_url = url_for(:controller => 'home')
+ format.html { session[:return_to] and URI.parse(session[:return_to]).path == '/' ? redirect_to(home_url) : redirect_back_or_default(home_url) }
+ end
+ end
+
+ def failed_login(message)
+ respond_to do |format|
+ flash.now[:error] = message
+ format.html { render :action ="" 'new' }
+ end
+ end
+
+ # Get the OpenID::Consumer object.
+ def consumer
+ # create the OpenID store for storing associations and nonces,
+ # putting it in your app's db directory
+ store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
+ store = OpenID::Store::Filesystem.new(store_dir)
+
+ return OpenID::Consumer.new(session, store)
+ end
+end
Modified: branches/datasets/app/controllers/tags_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/tags_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/tags_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -20,9 +20,9 @@
format.html {
@lod_nir = tag_url(@tag)
- @lod_html = formatted_tag_url(:id => @tag.id, :format => 'html')
- @lod_rdf = formatted_tag_url(:id => @tag.id, :format => 'rdf')
- @lod_xml = formatted_tag_url(:id => @tag.id, :format => 'xml')
+ @lod_html = tag_url(:id => @tag.id, :format => 'html')
+ @lod_rdf = tag_url(:id => @tag.id, :format => 'rdf')
+ @lod_xml = tag_url(:id => @tag.id, :format => 'xml')
# show.rhtml
}
Modified: branches/datasets/app/controllers/user_reports_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/user_reports_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/user_reports_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -37,7 +37,6 @@
def error
render(:text => '400 Bad Request', :status => "400 Bad Request")
- false
end
end
Modified: branches/datasets/app/controllers/userhistory_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/userhistory_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/userhistory_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -32,7 +32,6 @@
rescue ActiveRecord::RecordNotFound
error("User not found", "is invalid", :user_id)
- return false
end
else
@user = User.find(params[:id])
Modified: branches/datasets/app/controllers/users_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/users_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/users_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -40,9 +40,9 @@
def show
@lod_nir = user_url(@user)
- @lod_html = formatted_user_url(:id => @user.id, :format => 'html')
- @lod_rdf = formatted_user_url(:id => @user.id, :format => 'rdf')
- @lod_xml = formatted_user_url(:id => @user.id, :format => 'xml')
+ @lod_html = user_url(:id => @user.id, :format => 'html')
+ @lod_rdf = user_url(:id => @user.id, :format => 'rdf')
+ @lod_xml = user_url(:id => @user.id, :format => 'xml')
@user.salt = nil
@user.crypted_password = nil
@@ -578,17 +578,17 @@
@user = User.find(params[:id], :include => [ :profile, :tags ])
rescue ActiveRecord::RecordNotFound
error("User not found", "is invalid (not owner)")
- return false
+ return
end
unless @user
error("User not found", "is invalid (not owner)")
- return false
+ return
end
unless @user.activated?
error("User not activated", "is invalid (not owner)")
- return false
+ return
end
end
@@ -597,17 +597,17 @@
@user = User.find(params[:id], :conditions => ["id = ?", current_user.id])
rescue ActiveRecord::RecordNotFound
error("User not found (id not authorized)", "is invalid (not owner)")
- return false
+ return
end
unless @user
error("User not found (or not authorized)", "is invalid (not owner)")
- return false
+ return
end
unless @user.activated?
error("User not activated (id not authorized)", "is invalid (not owner)")
- return false
+ return
end
end
Modified: branches/datasets/app/controllers/workflows_controller.rb (2857 => 2858)
--- branches/datasets/app/controllers/workflows_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/controllers/workflows_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -219,7 +219,7 @@
end
format.rss do
address@hidden = Workflow.find(:all, :order => "updated_at DESC") # list all (if required)
- render :action ="" 'index.rxml', :layout => false
+ render :action ="" 'feed.rxml', :layout => false
end
end
end
@@ -245,14 +245,14 @@
if params[:version]
@lod_nir = workflow_version_url(:id => @workflow.id, :version => @viewing_version_number)
- @lod_html = formatted_workflow_version_url(:id => @workflow.id, :version => @viewing_version_number, :format => 'html')
- @lod_rdf = formatted_workflow_version_url(:id => @workflow.id, :version => @viewing_version_number, :format => 'rdf')
- @lod_xml = formatted_workflow_version_url(:id => @workflow.id, :version => @viewing_version_number, :format => 'xml')
+ @lod_html = workflow_version_url(:id => @workflow.id, :version => @viewing_version_number, :format => 'html')
+ @lod_rdf = workflow_version_url(:id => @workflow.id, :version => @viewing_version_number, :format => 'rdf')
+ @lod_xml = workflow_version_url(:id => @workflow.id, :version => @viewing_version_number, :format => 'xml')
else
@lod_nir = workflow_url(@workflow)
- @lod_html = formatted_workflow_url(:id => @workflow.id, :format => 'html')
- @lod_rdf = formatted_workflow_url(:id => @workflow.id, :format => 'rdf')
- @lod_xml = formatted_workflow_url(:id => @workflow.id, :format => 'xml')
+ @lod_html = workflow_url(:id => @workflow.id, :format => 'html')
+ @lod_rdf = workflow_url(:id => @workflow.id, :format => 'rdf')
+ @lod_xml = workflow_url(:id => @workflow.id, :format => 'xml')
end
# show.rhtml
Modified: branches/datasets/app/helpers/application_helper.rb (2857 => 2858)
--- branches/datasets/app/helpers/application_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/helpers/application_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -53,7 +53,7 @@
if old_dt.is_a?(DateTime)
rtn = old_dt
else
- rtn = Time.at(old_dt)
+ rtn = Time.at(old_dt.time)
end
return long ? rtn.strftime("%A %d %B %Y @ %H:%M:%S (%Z)") : rtn.strftime("%d/%m/%y @ %H:%M:%S")
@@ -62,7 +62,7 @@
def date(old_dt, long=true)
return nil unless old_dt
- rtn = Time.at(old_dt)
+ rtn = Time.at(old_dt.time)
return long ? rtn.strftime("%d %B %Y") : rtn.strftime("%d/%m/%y")
end
@@ -90,7 +90,7 @@
return nil
end
- name = truncate_to ? truncate(user.name, truncate_to) : name = user.name
+ name = truncate_to ? truncate(user.name, :length => truncate_to) : name = user.name
return link_to(h(name), user_url(user), :title => tooltip_title_attrib(h(user.name)))
end
@@ -105,7 +105,7 @@
return nil
end
- title = truncate_to ? truncate(network.title, truncate_to) : network.title
+ title = truncate_to ? truncate(network.title, :length => truncate_to) : network.title
return link_to(h(title), group_url(network))
end
@@ -215,7 +215,7 @@
rtn = fships
end
- return link_to(rtn, friendships_path(user))
+ return link_to(rtn, user_friendships_path(user))
end
def request_membership_link(user_id, network_id)
@@ -227,7 +227,7 @@
end
def request_friendship_link(user_id)
- link_to("Request Friendship", new_friendship_url(:user_id => user_id))
+ link_to("Request Friendship", new_user_friendship_url(:user_id => user_id))
end
def versioned_workflow_link(workflow_id, version_number, long_description=true)
@@ -405,7 +405,7 @@
def contributable_name(contributableid, contributabletype, truncate=nil)
str = contributable(contributableid, contributabletype, false)
- return truncate ? truncate(str, truncate) : str
+ return truncate ? truncate(str, :length => truncate) : str
end
def contributable_url(contributableid, contributabletype, base_host=nil)
@@ -466,7 +466,7 @@
end
def trim_body_html(body, limit=nil)
- truncate(body, limit)
+ truncate(body, :length => limit)
white_list(body)
end
Modified: branches/datasets/app/models/pack_remote_entry.rb (2857 => 2858)
--- branches/datasets/app/models/pack_remote_entry.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/models/pack_remote_entry.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-# myExperiment: app/models/pack_remote_entry.rb
+#/ myExperiment: app/models/pack_remote_entry.rb
#
# Copyright (c) 2008 University of Manchester and the University of Southampton.
# See license.txt for details.
@@ -31,4 +31,8 @@
# Rails 2 - use pack.destroyed? instead of pack.contribution.nil?
pack.touch unless pack.contribution.nil?
end
+
+ def available?
+ true
+ end
end
Modified: branches/datasets/app/models/user.rb (2857 => 2858)
--- branches/datasets/app/models/user.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/models/user.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -29,8 +29,7 @@
self.find(:all,
:order => "users.created_at DESC",
:limit => limit,
- :conditions => "users.activated_at IS NOT NULL",
- :include => :profile)
+ :conditions => "users.activated_at IS NOT NULL")
end
@@ -42,8 +41,7 @@
self.find(:all,
:order => "users.last_seen_at DESC",
:limit => limit,
- :conditions => "users.activated_at IS NOT NULL",
- :include => :profile)
+ :conditions => "users.activated_at IS NOT NULL")
end
Modified: branches/datasets/app/views/announcements/_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/announcements/_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/announcements/_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= error_messages_for 'announcement' %>
Modified: branches/datasets/app/views/announcements/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/announcements/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/announcements/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -19,7 +19,7 @@
<% if announcement.body and announcement.body.length > 0 %>
<div class="desc" style="font-size: 85%;">
- <%= truncate(strip_html(announcement.body), 180) %>
+ <%= truncate(strip_html(announcement.body), :length => 180) %>
</div>
<% end %>
Copied: branches/datasets/app/views/announcements/feed.rxml (from rev 2857, trunk/app/views/announcements/feed.rxml) (0 => 2858)
--- branches/datasets/app/views/announcements/feed.rxml (rev 0)
+++ branches/datasets/app/views/announcements/feed.rxml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,11 @@
+xml.rss "version" => "2.0", 'xmlns:opensearch' => "http://a9.com/-/spec/opensearch/1.1/", 'xmlns:atom' => "http://www.w3.org/2005/Atom" do
+ xml.channel do
+ xml.title "#{Conf.sitename} - Site Announcements"
+ xml.link announcements_url
+ xml.language "en-us"
+ xml.ttl "60"
+ xml.tag! "atom:link", :rel => 'search', :type => 'application/opensearchdescription+xml', :href ="" "http://#{request.host_with_port}/open_search.xml"
+ xml.description "RSS feed listing the Announcements on #{Conf.sitename}"
+ render(:partial => "layouts/announcement", :collection => @announcements, :locals => { :xm => xml })
+ end
+end
Modified: branches/datasets/app/views/announcements/index.rhtml (2857 => 2858)
--- branches/datasets/app/views/announcements/index.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/announcements/index.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,5 +1,5 @@
<h1>
- <%= feed_icon_tag "Site Announcements", formatted_announcements_path(:rss) %>
+ <%= feed_icon_tag "Site Announcements", announcements_path(:format => :rss) %>
Site Announcements (<%= @announcements.length %>)
</h1>
Deleted: branches/datasets/app/views/announcements/index.rxml (2857 => 2858)
--- branches/datasets/app/views/announcements/index.rxml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/announcements/index.rxml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,11 +0,0 @@
-xml.rss "version" => "2.0", 'xmlns:opensearch' => "http://a9.com/-/spec/opensearch/1.1/", 'xmlns:atom' => "http://www.w3.org/2005/Atom" do
- xml.channel do
- xml.title "#{Conf.sitename} - Site Announcements"
- xml.link announcements_url
- xml.language "en-us"
- xml.ttl "60"
- xml.tag! "atom:link", :rel => 'search', :type => 'application/opensearchdescription+xml', :href ="" "http://#{request.host_with_port}/open_search.xml"
- xml.description "RSS feed listing the Announcements on #{Conf.sitename}"
- render(:partial => "layouts/announcement", :collection => @announcements, :locals => { :xm => xml })
- end
-end
Modified: branches/datasets/app/views/blobs/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/blobs/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/blobs/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -69,7 +69,7 @@
<div class="desc" style="font-size: 85%;">
<% if blob.body and blob.body.length > 0 %>
- <% desc = truncate(strip_html(blob.body), 500) %>
+ <% desc = truncate(strip_html(blob.body), :length => 500) %>
<%= query ? highlight_all(desc, query) : desc %>
<% else -%>
<span class="none_text">No description</span>
@@ -79,7 +79,7 @@
<p style="font-size:85%;"><b>File type: </b><%= h blob.content_type.title %></p>
<p style="font-size: 85%;">
- <a href="" file_path(blob) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(blob.rating, 1) %> / 5 (<%= pluralize blob.ratings.count, 'rating' %>)</a> |
+ <a href="" file_path(blob) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(blob.rating, :precision => 1) %> / 5 (<%= pluralize blob.ratings.count, 'rating' %>)</a> |
<a href="" file_path(blob) + '#comments' -%>"><b>Comments: </b><%= blob.comments.count %></a> |
<b>Viewed:</b> <%=pluralize blob.contribution.site_viewings_count, "time" %> |
<b>Downloaded:</b> <%=pluralize blob.contribution.site_downloads_count, "time" %>
Modified: branches/datasets/app/views/blobs/edit.rhtml (2857 => 2858)
--- branches/datasets/app/views/blobs/edit.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/blobs/edit.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "Manage" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag "osp.js" %>
<h1>Manage File: <%= contributable_name(@blob.id, 'Blob') %></h1>
Modified: branches/datasets/app/views/blobs/new.rhtml (2857 => 2858)
--- branches/datasets/app/views/blobs/new.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/blobs/new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "New" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag "osp.js" %>
<h1>Upload File</h1>
Modified: branches/datasets/app/views/blogs/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/blogs/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/blogs/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -8,11 +8,11 @@
<ul class="sectionIcons">
<% if Authorization.is_authorized?("edit", nil, @blog, current_user) %>
<li><%= icon('new', new_blog_blog_post_path(@blog), nil, nil, "New post") %></li>
- <li><%= icon('edit', edit_blog_path(@blog), nil, nil, 'Edit ' + truncate(@blog.title, 10)) %></li>
+ <li><%= icon('edit', edit_blog_path(@blog), nil, nil, 'Edit ' + truncate(@blog.title, :length => 10)) %></li>
<% end %>
<% if Authorization.is_authorized?("destroy", nil, @blog, current_user) %>
- <li><%= icon('destroy', blog_path(@blog), nil, { :confirm => 'Are you sure?', :method => :delete }, 'Remove ' + truncate(@blog.title, 10)) %></li>
+ <li><%= icon('destroy', blog_path(@blog), nil, { :confirm => 'Are you sure?', :method => :delete }, 'Remove ' + truncate(@blog.title, :length => 10)) %></li>
<% end %>
</ul>
<% end %>
Modified: branches/datasets/app/views/comments/_comments.rhtml (2857 => 2858)
--- branches/datasets/app/views/comments/_comments.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/comments/_comments.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h2>
<%= icon "comments", nil, nil, { :style => "vertical-align: middle;" }, "" -%>
Modified: branches/datasets/app/views/content_types/edit.rhtml (2857 => 2858)
--- branches/datasets/app/views/content_types/edit.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/content_types/edit.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "Manage" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h1>Manage Content Type: <%= h @content_type.title %></h1>
Modified: branches/datasets/app/views/contributions/_most_tabs.rhtml (2857 => 2858)
--- branches/datasets/app/views/contributions/_most_tabs.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/contributions/_most_tabs.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -4,7 +4,7 @@
<div class="tabContainer">
<div class="tabTitle">
<% if controller.controller_name.downcase == 'workflows' -%>
- <%= feed_icon_tag "Latest Workflows", formatted_workflows_path(:rss), "margin-right: 0.2em;" %>
+ <%= feed_icon_tag "Latest Workflows", workflows_path(:format => :rss), "margin-right: 0.2em;" %>
<% end -%>
Latest
</div>
@@ -50,4 +50,4 @@
<%= render :partial => "contributions/list", :locals => { :collection => most_f, :table => true } %>
</div>
</div>
-<% end %>
\ No newline at end of file
+<% end %>
Modified: branches/datasets/app/views/experiments/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/experiments/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/experiments/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -24,7 +24,7 @@
<div class="desc" style="font-size: 85%;">
<% unless experiment.description.blank? %>
- <%= truncate(strip_html(experiment.description), 180) %>
+ <%= truncate(strip_html(experiment.description), :length => 180) %>
<% else -%>
<span class="none_text">No description</span>
<% end -%>
Modified: branches/datasets/app/views/experiments/edit.rhtml (2857 => 2858)
--- branches/datasets/app/views/experiments/edit.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/experiments/edit.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h1>Edit Experiment</h1>
@@ -38,4 +38,4 @@
<center><%= submit_tag "Update", :disable_with => "Updating..." %></center>
<% end -%>
</div>
-</center>
\ No newline at end of file
+</center>
Modified: branches/datasets/app/views/experiments/new.rhtml (2857 => 2858)
--- branches/datasets/app/views/experiments/new.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/experiments/new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h1>New Experiment</h1>
@@ -39,4 +39,4 @@
<center><%= submit_tag "Create", :disable_with => "Creating..." %></center>
<% end -%>
</div>
-</center>
\ No newline at end of file
+</center>
Modified: branches/datasets/app/views/friendships/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/friendships/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/friendships/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -22,7 +22,7 @@
<td class="actions">
<% if mine? friendship %>
<%= icon "show", user_friendship_path(friendship.friend_id, friendship), nil, nil, "View" %>
- <% unless friendship.accepted? %> <%= icon "confirm", accept_friendship_path(friendship.friend_id, friendship), nil, :method => :post %><% end %>
+ <% unless friendship.accepted? %> <%= icon "confirm", accept_user_friendship_path(friendship.friend_id, friendship), nil, :method => :post %><% end %>
<%= icon (friendship.accepted? ? "destroy" : "reject"), user_friendship_path(friendship.friend_id, friendship), nil, :confirm => "Are you sure?", :method => :delete %>
<% end %>
</td>
Modified: branches/datasets/app/views/friendships/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/friendships/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/friendships/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -76,7 +76,7 @@
<!-- These forms serve as 'data senders' for Accept/Reject buttons -->
- <% form_tag (accept_friendship_path(@friendship.friend_id, @friendship)) do %>
+ <% form_tag (accept_user_friendship_path(@friendship.friend_id, @friendship)) do %>
<%= hidden_field_tag "accept_msg", "" %>
<% end %>
Modified: branches/datasets/app/views/gadgets/_asset_manager.rhtml (2857 => 2858)
--- branches/datasets/app/views/gadgets/_asset_manager.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/gadgets/_asset_manager.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -26,7 +26,7 @@
<div class="content">
<ul class="gadget_list">
<% current_user.friends.each do |friend| %>
- <li><%= icon "user", nil, nil, nil, "" %> <%= link_to truncate(h(friend.name), gadget_characters_limit), user_path(friend), :title => tooltip_title_attrib(h(friend.name)) %></li>
+ <li><%= icon "user", nil, nil, nil, "" %> <%= link_to truncate(h(friend.name), :length => gadget_characters_limit), user_path(friend), :title => tooltip_title_attrib(h(friend.name)) %></li>
<% end %>
</ul>
</div>
@@ -41,10 +41,10 @@
<div class="content">
<ul class="gadget_list">
<% current_user.networks_owned.each do |network_owned| %>
- <li><%= icon "network-owned", nil, nil, nil, "" %> <%= link_to truncate(h(network_owned.title), gadget_characters_limit), group_path(network_owned), :title => tooltip_title_attrib(h(network_owned.title)) %></li>
+ <li><%= icon "network-owned", nil, nil, nil, "" %> <%= link_to truncate(h(network_owned.title), :length => gadget_characters_limit), group_path(network_owned), :title => tooltip_title_attrib(h(network_owned.title)) %></li>
<% end %>
<% current_user.networks.each do |network_member| %>
- <li><%= icon "network-member", nil, nil, nil, "" %> <%= link_to truncate(h(network_member.title), gadget_characters_limit), group_path(network_member), :title => tooltip_title_attrib(h(network_member.title)) %></li>
+ <li><%= icon "network-member", nil, nil, nil, "" %> <%= link_to truncate(h(network_member.title), :length => gadget_characters_limit), group_path(network_member), :title => tooltip_title_attrib(h(network_member.title)) %></li>
<% end %>
</ul>
</div>
Modified: branches/datasets/app/views/gadgets/_user_monitor.rhtml (2857 => 2858)
--- branches/datasets/app/views/gadgets/_user_monitor.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/gadgets/_user_monitor.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -40,7 +40,7 @@
<% current_user.messages_unread.each do |message| %>
<li>
<%= icon "message", message_path(message), nil, nil, "" %>
- <b><%= link_to truncate(h(message.subject), trunc_length), message_path(message), :title => tooltip_title_attrib(h(message.subject)) -%></b>
+ <b><%= link_to truncate(h(message.subject), :length => trunc_length), message_path(message), :title => tooltip_title_attrib(h(message.subject)) -%></b>
</li>
<% end %>
</ul>
@@ -59,7 +59,7 @@
<% current_user.friendships_pending.each do |friendship| %>
<li>
<%= icon "user", user_friendship_path(current_user, friendship), nil, nil, "" %>
- <b><%= link_to truncate(h(friendship.user.name), trunc_length), user_friendship_path(current_user, friendship), :title => tooltip_title_attrib(h(friendship.user.name)) -%></b>
+ <b><%= link_to truncate(h(friendship.user.name), :length => trunc_length), user_friendship_path(current_user, friendship), :title => tooltip_title_attrib(h(friendship.user.name)) -%></b>
</li>
<% end %>
</ul>
@@ -78,8 +78,8 @@
<ul class="gadget_list">
<% membership_invites.each do |membership| %>
<li>
- <%= icon "membership", membership_path(membership.user, membership), nil, nil, "" -%>
- <b><%= link_to truncate("From #{h(membership.network.owner.name)}", trunc_length), membership_path(membership.user, membership), :title => tooltip_title_attrib("From #{h(membership.network.owner.name)}") -%></b>
+ <%= icon "membership", user_membership_path(membership.user, membership), nil, nil, "" -%>
+ <b><%= link_to truncate("From #{h(membership.network.owner.name)}", :length => trunc_length), user_membership_path(membership.user, membership), :title => tooltip_title_attrib("From #{h(membership.network.owner.name)}") -%></b>
<span style="margin-left: 20px; display: block;"><small>(for Group: <%= title membership.network_id %>)</small></span>
</li>
<% end %>
@@ -99,8 +99,8 @@
<ul class="gadget_list">
<% membership_requests.each do |membership| %>
<li>
- <%= icon "membership", membership_path(membership.user, membership), nil, nil, "" -%>
- <b><%= link_to truncate("From #{h(membership.user.name)}", trunc_length), membership_path(membership.user, membership), :title => tooltip_title_attrib("From #{h(membership.user.name)}") -%></b>
+ <%= icon "membership", user_membership_path(membership.user, membership), nil, nil, "" -%>
+ <b><%= link_to truncate("From #{h(membership.user.name)}", :length => trunc_length), user_membership_path(membership.user, membership), :title => tooltip_title_attrib("From #{h(membership.user.name)}") -%></b>
<span style="margin-left: 20px; display: block;"><small>(for Group: <%= title membership.network_id %>)</small></span>
</li>
<% end %>
Modified: branches/datasets/app/views/group_announcements/_breadcrumbs.rhtml (2857 => 2858)
--- branches/datasets/app/views/group_announcements/_breadcrumbs.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/group_announcements/_breadcrumbs.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -8,11 +8,11 @@
<li><b>»</b></li>
<% case controller.action_name.to_s; when "show" -%>
- <li><%= truncate(h(@announcement.title),50) -%></li>
+ <li><%= truncate(h(@announcement.title), :length => 50) -%></li>
<% when "new" -%>
<li>New Announcement</li>
<% when "edit" -%>
- <li><%= link_to "#{truncate(h(@announcement.title),50)}", group_announcement_path(@group, @announcement) -%></li>
+ <li><%= link_to "#{truncate(h(@announcement.title), :length => 50)}", group_announcement_path(@group, @announcement) -%></li>
<li><b>»</b></li>
<li>Edit</li>
<% else -%>
Modified: branches/datasets/app/views/group_announcements/_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/group_announcements/_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/group_announcements/_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= error_messages_for 'announcement' %>
Modified: branches/datasets/app/views/group_announcements/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/group_announcements/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/group_announcements/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -19,7 +19,7 @@
<% if announcement.body and announcement.body.length > 0 %>
<div class="desc" style="font-size: 85%;">
- <%= truncate(strip_html(announcement.body), 180) %>
+ <%= truncate(strip_html(announcement.body), :length => 180) %>
</div>
<% end %>
Copied: branches/datasets/app/views/group_announcements/feed.rxml (from rev 2857, trunk/app/views/group_announcements/feed.rxml) (0 => 2858)
--- branches/datasets/app/views/group_announcements/feed.rxml (rev 0)
+++ branches/datasets/app/views/group_announcements/feed.rxml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,12 @@
+xml.rss "version" => "2.0", 'xmlns:opensearch' => "http://a9.com/-/spec/opensearch/1.1/", 'xmlns:atom' => "http://www.w3.org/2005/Atom" do
+ xml.channel do
+ xml.title "#{Conf.sitename} - Public Group Announcements for address@hidden Group"
+ xml.link group_announcements_url(@group)
+ xml.language "en-us"
+ xml.ttl "60"
+ xml.tag! "atom:link", :rel => 'search', :type => 'application/opensearchdescription+xml', :href ="" "http://#{request.host_with_port}/open_search.xml"
+ xml.description "RSS feed listing the Group Announcements for address@hidden Group on #{Conf.sitename}"
+ # for the feeds always display only the public announcements
+ render(:partial => "layouts/group_announcement", :collection => @group.announcements_public, :locals => { :xm => xml, :group => @group })
+ end
+end
Modified: branches/datasets/app/views/group_announcements/index.rhtml (2857 => 2858)
--- branches/datasets/app/views/group_announcements/index.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/group_announcements/index.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -5,7 +5,7 @@
<% end %>
<h1>
- <%= feed_icon_tag "Group #{h(@group.title)} Announcements", formatted_group_announcements_path(@group, :rss) %>
+ <%= feed_icon_tag "Group #{h(@group.title)} Announcements", group_announcements_path(@group, :format => :rss) %>
<%= @group.announcements_in_public_mode_for_user(current_user) ? "Public " : "All " -%> Group Announcements (<%= @announcements.length %>)
<br/>
<span style="font-size: 77%;">for group: <%= link_to_function h(@group.title) + expand_image, visual_effect(:toggle_blind, "group_box", :duration => 0.3) -%></span>
Deleted: branches/datasets/app/views/group_announcements/index.rxml (2857 => 2858)
--- branches/datasets/app/views/group_announcements/index.rxml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/group_announcements/index.rxml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,12 +0,0 @@
-xml.rss "version" => "2.0", 'xmlns:opensearch' => "http://a9.com/-/spec/opensearch/1.1/", 'xmlns:atom' => "http://www.w3.org/2005/Atom" do
- xml.channel do
- xml.title "#{Conf.sitename} - Public Group Announcements for address@hidden Group"
- xml.link group_announcements_url(@group)
- xml.language "en-us"
- xml.ttl "60"
- xml.tag! "atom:link", :rel => 'search', :type => 'application/opensearchdescription+xml', :href ="" "http://#{request.host_with_port}/open_search.xml"
- xml.description "RSS feed listing the Group Announcements for address@hidden Group on #{Conf.sitename}"
- # for the feeds always display only the public announcements
- render(:partial => "layouts/group_announcement", :collection => @group.announcements_public, :locals => { :xm => xml, :group => @group })
- end
-end
Modified: branches/datasets/app/views/home/_announcements.rhtml (2857 => 2858)
--- branches/datasets/app/views/home/_announcements.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/home/_announcements.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -2,7 +2,7 @@
<div class="box">
<b class="xtop"><b class="xb1"></b><b class="xb2"></b><b class="xb3"></b><b class="xb4"></b></b>
<div class="title">
- <%= feed_icon_tag "Site Announcements", formatted_announcements_path(:rss) %>
+ <%= feed_icon_tag "Site Announcements", announcements_path(:format => :rss) %>
Site Announcements
</div>
<div class="content">
@@ -30,4 +30,4 @@
</p>
</div>
<b class="xbottom"><b class="xb5"></b><b class="xb6"></b><b class="xb7"></b><b class="xb1"></b></b>
-</div>
\ No newline at end of file
+</div>
Modified: branches/datasets/app/views/home/_latest_comments.rhtml (2857 => 2858)
--- branches/datasets/app/views/home/_latest_comments.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/home/_latest_comments.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -19,7 +19,7 @@
(<%= timeago_fuzzy c.created_at %>)
</span>
<div class="box_standout" style="font-size: 85%; margin: 0.4em 2em; padding: 0.2em 0.5em;">
- <%= truncate(strip_html(white_list(c.comment)), 150) %>
+ <%= truncate(strip_html(white_list(c.comment)), :length => 150) %>
<p style="text-align: right;">[ <%= link_to "More", (c.commentable_type == 'Network' ? group_url(c.commentable) + "#comment_#{c.id}" : contributable_url(c.commentable_id, c.commentable_type) + "#comment_#{c.id}") %> ]</p>
</div>
<br/>
Modified: branches/datasets/app/views/home/_latest_reviews.rhtml (2857 => 2858)
--- branches/datasets/app/views/home/_latest_reviews.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/home/_latest_reviews.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -31,7 +31,7 @@
<% end -%>
</span>
</p>
- <%= truncate(strip_html(white_list(r.review)), 150) %>
+ <%= truncate(strip_html(white_list(r.review)), :length => 150) %>
<p style="text-align: right;">[ <%= link_to "More", workflow_review_url(r.reviewable, r) -%> ]</p>
</div>
<br/>
Modified: branches/datasets/app/views/jobs/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/jobs/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/jobs/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -21,7 +21,7 @@
<% unless job.description.blank? %>
<div class="desc" style="font-size: 85%; margin: 0.3em 0;">
- <%= truncate(strip_html(job.description), 180) %>
+ <%= truncate(strip_html(job.description), :length => 180) %>
</div>
<% end %>
Modified: branches/datasets/app/views/jobs/new.rhtml (2857 => 2858)
--- branches/datasets/app/views/jobs/new.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/jobs/new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor -%>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" -%>
<h1>New Job</h1>
Modified: branches/datasets/app/views/layouts/_feed_link_tags.rhtml (2857 => 2858)
--- branches/datasets/app/views/layouts/_feed_link_tags.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/layouts/_feed_link_tags.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -7,5 +7,5 @@
<% end -%>
<% if controller.controller_name.to_s == "packs" and controller.action_name.to_s == "show" -%>
- <link href="" formatted_items_pack_path(@pack, :rss) -%>" rel="alternate" type="application/rss+xml" title="<%= Conf.sitename %> - Pack items feed" />
+ <link href="" items_pack_path(@pack, :format => :rss) -%>" rel="alternate" type="application/rss+xml" title="<%= Conf.sitename %> - Pack items feed" />
<% end -%>
Modified: branches/datasets/app/views/licenses/_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/licenses/_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/licenses/_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag 'license_attributes' %>
<!--[form:license]-->
@@ -18,4 +18,4 @@
<%= fckeditor_textarea(:license, :description, :toolbarSet => 'Simple', :width => '700px', :height => '300px') %></p>
<br/><br/>
-<!--[eoform:license]-->
\ No newline at end of file
+<!--[eoform:license]-->
Modified: branches/datasets/app/views/licenses/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/licenses/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/licenses/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -23,7 +23,7 @@
<% if license.description_html and license.description_html.length > 0 %>
<div class="desc" style="font-size: 85%;">
- <%= truncate(strip_html(license.description_html), 180) %>
+ <%= truncate(strip_html(license.description_html), :length => 180) %>
</div>
<% end %>
Modified: branches/datasets/app/views/mailer/account_confirmation.rhtml (2857 => 2858)
--- branches/datasets/app/views/mailer/account_confirmation.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/mailer/account_confirmation.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -9,6 +9,7 @@
<%= url_for : false,
:controller => 'users',
:action ="" 'confirm_email',
+ :host => Conf.hostname,
:hash => @hash %>
- The <%= Conf.sitename %> Team
Modified: branches/datasets/app/views/mailer/forgot_password.rhtml (2857 => 2858)
--- branches/datasets/app/views/mailer/forgot_password.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/mailer/forgot_password.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -8,6 +8,7 @@
<%= url_for : false,
:controller => 'users',
+ :host => Conf.hostname,
:action ="" 'reset_password',
:reset_code => @reset_code %>
Modified: branches/datasets/app/views/mailer/friendship_invite_new_user.rhtml (2857 => 2858)
--- branches/datasets/app/views/mailer/friendship_invite_new_user.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/mailer/friendship_invite_new_user.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -13,12 +13,12 @@
<% end -%>
-You can find out more about me (<%= @name -%>) from my profile page: <%= url_for : false, :controller => 'users', :id => @user_id, :action ="" 'show' %>
+You can find out more about me (<%= @name -%>) from my profile page: <%= url_for : false, :controller => 'users', :host => Conf.hostname, :id => @user_id, :action ="" 'show' %>
To become my friend you will have to follow these simple steps:
-1. Register for <%= indefinite_article(Conf.sitename) %> <%= Conf.sitename %> account at: <%= url_for : false, :controller => 'users', :action ="" 'new', :token => @token %>
+1. Register for <%= indefinite_article(Conf.sitename) %> <%= Conf.sitename %> account at: <%= url_for : false, :controller => 'users', :host => Conf.hostname, :action ="" 'new', :token => @token %>
2. Confirm your email address as instructed during the registration process.
3. Accept my friendship request that you will receive directly to your account once the registration is complete.
Modified: branches/datasets/app/views/mailer/group_invite_new_user.rhtml (2857 => 2858)
--- branches/datasets/app/views/mailer/group_invite_new_user.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/mailer/group_invite_new_user.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -15,12 +15,12 @@
You can find out more:
--> about this group : <%= Conf.base_uri + group_path(@group_id) %>
---> and about me (<%= @name -%>) from my profile page : <%= url_for : false, :controller => 'users', :id => @user_id, :action ="" 'show' %>
+--> and about me (<%= @name -%>) from my profile page : <%= url_for : false, :controller => 'users', :host => Conf.hostname, :id => @user_id, :action ="" 'show' %>
To join the group you will have to follow these simple steps:
-1. Register for <%= indefinite_article(Conf.sitename) %> <%= Conf.sitename %> account at: <%= url_for : false, :controller => 'users', :action ="" 'new', :token => @token %>
+1. Register for <%= indefinite_article(Conf.sitename) %> <%= Conf.sitename %> account at: <%= url_for : false, :controller => 'users', :host => Conf.hostname, :action ="" 'new', :token => @token %>
2. Confirm your email address as instructed during the registration process.
3. Accept the group membership request that you will receive directly to your account once the registration is complete.
Modified: branches/datasets/app/views/mailer/invite_new_user.rhtml (2857 => 2858)
--- branches/datasets/app/views/mailer/invite_new_user.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/mailer/invite_new_user.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -11,11 +11,11 @@
---------------------------------------------------------------------------
<% end -%>
-Join us at: <%= url_for : false, :controller => 'users', :action ="" 'new' %>
+Join us at: <%= url_for : false, :controller => 'users', :host => Conf.hostname, :action ="" 'new' %>
You can find out more:
--> about <%= Conf.sitename -%>: <%= Conf.base_uri %>
---> and about me: <%= url_for : false, :controller => 'users', :id => @user_id, :action ="" 'show' %>
+--> and about me: <%= url_for : false, :controller => 'users', :host => Conf.hostname, :id => @user_id, :action ="" 'show' %>
Best regards,
Modified: branches/datasets/app/views/mailer/update_email_address.rhtml (2857 => 2858)
--- branches/datasets/app/views/mailer/update_email_address.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/mailer/update_email_address.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -8,6 +8,7 @@
<%= url_for : false,
:controller => 'users',
+ :host => Conf.hostname,
:action ="" 'confirm_email',
:hash => @hash %>
Modified: branches/datasets/app/views/memberships/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/memberships/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/memberships/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -26,22 +26,22 @@
<td><%= "<b>" unless membership.accepted? %><%=datetime(membership.accepted_at, false) || "Pending" %><%= "</b>" unless membership.accepted? %></td>
<td class="actions">
<% if my_page? membership.user or (logged_in? and membership.network.administrator?(current_user.id)) %>
- <%= icon "show", membership_path(membership.user_id, membership), nil, nil, "View" %>
+ <%= icon "show", user_membership_path(membership.user_id, membership), nil, nil, "View" %>
<% if membership.accepted? %>
- <%= icon "destroy", membership_path(membership.user_id, membership), nil, { :confirm => "Are you sure?", :method => :delete }, "Remove" %>
+ <%= icon "destroy", user_membership_path(membership.user_id, membership), nil, { :confirm => "Are you sure?", :method => :delete }, "Remove" %>
<% end %>
<% end %>
<% if allow_approval %>
<% unless membership.accepted? %>
- <%= icon "confirm", accept_membership_path(current_user.id, membership), nil, :method => :post %>
- <%= icon "reject", membership_path(membership.user_id, membership), nil, :confirm => "Are you sure?", :method => :delete %>
+ <%= icon "confirm", accept_user_membership_path(current_user.id, membership), nil, :method => :post %>
+ <%= icon "reject", user_membership_path(membership.user_id, membership), nil, :confirm => "Are you sure?", :method => :delete %>
<% end %>
<% end %>
<% if membership.accepted? %>
<% if membership.network.administrator?(membership.user_id) %>
- <%= icon "remove_group_admin", membership_path(membership.user_id, membership)+'?membership[administrator]=0', nil, {:method => :put}, "Remove group admin status" %>
+ <%= icon "remove_group_admin", user_membership_path(membership.user_id, membership)+'?membership[administrator]=0', nil, {:method => :put}, "Remove group admin status" %>
<% else %>
- <%= icon "make_group_admin", membership_path(membership.user_id, membership)+'?membership[administrator]=1', nil, {:method => :put}, "Add
+ <%= icon "make_group_admin", user_membership_path(membership.user_id, membership)+'?membership[administrator]=1', nil, {:method => :put}, "Add
group admin status" %>
<% end %>
<% end %>
Modified: branches/datasets/app/views/memberships/edit.rhtml (2857 => 2858)
--- branches/datasets/app/views/memberships/edit.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/memberships/edit.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -2,8 +2,8 @@
<%= error_messages_for :membership %>
-<% form_for(:membership, :url ="" membership_path(@membership.user_id, @membership), :html => { :method => :put }) do |f| %>
+<% form_for(:membership, :url ="" user_membership_path(@membership.user_id, @membership), :html => { :method => :put }) do |f| %>
<p>
<%= submit_tag "Save Changes" %>
</p>
-<% end %>
\ No newline at end of file
+<% end %>
Modified: branches/datasets/app/views/memberships/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/memberships/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/memberships/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -101,7 +101,7 @@
<!-- These forms serve as 'data senders' for Accept/Reject buttons -->
- <% form_tag(accept_membership_path(current_user.id, @membership)) do %>
+ <% form_tag(accept_user_membership_path(current_user.id, @membership)) do %>
<%= hidden_field_tag "accept_msg", "" %>
<% end %>
Modified: branches/datasets/app/views/messages/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/messages/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/messages/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -77,7 +77,7 @@
<% if inbox_mode -%>
<%= icon('reply', url_for(:controller => :messages, :action ="" :new, :reply_id => message.id), nil, nil, 'Reply') %>
<% end -%>
- <% complex_delete_url = "<a href="" (confirm('Are you sure you want to delete this message?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = "" m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var n = document.createElement('input'); n.setAttribute('type', 'hidden'); n.setAttribute('name', 'deleted_from'); n.setAttribute('value', '#{message_folder}'); f.appendChild(n); f.submit(); };return false;\">" -%>
+ <% complex_delete_url = "<a href="" (confirm('Are you sure you want to delete this message?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = "" m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var n = document.createElement('input'); n.setAttribute('type', 'hidden'); n.setAttribute('name', 'deleted_from'); n.setAttribute('value', '#{message_folder}'); f.appendChild(n); var o = document.createElement('input'); o.setAttribute('type', 'hidden'); o.setAttribute('name', 'authenticity_token'); o.setAttribute('value', '#{form_authenticity_token}'); f.appendChild(o); f.submit(); };return false;\">" -%>
<%= icon_no_link_processing('message_delete', complex_delete_url, nil, 'Delete') %>
</td>
</tr>
@@ -85,11 +85,11 @@
</table>
<br>
- <a class="button_slim" href="" (isSmthSelected()) { if(confirm('Are you sure you want to delete all selected messages?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = "" m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m); var n = document.createElement('input'); n.setAttribute('type', 'hidden'); n.setAttribute('name', 'msg_ids'); n.setAttribute('value', getSelectedMsgIDs()); f.appendChild(n); var o = document.createElement('input'); o.setAttribute('type', 'hidden'); o.setAttribute('name', 'deleted_from'); o.setAttribute('value', '<%=message_folder-%>'); f.appendChild(o); f.submit(); }} else{ alert('Please tick checkboxes next to the messages that you want to delete'); };return false;"><%= delete_image("vertical-align: middle", "") -%><span style="vertical-align: middle;"> Delete all selected messages</span></a>
+ <a class="button_slim" href="" (isSmthSelected()) { if(confirm('Are you sure you want to delete all selected messages?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = "" m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m); var n = document.createElement('input'); n.setAttribute('type', 'hidden'); n.setAttribute('name', 'msg_ids'); n.setAttribute('value', getSelectedMsgIDs()); f.appendChild(n); var o = document.createElement('input'); o.setAttribute('type', 'hidden'); o.setAttribute('name', 'deleted_from'); o.setAttribute('value', '<%=message_folder-%>'); f.appendChild(o); var p = document.createElement('input'); p.setAttribute('type', 'hidden'); p.setAttribute('name', 'authenticity_token'); p.setAttribute('value', '<%= form_authenticity_token -%>'); f.appendChild(p); f.submit(); }} else{ alert('Please tick checkboxes next to the messages that you want to delete'); };return false;"><%= delete_image("vertical-align: middle", "") -%><span style="vertical-align: middle;"> Delete all selected messages</span></a>
<% else %>
<p class="none_text" style="margin-left: 1.5em">No Messages</p>
-<% end %>
\ No newline at end of file
+<% end %>
Modified: branches/datasets/app/views/networks/_announcements.rhtml (2857 => 2858)
--- branches/datasets/app/views/networks/_announcements.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/networks/_announcements.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,7 +6,7 @@
<p class="heading" style="margin: 0;">
<span style="position: relative; z-index: 1000; float: left;">
- <%= feed_icon_tag "#{h(group.title)} Group Announcements", formatted_group_announcements_path(group, :rss) -%>
+ <%= feed_icon_tag "#{h(group.title)} Group Announcements", group_announcements_path(group, :format => :rss) -%>
</span>
<a name="group_announcements"></a>
<%= link_to "Announcements", group_announcements_url(group) -%>
Modified: branches/datasets/app/views/networks/_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/networks/_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/networks/_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
- <%= _javascript__include_tag :fckeditor %>
+ <%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<p>
<b>Administrator</b><br />
Modified: branches/datasets/app/views/networks/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/networks/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/networks/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -28,7 +28,7 @@
<div class="desc">
<div style="font-size: 85%;">
<% if network.description and network.description.length > 0 -%>
- <% desc = truncate(strip_html(network.description), 400) -%>
+ <% desc = truncate(strip_html(network.description), :length => 400) -%>
<%= query ? highlight_all(desc, query) : desc -%>
<% else -%>
<span class="none_text">No description</span>
@@ -74,7 +74,7 @@
<!-- user is not an admin, but a member already -->
<% cur_membership = Membership.find(:first, :conditions => ["network_id = ? AND user_id = ?", network.id, current_user.id] ) %>
<% if cur_membership %>
- <%= icon('network-leave', membership_path(cur_membership.user_id, cur_membership) + "?return_to=" + groups_path, nil, { :confirm => "Are you sure want to leave this group?", :method => :delete }, 'Leave Group') %>
+ <%= icon('network-leave', user_membership_path(cur_membership.user_id, cur_membership) + "?return_to=" + groups_path, nil, { :confirm => "Are you sure want to leave this group?", :method => :delete }, 'Leave Group') %>
<% end %>
<% elsif !current_user.membership_pending?(network.id) && !network.invitation_only? %>
<!-- not an admin, not a member yet and hasn't got pending request -->
Modified: branches/datasets/app/views/networks/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/networks/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/networks/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -7,7 +7,7 @@
</div>
<% elsif current_user.membership_invite_pending?(@network.id) %>
<div class="box_standout">
- <span style="text-align: left;"><b>You have been invited to join this group. Awaiting your <%= link_to "confirmation", membership_path(current_user, Membership.find(:first, :conditions => ['network_id = ? AND user_id = ?', @network, current_user])) -%>.</b></span>
+ <span style="text-align: left;"><b>You have been invited to join this group. Awaiting your <%= link_to "confirmation", user_membership_path(current_user, Membership.find(:first, :conditions => ['network_id = ? AND user_id = ?', @network, current_user])) -%>.</b></span>
</div>
<% end %>
@@ -16,7 +16,7 @@
<% if @network.member? current_user.id %>
<% cur_membership = Membership.find(:first, :conditions => ["network_id = ? AND user_id = ?", @network.id, current_user.id] ) %>
<% if cur_membership %>
- <li><%= icon('network-leave', membership_path(cur_membership.user_id, cur_membership), nil, { :confirm => "Are you sure want to leave this group?", :method => :delete }, 'Leave Group') %></li>
+ <li><%= icon('network-leave', user_membership_path(cur_membership.user_id, cur_membership), nil, { :confirm => "Are you sure want to leave this group?", :method => :delete }, 'Leave Group') %></li>
<% end %>
<% elsif !current_user.membership_pending?(@network.id) && address@hidden %>
<li class="with_sep_bottom"><%= request_membership_link(current_user.id, @network.id) %></li>
Modified: branches/datasets/app/views/notifier/membership_invite.rhtml (2857 => 2858)
--- branches/datasets/app/views/notifier/membership_invite.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/notifier/membership_invite.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -5,7 +5,7 @@
Name: <%= @network.title %>
Administrator: <%= @network.owner.name %>
-Please go to <%= "http://" + @base_url + membership_path(@user, @membership) %> to confirm/reject this invite.
+Please go to <%= "http://" + @base_url + user_membership_path(@user, @membership) %> to confirm/reject this invite.
<%= login_identity_reminder(@target) %>
Copied: branches/datasets/app/views/openid/_new.rhtml (from rev 2857, trunk/app/views/openid/_new.rhtml) (0 => 2858)
--- branches/datasets/app/views/openid/_new.rhtml (rev 0)
+++ branches/datasets/app/views/openid/_new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,18 @@
+<p>
+ <b>Current OpenID:</b><br />
+ <p title="<%= tooltip_title_attrib(current_user.openid_url) %>" ><%= current_user.openid_url.blank? ? "<span class='none_text'>Not registered yet</span>" : truncate(h(current_user.openid_url), :length => 30) %></P>
+
+</p>
+
+<div id="myexp_login">
+ <% form_tag openid_path do %>
+
+ <p>
+ <b>New OpenID:</b><br />
+ <%= text_field_tag 'openid_url', nil, :size => '30' %>
+ </p>
+
+ <%= submit_tag 'Validate', :disable_with => "Validating..." %>
+ <input type="submit" id="cancel_button" value="Return to your Profile" user_path(current_user) -%>';return false;"/>
+ <% end %>
+</div>
Deleted: branches/datasets/app/views/openid/new.rhtml (2857 => 2858)
--- branches/datasets/app/views/openid/new.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/openid/new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,18 +0,0 @@
-<p>
- <b>Current OpenID:</b><br />
- <p title="<%= tooltip_title_attrib(current_user.openid_url) %>" ><%= current_user.openid_url.blank? ? "<span class='none_text'>Not registered yet</span>" : truncate(h(current_user.openid_url), 30) %></P>
-
-</p>
-
-<div id="myexp_login">
- <% form_tag openid_path do %>
-
- <p>
- <b>New OpenID:</b><br />
- <%= text_field_tag 'openid_url', nil, :size => '30' %>
- </p>
-
- <%= submit_tag 'Validate', :disable_with => "Validating..." %>
- <input type="submit" id="cancel_button" value="Return to your Profile" user_path(current_user) -%>';return false;"/>
- <% end %>
-</div>
Modified: branches/datasets/app/views/packs/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/packs/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/packs/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -34,7 +34,7 @@
<div class="desc" style="font-size: 85%;">
<% unless pack.description.blank? %>
- <% desc = truncate(strip_html(pack.description), 500) %>
+ <% desc = truncate(strip_html(pack.description), :length => 500) %>
<%= query ? highlight_all(desc, query) : desc %>
<% else -%>
<span class="none_text">No description</span>
Modified: branches/datasets/app/views/packs/edit.rhtml (2857 => 2858)
--- branches/datasets/app/views/packs/edit.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/packs/edit.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "Manage" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag "osp.js" %>
<h1>Manage Pack: <%= contributable_name(@pack.id, 'Pack') %></h1>
Modified: branches/datasets/app/views/packs/new.rhtml (2857 => 2858)
--- branches/datasets/app/views/packs/new.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/packs/new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "New" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag "osp.js" %>
<h1>New Pack</h1>
Modified: branches/datasets/app/views/packs/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/packs/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/packs/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -71,7 +71,7 @@
<div class="contribution_version_box" style="background-color: #EEEEEE;">
<div class="contribution_version_inner_box">
<h4>
- <%= feed_icon_tag "RSS feed for items in this pack", formatted_items_pack_path(@pack, :rss), "float: right;" %>
+ <%= feed_icon_tag "RSS feed for items in this pack", items_pack_path(@pack, :format => :rss), "float: right;" %>
<% if @authorised_to_download %>
<%= download_icon_tag "Download all items in the pack as a single .zip archive", download_pack_path(@pack), "float: right; margin-right: 0.5em;" -%>
<% end %>
Modified: branches/datasets/app/views/profiles/_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/profiles/_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/profiles/_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<p style="color: #666666; font-weight: bold;">
Note: information you enter on this page will be visible to everyone (ie: will be public), but all fields are optional.
Modified: branches/datasets/app/views/ratings/_current.rhtml (2857 => 2858)
--- branches/datasets/app/views/ratings/_current.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/ratings/_current.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -3,9 +3,9 @@
Current:
</p>
<p style="font-size: 123.1%; font-weight: bold; padding-bottom: 0.2em; line-height: 1;">
- <%= number_with_precision(rateable.rating, 1) %> / 5
+ <%= number_with_precision(rateable.rating, :precision => 1) %> / 5
</p>
<p style="font-size: 85%; padding-top: 0.2em; line-height: 1;">
(<%= pluralize rateable.ratings.count, 'rating' %>)
</p>
-</div>
\ No newline at end of file
+</div>
Modified: branches/datasets/app/views/ratings/_rating.rhtml (2857 => 2858)
--- branches/datasets/app/views/ratings/_rating.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/ratings/_rating.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<ul class='star-rating'>
<li class='current-rating' style="width:<%= (rateable.rating * 30).to_i -%>px; border: none; padding: 0; margin: 0;">
- Currently <%= number_with_precision(rateable.rating, 0) %>/5 Stars.
+ Currently <%= number_with_precision(rateable.rating, :precision => 0) %>/5 Stars.
</li>
<li style="border: none; padding: 0; margin: 0;">
<%= link_to_remote( "1", {:url ="" { :controller => controller.to_s,
@@ -29,4 +29,4 @@
</li>
</ul>
-<%= render :partial => 'ratings/current', :locals => { :rateable => rateable } %>
\ No newline at end of file
+<%= render :partial => 'ratings/current', :locals => { :rateable => rateable } %>
Modified: branches/datasets/app/views/relationships/_relationships.rhtml (2857 => 2858)
--- branches/datasets/app/views/relationships/_relationships.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/relationships/_relationships.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -10,7 +10,11 @@
<ol class="relationship_sentences">
<% relationships.each do |relationship| %>
<li>
- <%= pack_entry_link(relationship.subject) -%>
+ <% if relationship.subject.available? %>
+ <%= pack_entry_link(relationship.subject) -%>
+ <% else %>
+ <span class="deletedPackItem">deleted item</span>
+ <% end %>
<% if relationship.predicate.phrase %>
<%=h relationship.predicate.phrase -%>
@@ -18,7 +22,11 @@
<%=h relationship.predicate.preferred_label.text.underscore.humanize.downcase -%>
<% end %>
- <%= pack_entry_link(relationship.objekt) -%>.
+ <% if relationship.objekt.available? %>
+ <%= pack_entry_link(relationship.objekt) -%>.
+ <% else %>
+ <span class="deletedPackItem">deleted item</span>
+ <% end %>
<% if can_edit && defined?(show_delete) && show_delete %>
<%= link_to_remote("<img src='' />",
Modified: branches/datasets/app/views/reviews/_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/reviews/_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/reviews/_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= error_messages_for 'review' %>
Modified: branches/datasets/app/views/reviews/_reviews.rhtml (2857 => 2858)
--- branches/datasets/app/views/reviews/_reviews.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/reviews/_reviews.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +1,4 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h2>
<%= icon "review", nil, "Reviews", { :style => "vertical-align: middle;" }, "" -%>
Modified: branches/datasets/app/views/reviews/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/reviews/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/reviews/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -31,7 +31,7 @@
<div class="desc" style="font-size: 85%;">
<% unless (text = strip_html(review.review)).blank? %>
- <%= truncate(text, 500) %>
+ <%= truncate(text, :length => 500) %>
<% else %>
<p class="none_text">No text</p>
<% end %>
Modified: branches/datasets/app/views/runners/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/runners/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/runners/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -24,7 +24,7 @@
<% unless runner.description.blank? %>
<div class="desc" style="font-size: 85%;">
- <%= truncate(strip_html(runner.description), 180) %>
+ <%= truncate(strip_html(runner.description), :length => 180) %>
</div>
<% end %>
Modified: branches/datasets/app/views/services/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/services/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/services/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -70,7 +70,7 @@
<div class="desc" style="font-size: 85%;">
<% unless service.description.blank? -%>
- <% desc = truncate(strip_html(service.description), 500) -%>
+ <% desc = truncate(strip_html(service.description), :length => 500) -%>
<%= query ? highlight_all(desc, query) : desc %>
<% else -%>
<span class="none_text">No description</span>
Modified: branches/datasets/app/views/tags/_tags_box.rhtml (2857 => 2858)
--- branches/datasets/app/views/tags/_tags_box.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/tags/_tags_box.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -25,7 +25,7 @@
<div class="auto_complete" id="tags_auto_complete" ></div>
<%= auto_complete_field :tag_list,
:update => "tags_auto_complete",
- :url ="" {:controller => 'tags', :action ="" 'auto_complete'},
+ :url ="" {:controller => 'tags', :action ="" 'auto_complete', :authenticity_token => form_authenticity_token},
:tokens => ',',
:indicator => "addtag_indicator" -%>
</p>
Modified: branches/datasets/app/views/tags/_tags_form.rhtml (2857 => 2858)
--- branches/datasets/app/views/tags/_tags_form.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/tags/_tags_form.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -48,7 +48,7 @@
<div class="auto_complete" id="tags_auto_complete" ></div>
<%= auto_complete_field "tags_input",
:update => "tags_auto_complete",
- :url ="" {:controller => 'tags', :action ="" 'auto_complete'},
+ :url ="" {:controller => 'tags', :action ="" 'auto_complete', :authenticity_token => form_authenticity_token},
:tokens => ',',
:indicator => "tagautocomplete_indicator" -%>
<img id="tagautocomplete_indicator" style="margin-top: 0.2em; display: none;" src="" />
Modified: branches/datasets/app/views/userhistory/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/userhistory/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/userhistory/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -34,7 +34,7 @@
<%= datetime c.created_at, false %> - for <%= visible_name c.commentable_type %>:
<%= c.commentable_type == 'Network' ? title(c.commentable_id) : contributable(c.commentable_id, c.commentable_type) %>
<div class="box_standout" style="margin: 0.5em 0;">
- <%= truncate(white_list(c.comment), 300) %>
+ <%= truncate(white_list(c.comment), :length => 300) %>
</div>
<br/><br/>
</li>
Modified: branches/datasets/app/views/users/_listing.rhtml (2857 => 2858)
--- branches/datasets/app/views/users/_listing.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/users/_listing.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -18,7 +18,7 @@
<div class="desc" style="font-size: 85%;">
<% unless user.profile.body.blank? %>
- <% desc = truncate(strip_html(user.profile.body), 180) %>
+ <% desc = truncate(strip_html(user.profile.body), :length => 180) %>
<%= query ? highlight_all(desc, query) : desc %>
<% else -%>
<span class="none_text">No description</span>
Modified: branches/datasets/app/views/users/edit.rhtml (2857 => 2858)
--- branches/datasets/app/views/users/edit.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/users/edit.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -59,7 +59,7 @@
<h2 style="width: 275px">OpenID account</h2>
<center>
<div style="width: 77%">
- <%= render "openid/new" %>
+ <%= render :partial => "openid/new" %>
</div>
</center>
</td>
Modified: branches/datasets/app/views/users/show.rhtml (2857 => 2858)
--- branches/datasets/app/views/users/show.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/users/show.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -40,7 +40,7 @@
<!-- check if the profile that we are viewing now is a friend of current user -> stored for better performance -->
<% this_user_is_friend_of_current_user = @user.friend? current_user.id %>
<% unless this_user_is_friend_of_current_user || current_user.friendship_pending?(@user.id) %>
- <li><%= icon('friendship', new_friendship_url(:user_id => @user.id), nil, nil, 'Request Friendship') %></li>
+ <li><%= icon('friendship', new_user_friendship_url(:user_id => @user.id), nil, nil, 'Request Friendship') %></li>
<% end %>
<% unless mine? @user %>
@@ -261,7 +261,7 @@
<b><%= h @user.name -%> has an average rating of:</b>
</p>
<p style="font-size: 123.1%; font-weight: bold; padding-bottom: 0.2em; line-height: 1;">
- <%= number_with_precision(avg_rating, 1) -%> / 5
+ <%= number_with_precision(avg_rating, :precision => 1) -%> / 5
</p>
<p style="font-size: 77%; padding-top: 0.2em; line-height: 1;">
(<%= pluralize rating_count, "rating" -%> in total)
Modified: branches/datasets/app/views/workflows/_table.rhtml (2857 => 2858)
--- branches/datasets/app/views/workflows/_table.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/_table.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -87,7 +87,7 @@
<p style="margin: 0; padding: 0; border: 0;">
<div class="desc" style="<%= desc_style -%>">
<% if workflow.body and workflow.body.length > 0 -%>
- <% desc = truncate(strip_html(workflow.body), 500) -%>
+ <% desc = truncate(strip_html(workflow.body), :length => 500) -%>
<%= query ? highlight_all(desc, query) : desc %>
<% else -%>
<span class="none_text">No description</span>
@@ -98,7 +98,7 @@
<div style="clear: both"></div>
<p style="font-size: 85%;">
- <a href="" workflow_path(workflow) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(workflow.rating, 1) %> / 5 (<%= pluralize workflow.ratings.count, 'rating' %>)</a> |
+ <a href="" workflow_path(workflow) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(workflow.rating, :precision => 1) %> / 5 (<%= pluralize workflow.ratings.count, 'rating' %>)</a> |
<a href="" workflow_path(workflow) + '#versions' -%>"><b>Versions: </b><%= workflow.versions.count %></a> |
<a href="" workflow_path(workflow) + '#reviews' -%>"><b>Reviews: </b><%= workflow.reviews.count %></a> |
<a href="" workflow_path(workflow) + '#comments' -%>"><b>Comments: </b><%= workflow.comments.count %></a> |
Modified: branches/datasets/app/views/workflows/_workflow.rhtml (2857 => 2858)
--- branches/datasets/app/views/workflows/_workflow.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/_workflow.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -21,7 +21,7 @@
<% if show and desc = workflow.body %>
<tr>
<td width="320" colspan="<%= image ? 2 : 3 %>">
- <%= truncate(desc, 100) %>
+ <%= truncate(desc, :length => 100) %>
</td>
</tr>
<% end %>
@@ -53,4 +53,4 @@
</tr>
</table>
</center>
-<% end %>
\ No newline at end of file
+<% end %>
Modified: branches/datasets/app/views/workflows/edit_version.rhtml (2857 => 2858)
--- branches/datasets/app/views/workflows/edit_version.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/edit_version.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "Edit Version" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h1>
Edit Version <%= @viewing_version_number.to_s %>
@@ -52,4 +52,4 @@
</div>
</center>
-<% end %>
\ No newline at end of file
+<% end %>
Copied: branches/datasets/app/views/workflows/feed.rxml (from rev 2857, trunk/app/views/workflows/feed.rxml) (0 => 2858)
--- branches/datasets/app/views/workflows/feed.rxml (rev 0)
+++ branches/datasets/app/views/workflows/feed.rxml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,11 @@
+xml.rss "version" => "2.0", 'xmlns:opensearch' => "http://a9.com/-/spec/opensearch/1.1/", 'xmlns:atom' => "http://www.w3.org/2005/Atom" do
+ xml.channel do
+ xml.title "#{Conf.sitename} - Latest Workflows"
+ xml.link workflows_url
+ xml.language "en-us"
+ xml.ttl "60"
+ xml.tag! "atom:link", :rel => 'search', :type => 'application/opensearchdescription+xml', :href ="" "http://#{request.host_with_port}/open_search.xml"
+ xml.description "RSS feed listing the latest Workflows which have been uploaded to #{Conf.sitename}"
+ render(:partial => "layouts/workflow", :collection => @rss_workflows, :locals => { :xm => xml })
+ end
+end
Deleted: branches/datasets/app/views/workflows/index.rxml (2857 => 2858)
--- branches/datasets/app/views/workflows/index.rxml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/index.rxml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,11 +0,0 @@
-xml.rss "version" => "2.0", 'xmlns:opensearch' => "http://a9.com/-/spec/opensearch/1.1/", 'xmlns:atom' => "http://www.w3.org/2005/Atom" do
- xml.channel do
- xml.title "#{Conf.sitename} - Latest Workflows"
- xml.link workflows_url
- xml.language "en-us"
- xml.ttl "60"
- xml.tag! "atom:link", :rel => 'search', :type => 'application/opensearchdescription+xml', :href ="" "http://#{request.host_with_port}/open_search.xml"
- xml.description "RSS feed listing the latest Workflows which have been uploaded to #{Conf.sitename}"
- render(:partial => "layouts/workflow", :collection => @rss_workflows, :locals => { :xm => xml })
- end
-end
Modified: branches/datasets/app/views/workflows/new.rhtml (2857 => 2858)
--- branches/datasets/app/views/workflows/new.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/new.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "New" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag "osp.js" %>
<h1>Upload Workflow</h1>
Modified: branches/datasets/app/views/workflows/new_version.rhtml (2857 => 2858)
--- branches/datasets/app/views/workflows/new_version.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/new_version.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
<% t "Upload New Version" -%>
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<h1>
Upload New Version
Modified: branches/datasets/app/views/workflows/tag_suggestions.rhtml (2857 => 2858)
--- branches/datasets/app/views/workflows/tag_suggestions.rhtml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/app/views/workflows/tag_suggestions.rhtml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,10 +1,12 @@
-<%= _javascript__include_tag :fckeditor %>
+<%= _javascript__include_tag "fckeditor/fckeditor.js" %>
<%= _javascript__include_tag "tag_suggestions.js" %>
<h1>Extra workflow metadata</h1>
<form id="metadata" action="" "/workflows/address@hidden/process_tag_suggestions" %>" method="post">
+ <%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
+
<% if @workflow.body.nil? || @workflow.body == "" %>
<h2>Workflow description</h2>
Modified: branches/datasets/config/boot.rb (2857 => 2858)
--- branches/datasets/config/boot.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/boot.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,39 +1,114 @@
-# Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb
+# Don't change this file!
+# Configure your app in config/environment.rb and config/environments/*.rb
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
-unless defined?(Rails::Initializer)
- if File.directory?("#{RAILS_ROOT}/vendor/rails")
- require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
- else
- require 'rubygems'
+module Rails
+ class << self
+ def boot!
+ unless booted?
+ preinitialize
+ pick_boot.run
+ end
+ end
- rails_gem_version =
- if defined? RAILS_GEM_VERSION
- RAILS_GEM_VERSION
+ def booted?
+ defined? Rails::Initializer
+ end
+
+ def pick_boot
+ (vendor_rails? ? VendorBoot : GemBoot).new
+ end
+
+ def vendor_rails?
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
+ end
+
+ def preinitialize
+ load(preinitializer_path) if File.exist?(preinitializer_path)
+ end
+
+ def preinitializer_path
+ "#{RAILS_ROOT}/config/preinitializer.rb"
+ end
+ end
+
+ class Boot
+ def run
+ load_initializer
+ Rails::Initializer.run(:set_load_path)
+ end
+ end
+
+ class VendorBoot < Boot
+ def load_initializer
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
+ Rails::Initializer.run(:install_gem_spec_stubs)
+ Rails::GemDependency.add_frozen_gem_path
+ end
+ end
+
+ class GemBoot < Boot
+ def load_initializer
+ self.class.load_rubygems
+ load_rails_gem
+ require 'initializer'
+ end
+
+ def load_rails_gem
+ if version = self.class.gem_version
+ gem 'rails', version
else
- File.read("#{File.dirname(__FILE__)}/environment.rb") =~ /^[^#]*RAILS_GEM_VERSION\s+=\s+'([\d.]+)'/
- $1
+ gem 'rails'
end
+ rescue Gem::LoadError => load_error
+ if load_error.message =~ /Could not find RubyGem rails/
+ STDERR.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
+ exit 1
+ else
+ raise
+ end
+ end
- if rails_gem_version
- rails_gem = Gem.cache.find_name('rails', "=#{rails_gem_version}.0").sort_by { |g| g.version.version }.last
+ class << self
+ def rubygems_version
+ Gem::RubyGemsVersion rescue nil
+ end
- if rails_gem
- gem "rails", "=#{rails_gem.version.version}"
- require rails_gem.full_gem_path + '/lib/initializer'
- else
- STDERR.puts %(Cannot find gem for Rails =#{rails_gem_version}.0:
- Install the missing gem with 'gem install -v=#{rails_gem_version} rails', or
- change environment.rb to define RAILS_GEM_VERSION with your desired version.
- )
+ def gem_version
+ if defined? RAILS_GEM_VERSION
+ RAILS_GEM_VERSION
+ elsif ENV.include?('RAILS_GEM_VERSION')
+ ENV['RAILS_GEM_VERSION']
+ else
+ parse_gem_version(read_environment_rb)
+ end
+ end
+
+ def load_rubygems
+ min_version = '1.3.2'
+ require 'rubygems'
+ unless rubygems_version >= min_version
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
+ exit 1
+ end
+
+ rescue LoadError
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
exit 1
end
- else
- gem "rails"
- require 'initializer'
+
+ def parse_gem_version(text)
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
+ end
+
+ private
+ def read_environment_rb
+ File.read("#{RAILS_ROOT}/config/environment.rb")
+ end
end
end
+end
- Rails::Initializer.run(:set_load_path)
-end
+# All that for this:
+Rails.boot!
Modified: branches/datasets/config/default_settings.yml (2857 => 2858)
--- branches/datasets/config/default_settings.yml 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/default_settings.yml 2011-12-01 14:16:25 UTC (rev 2858)
@@ -330,6 +330,19 @@
secret_word: our_secret_word_that_no_one_knows
+# session store secret - This secret key is used for session store integrity.
+#
+# (see config/initializers/session_store.rb)
+
+session_store_secret: dc9f8b03a18fc2b7fa858bf660d9685f1637ed67c1ff0fd5c39978ec2f22ccca8201b32d89aeada76722b4ee5fa3df9df7400b37995636876a7140f0382231ef
+
+# cookie verifier secret - This secret key is used to verify cookie session
+# data integrity.
+#
+# (see config/initializers/cookie_verification_secret.rb)
+
+cookie_verifier_secret: 64a59b43e7aa93e55a5db119180a2973b584555f71e87388de5c27682407987446a0293dab64f5913cb19ead617893546b3646c98672905a38e6dfbfb5871034
+
# google_web_analytics - Enable this to enable Google web analytics.
google_web_analytics:
Modified: branches/datasets/config/environment.rb (2857 => 2858)
--- branches/datasets/config/environment.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/environment.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,11 +1,7 @@
-# Be sure to restart your web server when you modify this file.
+# Be sure to restart your server when you modify this file
-# Uncomment below to force Rails into production mode when
-# you don't control web/app server and can't set it the proper way
-# ENV['RAILS_ENV'] ||= 'production'
-
# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '1.2.6' unless defined? RAILS_GEM_VERSION
+RAILS_GEM_VERSION = '2.3.14' unless defined? RAILS_GEM_VERSION
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
@@ -13,58 +9,70 @@
require 'uri'
Rails::Initializer.run do |config|
- # Settings in config/environments/* take precedence over those specified here
-
- # Skip frameworks you're not going to use (only works if using vendor/rails)
- # config.frameworks -= [ :action_web_service, :action_mailer ]
+ # Settings in config/environments/* take precedence over those specified here.
+ # Application configuration should go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded.
- # Only load the plugins named here, by default all plugins in vendor/plugins are loaded
- # config.plugins = %W( exception_notification ssl_requirement )
-
- config.plugins = ["engines", "encrypted_strings", "widgets", "white_list", "white_list_formatted_content", "*"]
-
# Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{RAILS_ROOT}/extras )
+ # config.autoload_paths += %W( #{RAILS_ROOT}/extras )
- # Force all environments to use the same logger level
- # (by default production uses :info, the others :debug)
- # config.log_level = :debug
+ # Specify gems that this application depends on and have them installed with rake gems:install
+ # config.gem "bj"
+ # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
+ # config.gem "sqlite3-ruby", :lib => "sqlite3"
+ # config.gem "aws-s3", :lib => "aws/s3"
- # Use the database for sessions instead of the file system
- # (create the session table with 'rake db:sessions:create')
+ # Only load the plugins named here, in the order given (default is alphabetical).
+ # :all can be used as a placeholder for all plugins not explicitly named
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
+ config.plugins = [
+ :encrypted_strings,
+ :widgets,
+ :country_select,
+ :white_list,
+ :white_list_formatted_content,
+ :acts_as_bookmarkable,
+ :acts_as_commentable,
+ :acts_as_rateable,
+ :acts_as_solr,
+ :acts_as_taggable_redux,
+ :acts_as_versioned,
+ :auto_complete,
+ :browser_filters,
+ :encrypted_attributes,
+ :exception_notification,
+ :fckeditor,
+ :headliner,
+ :mannie_taverna_scufl,
+ :mannie_taverna_t2flow,
+ :oauth_plugin,
+ :open_id_authentication,
+ :paginating_find,
+ :qrcode,
+ :query_stats,
+ :recaptcha,
+ :simile_timeline,
+ :structured_data,
+ :validates_captcha,
+ :validates_email_veracity_of
+ ]
- config.action_controller.session_store = :active_record_store
+ # Skip frameworks you're not going to use. To use Rails without a database,
+ # you must remove the Active Record framework.
+ # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
- # Use SQL instead of Active Record's schema dumper when creating the test database.
- # This is necessary if your schema can't be completely dumped by the schema dumper,
- # like if you have constraints or database-specific column types
- # config.active_record.schema_format = :sql
-
# Activate observers that should always be running
- # config.active_record.observers = :cacher, :garbage_collector
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
- # Make Active Record use UTC-base instead of local time
- # config.active_record.default_timezone = :utc
-
- # See Rails::Configuration for more options
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+ # Run "rake -D time" for a list of tasks for finding time zone names.
+ config.time_zone = 'UTC'
- base_uri = URI.parse(Conf.base_uri)
-
- config.action_mailer.default_url_options = {
- :host => base_uri.host + (base_uri.port == 80 ? "" : ":#{base_uri.port.to_s}")
- }
-
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
+ # config.i18n.default_locale = :de
end
-# Add new inflection rules using the following format
-# (all these examples are active by default):
-# Inflector.inflections do |inflect|
-# inflect.plural /^(ox)$/i, '\1en'
-# inflect.singular /^(ox)en/i, '\1'
-# inflect.irregular 'person', 'people'
-# inflect.uncountable %w( fish sheep )
-# end
-
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register "application/x-mobile", :mobile
@@ -87,15 +95,6 @@
ActionMailer::Base.smtp_settings = Conf.smtp
-# don't require actual keys for recaptcha during tests
-
-if RAILS_ENV == 'test'
- Recaptcha.configure do |config|
- config.public_key = ''
- config.private_key = ''
- end
-end
-
class ActiveRecord::Base
def inhibit_timestamps(&blk)
Modified: branches/datasets/config/environments/development.rb (2857 => 2858)
--- branches/datasets/config/environments/development.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/environments/development.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -8,14 +8,10 @@
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
-# Enable the breakpoint server that script/breakpointer connects to
-config.breakpoint_server = true
-
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching = false
-config.action_view.cache_template_extensions = false
config.action_view.debug_rjs = true
+config.action_controller.perform_caching = false
# Don't care if the mailer can't send
-config.action_mailer.raise_delivery_errors = false
+config.action_mailer.raise_delivery_errors = false
\ No newline at end of file
Modified: branches/datasets/config/environments/production.rb (2857 => 2858)
--- branches/datasets/config/environments/production.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/environments/production.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -4,15 +4,27 @@
# Code is not reloaded between requests
config.cache_classes = true
-# Use a different logger for distributed setups
-# config.logger = SyslogLogger.new
+config.log_path="log/production.#{Time.new().strftime(fmt='%Y%m%d')}.#{Process.pid}.log"
# Full error reports are disabled and caching is turned on
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = true
+config.action_view.cache_template_loading = true
+# See everything in the log (default is :info)
+# config.log_level = :debug
+
+# Use a different logger for distributed setups
+# config.logger = SyslogLogger.new
+
+# Use a different cache store in production
+# config.cache_store = :mem_cache_store
+
# Enable serving of images, stylesheets, and _javascript_s from an asset server
-# config.action_controller.asset_host = "http://assets.example.com"
+# config.action_controller.asset_host = "http://assets.example.com"
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
+
+# Enable threaded mode
+# config.threadsafe!
Modified: branches/datasets/config/environments/test.rb (2857 => 2858)
--- branches/datasets/config/environments/test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/environments/test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -12,8 +12,17 @@
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false
+config.action_view.cache_template_loading = true
-# Tell ActionMailer not to deliver emails to the real world.
+# Disable request forgery protection in test environment
+config.action_controller.allow_forgery_protection = false
+
+# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
-config.action_mailer.delivery_method = :test
\ No newline at end of file
+config.action_mailer.delivery_method = :test
+
+# Use SQL instead of Active Record's schema dumper when creating the test database.
+# This is necessary if your schema can't be completely dumped by the schema dumper,
+# like if you have constraints or database-specific column types
+# config.active_record.schema_format = :sql
\ No newline at end of file
Modified: branches/datasets/config/routes.rb (2857 => 2858)
--- branches/datasets/config/routes.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/config/routes.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -72,6 +72,7 @@
# search
map.resource :search,
+ :controller => 'search',
:member => { :live_search => :get, :open_search_beta => :get }
# tags
@@ -200,9 +201,6 @@
# messages
map.resources :messages, :collection => { :sent => :get, :delete_all_selected => :delete }
- # all ***ship's
- map.resources :memberships, :friendships
-
# all oauth
map.oauth '/oauth',:controller=>'oauth',:action=""
map.authorize '/oauth/authorize',:controller=>'oauth',:action=""
@@ -278,7 +276,6 @@
# map.connect '', :controller => 'users'
# Explicit redirections
- map.connect 'exercise', :controller => 'redirects', :action ="" 'exercise'
map.connect 'google', :controller => 'redirects', :action ="" 'google'
map.connect 'benchmarks', :controller => 'redirects', :action ="" 'benchmarks'
Copied: branches/datasets/db/seeds.rb (from rev 2857, trunk/db/seeds.rb) (0 => 2858)
--- branches/datasets/db/seeds.rb (rev 0)
+++ branches/datasets/db/seeds.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
+# Major.create(:name => 'Daley', :city => cities.first)
Modified: branches/datasets/doc/README_FOR_APP (2857 => 2858)
--- branches/datasets/doc/README_FOR_APP 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/doc/README_FOR_APP 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,2 +1,2 @@
Use this README file to introduce your application and point to useful places in the API for learning more.
-Run "rake appdoc" to generate API documentation for your models and controllers.
\ No newline at end of file
+Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
Property changes: branches/datasets/installers/ubuntu
Added: svn:ignore
Modified: branches/datasets/installers/ubuntu/README.txt (2857 => 2858)
--- branches/datasets/installers/ubuntu/README.txt 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/installers/ubuntu/README.txt 2011-12-01 14:16:25 UTC (rev 2858)
@@ -12,8 +12,8 @@
/bin/bash install.bash
This install script requires the settings file, settings.bash, which needs to be
-kept in th same directory. This can be created by copying the
-default_settings.bash to settings.bash and making the followiing changes
+kept in the same directory. This can be created by copying the
+default_settings.bash to settings.bash and making the following changes
before running install.bash:
myexp_root_password - Choose a password for the root account of MySQL. If for
@@ -23,26 +23,27 @@
myexp_user_password - Choose a password for the account that myExperiment uses
to access databases it creates for storing myExperiment data.
-fq_server_name - The fully-qualified server name for a machine, e.g
-myexperiment.example.org
+fq_server_name - The fully-qualified server name and domain for your server,
+i.e. the A record. E.g. myexperiment.example.org
-exim_smarthost - The mail server you want to user as a relay for emails
-e.g. smtp.example.org
+exim_smarthost_server - The mail server you want to user as a relay for emails.
+E.g. smtp
+exim_smarthost_domain - The mail server you want to user as a relay for emails.
+E.g. example.org
+myexp_cname - The location you intend to host the myExperiment site. This may
+be the same as fq_server_name.
+E.g. myexperiment.example.org
+
+
== Post-installation configuration ==
The installer is designed to work on a freshly installed version of Ubuntu and
will do minimal configuration of myExperiment. To do further configuration
you will need to edit settings.yml in the config directory of the SVN checkout
-of myExperiment by default this /var/rails/myexperiment/config/.
+of myExperiment by default this /var/rails/myexperiment/config/.
-After updating the settings file you will need to restart the myExperiment
-server. To do this go to the file
-/var/rails/myexperiment/tmp/pids/mongrel.pid
-and copy the process id number in this file then run:
+Some configuration may require restarting Apache using the following command:
-kill process_id
-rm /var/rails/myexperiment/tmp/pids/mongrel.pid
-ruby var/rails/myexperiment/script/server -d
-
+sudo apache2ctl restart
Modified: branches/datasets/installers/ubuntu/default_settings.bash (2857 => 2858)
--- branches/datasets/installers/ubuntu/default_settings.bash 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/installers/ubuntu/default_settings.bash 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,34 +1,21 @@
#!/bin/bash
install_dir="/var/rails/myexperiment" # Where to checkout the myExperiment SVN
-mysql_root_password="changme"
+branch="trunk"
+mysql_root_password="changeme"
mysql_user_name="myexp"
mysql_user_password="changeme"
rdoc=1 # Set to 0 if you want no RDoc Ruby Gem documentaion
ri=1 # Set yo 0 if you want no RI Ruby Gem documentatiom
-rake_version="0.7.2"
-rails_version="1.2.6"
+rake_version="0.8.7"
+rails_version="2.3.14"
+passenger_version="2.2.15"
fq_server_name="server.domain"
-exim_smarthost="smtp.domain"
+exim_smarthost_server="smtp"
+exim_smarthost_domain="domain"
+myexp_cname="myexp.domain" # Where your myExperiment will be hosted can be the same as $fq_server_name
+
# Patch Files
-oauth_patch='--- action_controller_request.rb.old 2011-10-26 15:52:34.250151798 +0000
-+++ action_controller_request.rb 2011-10-26 15:50:59.937490274 +0000
-@@ -55,7 +55,13 @@
- end
-
- def request_params
-- request.request_parameters
-+ unless @request_parameters
-+ @request_parameters = request.request_parameters.dup
-+ request.symbolized_path_parameters.keys.each do |k|
-+ @request_parameters.delete k.to_s
-+ end if request.respond_to? :symbolized_path_parameters
-+ end
-+ @request_parameters
- end
-
- end
-'
net_http_patch='Index: lib/net/http.rb
===================================================================
--- lib/net/http.rb (revision 26550)
@@ -41,8 +28,19 @@
+ @socket.close if @socket and not @socket.closed?
raise exception
end'
-settings_patch='--- default_settings.yml 2011-10-26 06:32:16.344994469 +0100
-+++ settings.yml 2011-10-26 06:38:39.788127578 +0100
+
+exim_smarthost="${exim_smarthost_server}.${exim_smarthost_domain}"
+settings_patch='--- default_settings.yml 2011-11-28 18:40:40.337937711 +0000
++++ settings.yml 2011-11-28 19:00:56.231831591 +0000
+@@ -75,7 +75,7 @@
+ #
+ # NOTE: No trailing slash.
+
+-base_uri: http://www.example.com
++base_uri: http://'${myexp_cname}'
+
+ # admins - Set "admins" to the list of usernames of people that are
+ # administrators of this installation. This is "Username" that is set
@@ -302,19 +302,16 @@
# solr_enable - Set solr_enable to true to enable the search facility - this
# requires a running solr server.
@@ -56,25 +54,54 @@
smtp:
- :address: "smtp.example.com"
-+ :address: "relay.ecs.soton.ac.uk"
++ :address: "'${exim_smarthost}'"
:port: 25,
- :domain: ""
- :authentication: :login
- :user_name: "username"
- :password: "password"
-+ :domain: "ecs.soton.ac.uk"
++ :domain: "'${exim_smarthost_domain}'"
# show_debug - Shows query statistics in the footer: "Queries in Controller",
# "Queries in View" and "Query Time".
'
+exim_config="dc_eximconfig_configtype='satellite'
+dc_other_hostnames='${fq_server_name}'
+dc_local_interfaces='127.0.0.1 ; ::1'
+dc_readhost='${fq_server_name}'
+dc_relay_domains=''
+dc_minimaldns='false'
+dc_relay_nets=''
+dc_smarthost='${exim_smarthost}'
+CFILEMODE='644'
+dc_use_split_config='false'
+dc_hide_mailname='true'
+dc_mailname_in_oh='true'
+dc_localdelivery='mail_spool'"
+apache_config="LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-${passenger_version}/ext/apache2/mod_passenger.so
+PassengerRoot /var/lib/gems/1.8/gems/passenger-${passenger_version}
+PassengerRuby /usr/bin/ruby1.8
+RailsEnv development
+
+<VirtualHost *:80>
+ ServerAdmin address@hidden
+ ServerName ${myexp_cname}
+ DocumentRoot ${install_dir}/public
+ <Directory ${install_dir}/public/>
+ AllowOverride all
+ Options -MultiViews
+ </Directory>
+</VirtualHost>"
+
+
# Configure options for (Ruby) gem install
-if [ $rdoc == 0 ]; then
+if [ ${rdoc} == 0 ]; then
nordoc="--no-rdoc"
else
nordoc=""
fi
-if [ $ri == 0 ]; then
+if [ ${ri} == 0 ]; then
nori="--no-ri"
else
nori=""
Modified: branches/datasets/installers/ubuntu/install.bash (2857 => 2858)
--- branches/datasets/installers/ubuntu/install.bash 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/installers/ubuntu/install.bash 2011-12-01 14:16:25 UTC (rev 2858)
@@ -8,7 +8,7 @@
echo ""
settings_file=`dirname $0`/settings.bash
-source $settings_file || { echo "Could not find settings file at $settings_file. Aborting ..."; exit 1; }
+source ${settings_file} || { echo "Could not find settings file at ${settings_file}. Aborting ..."; exit 1; }
echo "Preseeding debconf"
sudo su -c "echo mysql-server-5.1 mysql-server/root_password password `echo "'"``echo ${mysql_root_password}``echo "'"` | debconf-set-selections" || { echo "Could not set debconf option mysql-server-5.1 mysql-server/root_password. Aborting ..."; exit 2; }
@@ -16,93 +16,87 @@
echo "Installing required APT packages"
sudo apt-get update || { echo "Could not update apt-get. Aborting ..."; exit 4; }
-sudo -n apt-get install -y build-essential exim4 ruby ruby1.8-dev libzlib-ruby rdoc irb rubygems rake libapache2-mod-fcgid libfcgi-ruby1.8 libmysql-ruby gcj-4.4-jre-headless subversion libopenssl-ruby1.8 libcurl3 libcurl3-gnutls libcurl4-openssl-dev mysql-server graphicsmagick imagemagick librmagick-ruby1.8 libmagick9-dev graphviz mlocate || { echo "Could not install required APT packages. Aborting ..."; exit 5; }
+sudo -n apt-get install -y build-essential exim4 ruby ruby1.8-dev libzlib-ruby rdoc irb rubygems rake apache2 apache2-dev libapache2-mod-fcgid libfcgi-ruby1.8 libmysql-ruby gcj-4.4-jre-headless subversion libopenssl-ruby1.8 libcurl3 libcurl3-gnutls libcurl4-openssl-dev mysql-server graphicsmagick imagemagick librmagick-ruby1.8 libmagick9-dev graphviz mlocate wget || { echo "Could not install required APT packages. Aborting ..."; exit 5; }
-echo "Installing Rake version $rake_version and Rails version $rails_version Ruby Gems"
-sudo gem install rake $nordoc $nori --version $rake_version || { echo "Could not install Rake Ruby Gem (version $rake_version). Aborting ..."; exit 6; }
-sudo gem install rails $nordoc $nori --version $rails_version || { echo "Could not install Rails Ruby Gem (v$rails_version) and dependencies. Aborting ..."; exit 7; }
+echo "Installing Rake version ${rake_version} and Rails version ${rails_version} Ruby Gems"
+sudo gem install rake ${nordoc} ${nori} --version ${rake_version} || { echo "Could not install Rake Ruby Gem (version ${rake_version}). Aborting ..."; exit 6; }
+sudo gem install rails ${nordoc} ${nori} --version ${rails_version} || { echo "Could not install Rails Ruby Gem (v${rails_version}) and dependencies. Aborting ..."; exit 7; }
echo "Installing Ruby Gems required by myExperiment"
if [ `cat /etc/environment | grep "/var/lib/gems/1.8/bin" | wc -l` -eq 0 ]; then
cat /etc/environment | sed "s/\"$/:\/var\/lib\/gems\/1.8\/bin\"/" | sudo tee /etc/environment > /dev/null || { echo "Could not add Gems path to PATH. Aborting ..."; exit 8;}
fi
-if [ `echo $PATH | grep "/var/lib/gems/1.8/bin" | wc -l` -eq 0 ]; then
- DOLLAR='$'; echo -e "export PATH=${DOLLAR}PATH:/var/lib/gems/1.8/bin\nalias sudo='sudo env PATH=${DOLLAR}PATH'" >> /home/$USER/.bashrc || { echo "Could not write to /home/$USER/.bashrc. Aborting ..."; exit 9;}
- export PATH=$PATH:/var/lib/gems/1.8/bin
+if [ `echo ${PATH} | grep "/var/lib/gems/1.8/bin" | wc -l` -eq 0 ]; then
+ DOLLAR='$'; echo -e "export PATH=${DOLLAR}PATH:/var/lib/gems/1.8/bin\nalias sudo='sudo env PATH=${DOLLAR}PATH'" >> /home/${USER}/.bashrc || { echo "Could not write to /home/${USER}/.bashrc. Aborting ..."; exit 9;}
+ source /home/${USER}/.bashrc || { echo "Could not source /home/${USER}/.bashrc. Aborting ..."; exit 10; }
fi
-sudo gem install $nordoc $nori cgi_multipart_eof_fix daemons dsl_accessor fastthread gem_plugin json mime-types mongrel mongrel_cluster needle net-sftp net-ssh openid_login_generator RedCloth ruby-yadis rubyzip solr-ruby xml-simple libxml-ruby oauth ruby-hmac openurl curb marc taverna-scufl taverna-t2flow || { echo "Could not install all remaining generic Ruby Gems required by myExperiment. Aborting ..."; exit 10; }
-sudo gem install rmagick $nordoc $nori --version=1.15.14 || { echo "Could not install RMagick Ruby Gem. Aborting ..."; exit 11; }
+sudo gem install ${nordoc} ${nori} mongrel_cluster rubyzip oauth libxml-ruby rmagick dsl_accessor ruby-openid openurl curb marc || { echo "Could not install all remaining generic Ruby Gems required by myExperiment. Aborting ..."; exit 11; }
-echo "Making OAuth Ruby Gem compatible with Rails $version"
+echo "Making OAuth Ruby Gem compatible with Rails ${rails_version}"
tempdir=$(mktemp -d /tmp/myexp_installer.XXXXXXXXXX) || { echo "Could not create temporary file for writing patches to. Aborting ..."; exit 12; }
-cd $tempdir || { echo "Could not find temporary directory. Aborting ..."; exit 13; }
-echo "$oauth_patch" > oauth.patch || { echo "Could not write oauth patch file. Aborting ..."; exit 14; }
-echo "$net_http_patch" > net_http.patch || { echo "Could not write net/http patch file. Aborting ..."; exit 15; }
-echo "$settings_patch" > settings.patch || { echo "Could not write settings patch file. Aborting ..."; exit 16; }
-sudo updatedb || { echo "Could not run updatedb so that OAuth Ruby Gem file that needs updating can be located. Aborting ..."; exit 17; }
-oauth_file=`locate lib/oauth/request_proxy/action_controller_request.rb`
-if [ ! -e $oauth_file ]; then
- echo "Could not locate OAuth Ruby Gem file that requires updating. Aborting ..."; exit 18;
-fi
-sudo patch $oauth_file $tempdir/oauth.patch || { echo "Could not patch OAuth Ruby Gem file: $oauth_file. Aborting ..."; exit 19; }
+cd ${tempdir} || { echo "Could not find temporary directory. Aborting ..."; exit 13; }
+echo "${net_http_patch}" > net_http.patch || { echo "Could not write net/http patch file. Aborting ..."; exit 14; }
+echo "${settings_patch}" > settings.patch || { echo "Could not write settings patch file. Aborting ..."; exit 15; }
+sudo updatedb || { echo "Could not run updatedb so that http.rb that needs updating can be located. Aborting ..."; exit 16; }
net_http_file=`locate net/http.rb`
-if [ ! -e $net_http_file ]; then
- echo "Could not locate net/http Ruby file that requires updating. Aborting ..."; exit 20;
+if [ ! -e ${net_http_file} ]; then
+ echo "Could not locate net/http Ruby file that requires updating. Aborting ..."; exit 17;
fi
-sudo patch $net_http_file $tempdir/net_http.patch || { echo "Could not patch net/http Ruby file: $net_http_file. Aborting ..."; exit 21; }
+sudo patch ${net_http_file} ${tempdir}/net_http.patch || { echo "Could not patch net/http Ruby file: ${net_http_file}. Aborting ..."; exit 18; }
echo "Checking out myExperiment codebase from SVN"
cd /
-for idir in `echo $install_dir | awk 'BEGIN{RS="/"}{print $1}'`; do
- if [ -n $idir ]; then
- sudo mkdir $idir
- cd $idir
+for idir in `echo ${install_dir} | awk 'BEGIN{RS="/"}{print $1}'`; do
+ if [ -n ${idir} ]; then
+ if [ ! -d ${idir} ]; then
+ sudo mkdir ${idir} || { echo "Could not create directory ${idir} in `pwd`. Aborting ..."; exit 19; }
+ fi
+ cd ${idir}
fi
done
-sudo chown $USER:www-data $install_dir || { echo "Could not update permissions on $install_dir. Aborting ..."; exit 22; }
-svn checkout svn://rubyforge.org/var/svn/myexperiment/trunk $install_dir || { echo "Could not checkout SVN to $install_dir. Aborting ..."; exit 23; }
-cd ${install_dir}/config/ || { echo "Could not find config directory for myExperiment. Aborting ..."; exit 24; }
+sudo chown ${USER}:www-data ${install_dir} || { echo "Could not update permissions on ${install_dir}. Aborting ..."; exit 20; }
+svn checkout svn://rubyforge.org/var/svn/myexperiment/${branch} ${install_dir} || { echo "Could not checkout SVN to ${install_dir}. Aborting ..."; exit 21; }
+cd ${install_dir}/config/ || { echo "Could not find config directory for myExperiment. Aborting ..."; exit 22; }
echo "Setting up config files for myExperiment"
-cat database.yml.pre | sed "s/username: root/username: $mysql_user_name/" | sed "s/password:/password: $mysql_user_password/" > database.yml || { echo "Could not create database.yml file with appropriate configuration settings. Aborting ..."; exit 25; }
-cp default_settings.yml settings.yml || { echo "Could not copy default_settings.yml to settings.yml ..."; exit 26; }
-patch settings.yml $tempdir/settings.patch || { echo "Could not patch settings.yml. Aborting ..."; exit 27; }
-cp captcha.yml.pre captcha.yml || { echo "Could not create captcha.yml file. Aborting ..."; exit 28; }
+cat database.yml.pre | sed "s/username: root/username: ${mysql_user_name}/" | sed "s/password:/password: ${mysql_user_password}/" > database.yml || { echo "Could not create database.yml file with appropriate configuration settings. Aborting ..."; exit 23; }
+cp default_settings.yml settings.yml || { echo "Could not copy default_settings.yml to settings.yml ..."; exit 24; }
+patch settings.yml ${tempdir}/settings.patch || { echo "Could not patch settings.yml. Aborting ..."; exit 25; }
+cp captcha.yml.pre captcha.yml || { echo "Could not create captcha.yml file. Aborting ..."; exit 26; }
cd ..
-echo "Setting up exim4 (Email) for myExperiment"
-echo "dc_eximconfig_configtype='satellite'
-dc_other_hostnames='${fq_server_name}'
-dc_local_interfaces='127.0.0.1 ; ::1'
-dc_readhost='${fq_server_name}'
-dc_relay_domains=''
-dc_minimaldns='false'
-dc_relay_nets=''
-dc_smarthost='${exim_smarthost}'
-CFILEMODE='644'
-dc_use_split_config='false'
-dc_hide_mailname='true'
-dc_mailname_in_oh='true'
-dc_localdelivery='mail_spool'" | sudo tee /etc/exim4/update-exim4.conf.conf > /dev/null || { echo "Could not write new exim4 config. Aborting..."; exit 29; }
-echo "${fq_server_name}" | sudo tee /etc/mailname > /dev/null || { echo "Could not update hostname for /etc/mailname. Aborting..."; exit 30; }
-sudo dpkg-reconfigure -fnoninteractive exim4-config || { echo "Could not write new reconfingure exim4. Aborting..."; exit 31; }
+echo "Setting up exim (Email) for myExperiment"
+echo "${exim_config}" | sudo tee /etc/exim4/update-exim4.conf.conf > /dev/null || { echo "Could not write new exim4 config. Aborting..."; exit 27; }
+echo "${fq_server_name}" | sudo tee /etc/mailname > /dev/null || { echo "Could not update hostname for /etc/mailname. Aborting..."; exit 28; }
+sudo dpkg-reconfigure -fnoninteractive exim4-config || { echo "Could not write new reconfingure exim4. Aborting..."; exit 29; }
echo "Setting up myExperiment databases in MySQL"
-mysql -u root -p$mysql_root_password -e "CREATE USER '$mysql_user_name'@'localhost' IDENTIFIED BY '$mysql_user_password'; CREATE DATABASE m2_development; CREATE DATABASE m2_production; CREATE DATABASE m2_test; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP,CREATE TEMPORARY TABLES,CREATE VIEW,SHOW VIEW ON m2_development . * TO '$mysql_user_name'@'localhost';GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP,CREATE TEMPORARY TABLES,CREATE VIEW,SHOW VIEW ON m2_production . * TO '$mysql_user_name'@'localhost';GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP,CREATE TEMPORARY TABLES,CREATE VIEW,SHOW VIEW ON m2_test . * TO '$mysql_user_name'@'localhost';" || { echo "Could not create myExperiment databases in MySQL and set up appropriate access for the $mysql_user_name user. Aborting ..."; exit 32; }
+mysql -u root -p${mysql_root_password} -e "CREATE USER '${mysql_user_name}'@'localhost' IDENTIFIED BY '${mysql_user_password}'; CREATE DATABASE m2_development; CREATE DATABASE m2_production; CREATE DATABASE m2_test; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP,CREATE TEMPORARY TABLES,CREATE VIEW,SHOW VIEW ON m2_development . * TO '${mysql_user_name}'@'localhost';GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP,CREATE TEMPORARY TABLES,CREATE VIEW,SHOW VIEW ON m2_production . * TO '${mysql_user_name}'@'localhost';GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP,CREATE TEMPORARY TABLES,CREATE VIEW,SHOW VIEW ON m2_test . * TO '${mysql_user_name}'@'localhost';" || { echo "Could not create myExperiment databases in MySQL and set up appropriate access for the ${mysql_user_name} user. Aborting ..."; exit 30; }
echo "Migrating myExperiment database"
-rake db:migrate || { echo "Could not migrate myExperiment data model to a MySQL database. Aborting ..."; exit 33; }
+rake db:migrate || { echo "Could not migrate myExperiment data model to a MySQL database. Aborting ..."; exit 31; }
echo "Starting Solr (search) server and indexing"
-rake solr:start || { echo "Could not start Solr server. Aborting ..."; exit 34; }
+rake solr:start || { echo "Could not start Solr server. Aborting ..."; exit 32; }
-echo "Starting Mongrel webserver as a daemon running myExperiment website"
-ruby script/server -d || { echo "Could not start Mongrel Webserver for myExperiment website. Aborting ..."; exit 35; }
+echo "Installing and configuring Passenger Gem (mod_rails)";
+sudo gem install passenger --version ${passenger_version} || { echo "Could not install Passnger Gem version ${passenger_version}. Aborting ..."; exit 33; }
+sudo su -c "yes | /var/lib/gems/1.8/bin/passenger-install-apache2-module" || { echo "Could not install Apache2 module for Passenger. Aborting ..."; exit 34; }
+echo "${apache_config}" | sudo tee /etc/apache2/sites-available/myexperiment > /dev/null || { echo "Could not add bespoke myExperiment Apache configuration. Aborting ..."; exit 35; }
+if [ ! -h /etc/apache2/sites-enabled/myexperiment ]; then
+ sudo ln -s /etc/apache2/sites-available/myexperiment /etc/apache2/sites-enabled/myexperiment || { echo "Could symlink Apache configuration to sites-enabled."; exit 36; }
+fi
+if [ -f "/etc/apache2/sites-enabled/000-default" ]; then
+ sudo rm /etc/apache2/sites-enabled/000-default || { echo "Could not remove 000-default to sites-enabled. Aborting ..."; exit 37; }
+fi
+sudo apache2ctl stop || { echo "Could not stop Apache2. Aborting ..."; exit 38; }
+sleep 2
+sudo apache2ctl start || { echo "Could not start Apache2. Aborting ..."; exit 39; }
echo "Removing temporary directory created for writing patch files to"
-sudo rm -rf $tempdir || { echo "Could not remove temporary directory used by patch files."; echo exit 36; }
+sudo rm -rf ${tempdir} || { echo "Could not remove temporary directory used by patch files."; exit 40; }
-echo "+--------------------------------------------------------------------------------------------+"
-echo "| myExperiment is now fully installed. Go to http://localhost:3000 to use myExperiment |"
-echo "| Or substitute for the server name if you have installed myExperiment on a separate server |"
-echo "+--------------------------------------------------------------------------------------------+"
+echo ""
+echo "+-----------------------------------------------------------------------------------------+"
+echo "| myExperiment is now fully installed. Go to http://$myexp_cname/ to use myExperiment |"
+echo "+-----------------------------------------------------------------------------------------+"
Modified: branches/datasets/lib/authenticated_system.rb (2857 => 2858)
--- branches/datasets/lib/authenticated_system.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/authenticated_system.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -105,7 +105,7 @@
# Redirect to the URI stored by the most recent store_location call or
# to the passed default.
def redirect_back_or_default(default)
- session[:return_to] ? redirect_to_url(session[:return_to]) : redirect_to(default)
+ session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(default)
session[:return_to] = nil
end
Modified: branches/datasets/lib/authorization.rb (2857 => 2858)
--- branches/datasets/lib/authorization.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/authorization.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -329,7 +329,7 @@
unless found_thing
# search didn't yield any results - the "thing" wasn't found; can't authorize unknown objects
- logger.error("UNEXPECTED ERROR - Couldn't find object to be authorized:(#{thing_type}, #{thing_id}); action: #{action_name}; user: #{user_id}")
+ Rails.logger.error("UNEXPECTED ERROR - Couldn't find object to be authorized:(#{thing_type}, #{thing_id}); action: #{action_name}; user: #{user_id}")
return false
else
if (["Contribution"] + Conf.contributable_models).include?(thing_type)
@@ -790,8 +790,8 @@
# original contributor not found, but the Contribution entry still exists -
# this is an error in associations then, because all dependent items
# should have been deleted along with the contributor entry; log the error
- logger.error("UNEXPECTED ERROR - Contributor object missing for an existing contribution: (#{thing_contribution.class.name}, #{thing_contribution.id})")
- logger.error("EXCEPTION:" + e)
+ Rails.logger.error("UNEXPECTED ERROR - Contributor object missing for an existing contribution: (#{thing_contribution.class.name}, #{thing_contribution.id})")
+ Rails.logger.error("EXCEPTION:" + e)
return nil
end
end
Modified: branches/datasets/lib/conf.rb (2857 => 2858)
--- branches/datasets/lib/conf.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/conf.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -49,6 +49,10 @@
end
end
+ def self.hostname
+ self.base_uri.sub(/https?:\/\//, '')
+ end
+
def self.admins
self.fetch_entry('admins')
end
@@ -165,6 +169,14 @@
self.fetch_entry('recaptcha_private')
end
+ def self.session_store_secret
+ self.fetch_entry('session_store_secret')
+ end
+
+ def self.cookie_verifier_secret
+ self.fetch_entry('cookie_verifier_secret')
+ end
+
def self.layouts
#TODO: Perhaps implement code that can load different/extra settings files based on current environment
layouts = self.fetch_entry('layouts')
Copied: branches/datasets/lib/tasks/acts_as_bookmarkable_tasks.rake (from rev 2857, trunk/lib/tasks/acts_as_bookmarkable_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/acts_as_bookmarkable_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/acts_as_bookmarkable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :acts_as_bookmarkable do
+# # Task goes here
+# end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/acts_as_commentable_tasks.rake (from rev 2857, trunk/lib/tasks/acts_as_commentable_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/acts_as_commentable_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/acts_as_commentable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :acts_as_commentable do
+# # Task goes here
+# end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/acts_as_rateable_tasks.rake (from rev 2857, trunk/lib/tasks/acts_as_rateable_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/acts_as_rateable_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/acts_as_rateable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :acts_as_rateable do
+# # Task goes here
+# end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/acts_as_taggable_tasks.rake (from rev 2857, trunk/lib/tasks/acts_as_taggable_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/acts_as_taggable_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/acts_as_taggable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,19 @@
+# namespace :acts_as_taggable do
+# require 'rails_generator'
+# require 'rails_generator/scripts/generate'
+#
+# namespace :db do
+# desc "Creates tag tables for use with acts_as_taggable"
+# task :create => :environment do
+# raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
+# Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_tables", "add_acts_as_taggable_tables" ])
+# end
+# end
+#
+# namespace :stylesheet do
+# desc "Create tag stylesheet for use with acts_as_taggable"
+# task :create do
+# Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_stylesheet" ])
+# end
+# end
+# end
Copied: branches/datasets/lib/tasks/fckeditor_tasks.rake (from rev 2857, trunk/lib/tasks/fckeditor_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/fckeditor_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/fckeditor_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,97 @@
+# desc "Explaining what the task does"
+# task :fckeditor do
+# # Task goes here
+# end
+
+namespace :fckeditor do
+ def setup
+ require "config/environment"
+ require 'fileutils'
+
+ directory = File.join(RAILS_ROOT, '/vendor/plugins/fckeditor/')
+ require "#{directory}lib/fckeditor"
+ require "#{directory}lib/fckeditor_version"
+ require "#{directory}lib/fckeditor_file_utils"
+ end
+
+ desc 'Install the FCKEditor components'
+ task :install do
+ setup
+ puts "** Installing FCKEditor Plugin version #{FckeditorVersion.current}..."
+
+ FckeditorFileUtils.destroy_and_install
+
+ puts "** Successfully installed FCKEditor Plugin version #{FckeditorVersion.current}"
+ end
+
+ def fetch(path)
+ response = Net::HTTP.get_response(URI.parse(path))
+ case response
+ when Net::HTTPSuccess then
+ response
+ when Net::HTTPRedirection then
+ puts "** Redirected to #{response['location']}"
+ fetch(response['location'])
+ else
+ response.error!
+ end
+ end
+
+ desc "Update the FCKEditor code to the latest nightly build"
+ task :download do
+ require 'net/http'
+ require 'zip/zipfilesystem'
+
+ setup
+ version = ENV['VERSION'] || "Nightly"
+ installed_version = "2.4.2"
+
+ puts "** Current FCKEditor version: #{installed_version}..."
+ puts "** Downloading #{version} (1.2mb - please be patient)..."
+
+ rails_tmp_path = File.join(RAILS_ROOT, "/tmp/")
+ tmp_zip_path = File.join(rails_tmp_path, "fckeditor_#{version}.zip")
+
+ # Creating tmp dir if it doesn't exist
+ Dir.mkdir(rails_tmp_path) unless File.exists? rails_tmp_path
+
+ # Download nightly build (http://www.fckeditor.net/nightly/FCKeditor_N.zip)
+ # Releases (http://downloads.sourgefourge.net/fckeditor/FCKEditor_[2.4.3, 2.5b, 2.4.2].zip)
+ nightly = version=='Nightly' ? true : false
+ domain = nightly ? "http://www.fckeditor.net" : "http://downloads.sourceforge.net"
+ path = nightly ? "/nightly/FCKeditor_N.zip" : "/fckeditor/FCKeditor_#{version}.zip"
+
+ puts "** Download from #{domain}#{path}"
+ #Net::HTTP.start(domain) { |http|
+ response = fetch("#{domain}#{path}")
+
+ open(tmp_zip_path, "wb") { |file|
+ file.write(response.body)
+ }
+ #}
+ puts "** Download successful"
+
+ puts "** Extracting FCKeditor"
+ Zip::ZipFile.open(tmp_zip_path) do |zipfile|
+ zipfile.each do |entry|
+ filename = File.join(rails_tmp_path, entry.name)
+ FileUtils.rm_f(filename)
+ FileUtils.mkdir_p(File.dirname(filename))
+ entry.extract(filename)
+ end
+ end
+
+ puts "** Backing up existing FCKEditor install to /public/_javascript_s/fckeditor_bck"
+ FckeditorFileUtils.backup_existing
+
+ puts "** Shifting files to /public/_javascript_s/fckeditor"
+ FileUtils.cp_r File.join(RAILS_ROOT, "/tmp/fckeditor/"), File.join(RAILS_ROOT, "/public/_javascript_s/")
+
+ puts "** Clean up"
+ FileUtils.remove_file(tmp_zip_path, true)
+ FileUtils.remove_entry(File.join(rails_tmp_path, "fckeditor/"), true)
+
+ puts "** Successfully updated to FCKEditor version: #{version}..."
+ end
+end
+
Copied: branches/datasets/lib/tasks/oauth_tasks.rake (from rev 2857, trunk/lib/tasks/oauth_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/oauth_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/oauth_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :oauth do
+# # Task goes here
+# end
Copied: branches/datasets/lib/tasks/open_id_authentication_tasks.rake (from rev 2857, trunk/lib/tasks/open_id_authentication_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/open_id_authentication_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/open_id_authentication_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,16 @@
+namespace :open_id_authentication do
+ namespace :db do
+ desc "Creates authentication tables for use with OpenIdAuthentication"
+ task :create => :environment do
+ raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
+ require 'rails_generator'
+ require 'rails_generator/scripts/generate'
+ Rails::Generator::Scripts::Generate.new.run([ "open_id_authentication_tables", "add_open_id_authentication_tables" ])
+ end
+
+ desc "Clear the authentication tables"
+ task :clear => :environment do
+ OpenIdAuthentication::DbStore.gc
+ end
+ end
+end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/qrcode_tasks.rake (from rev 2857, trunk/lib/tasks/qrcode_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/qrcode_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/qrcode_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :qrcode do
+# # Task goes here
+# end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/recaptcha_tasks.rake (from rev 2857, trunk/lib/tasks/recaptcha_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/recaptcha_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/recaptcha_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :recaptcha do
+# # Task goes here
+# end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/structured_data_tasks.rake (from rev 2857, trunk/lib/tasks/structured_data_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/structured_data_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/structured_data_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :structured_data do
+# # Task goes here
+# end
Copied: branches/datasets/lib/tasks/validates_captcha_tasks.rake (from rev 2857, trunk/lib/tasks/validates_captcha_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/validates_captcha_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/validates_captcha_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :validates_captcha do
+# # Task goes here
+# end
\ No newline at end of file
Copied: branches/datasets/lib/tasks/widgets_tasks.rake (from rev 2857, trunk/lib/tasks/widgets_tasks.rake) (0 => 2858)
--- branches/datasets/lib/tasks/widgets_tasks.rake (rev 0)
+++ branches/datasets/lib/tasks/widgets_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :widgets do
+# # Task goes here
+# end
\ No newline at end of file
Modified: branches/datasets/lib/workflow_processors/bio_extract.rb (2857 => 2858)
--- branches/datasets/lib/workflow_processors/bio_extract.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/workflow_processors/bio_extract.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -42,7 +42,7 @@
file.rewind
return !bioextract_model.nil?
rescue
- logger.info($!)
+ Rails.logger.info $!
return false
end
end
Modified: branches/datasets/lib/workflow_processors/galaxy.rb (2857 => 2858)
--- branches/datasets/lib/workflow_processors/galaxy.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/workflow_processors/galaxy.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -176,7 +176,7 @@
workflow
rescue
- logger.info $!
+ Rails.logger.info $!
nil
end
end
Modified: branches/datasets/lib/workflow_processors/rapid_miner.rb (2857 => 2858)
--- branches/datasets/lib/workflow_processors/rapid_miner.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/workflow_processors/rapid_miner.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -45,7 +45,7 @@
file.rewind
return !rapid_miner_model.nil?
rescue
- logger.info $!
+ Rails.logger.info $!
return false
end
end
@@ -291,7 +291,7 @@
package
rescue
- logger.info $!
+ Rails.logger.info $!
nil
end
end
Modified: branches/datasets/lib/workflow_processors/trident_opc.rb (2857 => 2858)
--- branches/datasets/lib/workflow_processors/trident_opc.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/workflow_processors/trident_opc.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -29,23 +29,43 @@
# All the file extensions supported by this workflow processor.
# Must be all in lowercase.
def self.file_extensions_supported
- [ "zip" ]
+ [ "zip", "twp" ]
end
def self.can_determine_type_from_file?
- false
+ true
end
+ # It is not possible to give a 100% gurantee that a file is a valid trident package
+ # unless each zip entry is read for structure.
+ # This method thus makes sure if the package file is a valid zip file and then checks
+ # if it is atleast a valid OPC package by checking for a mandatory root file Content_Types,xml
def self.recognised?(file)
- false
+ begin
+ zipfile = Tempfile.new('package.zip')
+ zipfile.binmode
+
+ zipfile.print(file.read)
+ zipfile.close
+
+ Zip::ZipFile.open(zipfile.path, Zip::ZipFile::CREATE) {
+ |file1|
+ if nil == file1.get_entry('[Content_Types].xml')
+ return false
+ end
+ return true
+ }
+ rescue
+ return false
+ end
end
def self.can_infer_metadata?
- false
+ true
end
def self.can_generate_preview_image?
- false
+ true
end
def self.can_generate_preview_svg?
@@ -58,18 +78,106 @@
# Begin Object Initializer
def initialize(workflow_definition)
+
super(workflow_definition)
+
+ # Check if the zip file exists. If yes then remove it
+ zipfile = Tempfile.new('package.zip')
+ zipfile.binmode
+
+ @filename = zipfile.path
+ zipfile.print(workflow_definition)
+
end
# End Object Initializer
+ def filename
+ @filename = ''
+ end
-
# Begin Instance Methods
-
# These provide more specific functionality for a given workflow definition, such as parsing for metadata and image generation.
+ def get_title
+ Zip::ZipInputStream::open(@filename) {
+ |io|
+
+ while (entry = io.get_next_entry)
+ if entry.name.match('^.*/ActivityKind/.*xml$')
+ xml = io.read
+ doc, statuses = REXML::Document.new(xml), []
+ doc.elements.each('/ObjectDetails/Type') do |s1|
+ if s1.text.match('Root')
+ doc.elements.each('/ObjectDetails/Label') do |s|
+ return s.text
+ end
+ end
+ end
+ end
+ end
+ }
+ rescue
+ return ''
+ end
+ def get_description
+ Zip::ZipInputStream::open(@filename) {
+ |io|
+
+ while (entry = io.get_next_entry)
+ if entry.name.match('^.*/ActivityKind/.*xml$')
+ xml = io.read
+ doc, statuses = REXML::Document.new(xml), []
+ doc.elements.each('/ObjectDetails/Type') do |s1|
+ if s1.text.match('Root')
+ doc.elements.each('/ObjectDetails/Description') do |s|
+ return s.text
+ end
+ end
+ end
+ end
+ end
+ }
+ rescue
+ return ''
+ end
+ def get_search_terms
+ Zip::ZipInputStream::open(@filename) {
+ |io|
+
+ while (entry = io.get_next_entry)
+ if entry.name.match('^.*/ActivityKind/.*xml$')
+ xml = io.read
+ doc, statuses = REXML::Document.new(xml), []
+ doc.elements.each('/ObjectDetails/Type') do |s1|
+ if s1.text.match('Root')
+ doc.elements.each('/ObjectDetails/Keywords') do |s|
+ return s.text
+ end
+ end
+ end
+ end
+ end
+ }
+
+ rescue
+ return ''
+ end
+
+ def get_preview_image
+ Zip::ZipInputStream::open(@filename) {
+ |io|
+ while (entry = io.get_next_entry)
+ if entry.name.match('/MyExp/Image/')
+ return entry
+ end
+ end
+ }
+ rescue
+ return nil
+ end
+
# End Instance Methods
end
end
Modified: branches/datasets/lib/workflow_types_handler.rb (2857 => 2858)
--- branches/datasets/lib/workflow_types_handler.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/lib/workflow_types_handler.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -5,6 +5,9 @@
# Helper class to deal with Workflow types and processors.
# Note that workflow types can exist that don't have corresponding processors.
+
+require 'lib/workflow_processors/interface'
+
class WorkflowTypesHandler
# Gets all the workflow processor classes that have been defined in the \lib\workflow_processors directory.
@@ -135,7 +138,7 @@
end
# Load up the processor classes at startup
-logger.debug("Workflow type processors found: " + WorkflowTypesHandler.processor_classes.to_sentence)
+Rails.logger.debug("Workflow type processors found: " + WorkflowTypesHandler.processor_classes.to_sentence)
# Refresh the list of workflow types in the system
WorkflowTypesHandler.refresh_all_known_types!
Deleted: branches/datasets/public/.htaccess (2857 => 2858)
--- branches/datasets/public/.htaccess 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/.htaccess 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,40 +0,0 @@
-# General Apache options
-AddHandler fastcgi-script .fcgi
-AddHandler cgi-script .cgi
-Options +FollowSymLinks +ExecCGI
-
-# If you don't want Rails to look in certain directories,
-# use the following rewrite rules so that Apache won't rewrite certain requests
-#
-# Example:
-# RewriteCond %{REQUEST_URI} ^/notrails.*
-# RewriteRule .* - [L]
-
-# Redirect all requests not available on the filesystem to Rails
-# By default the cgi dispatcher is used which is very slow
-#
-# For better performance replace the dispatcher with the fastcgi one
-#
-# Example:
-# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
-RewriteEngine On
-
-# If your Rails application is accessed via an Alias directive,
-# then you MUST also set the RewriteBase in this htaccess file.
-#
-# Example:
-# Alias /myrailsapp /path/to/myrailsapp/public
-# RewriteBase /myrailsapp
-
-RewriteRule ^$ index.html [QSA]
-RewriteRule ^([^.]+)$ $1.html [QSA]
-RewriteCond %{REQUEST_FILENAME} !-f
-RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
-
-# In case Rails experiences terminal errors
-# Instead of displaying this message you can supply a file here which will be rendered instead
-#
-# Example:
-# ErrorDocument 500 /500.html
-
-ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
\ No newline at end of file
Copied: branches/datasets/public/422.html (from rev 2857, trunk/public/422.html) (0 => 2858)
--- branches/datasets/public/422.html (rev 0)
+++ branches/datasets/public/422.html 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <title>The change you wanted was rejected (422)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
+</head>
+
+<body>
+ <!-- This file lives in public/422.html -->
+ <div class="dialog">
+ <h1>The change you wanted was rejected.</h1>
+ <p>Maybe you tried to change something you didn't have access to.</p>
+ </div>
+</body>
+</html>
\ No newline at end of file
Modified: branches/datasets/public/500.html (2857 => 2858)
--- branches/datasets/public/500.html 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/500.html 2011-12-01 14:16:25 UTC (rev 2858)
@@ -5,7 +5,7 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
- <title>We're sorry, but something went wrong</title>
+ <title>We're sorry, but something went wrong (500)</title>
<style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
div.dialog {
@@ -27,4 +27,4 @@
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
</div>
</body>
-</html>
\ No newline at end of file
+</html>
Deleted: branches/datasets/public/dispatch.cgi (2857 => 2858)
--- branches/datasets/public/dispatch.cgi 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/dispatch.cgi 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,10 +0,0 @@
-#!/usr/local/bin/ruby
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
Deleted: branches/datasets/public/dispatch.fcgi (2857 => 2858)
--- branches/datasets/public/dispatch.fcgi 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/dispatch.fcgi 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,24 +0,0 @@
-#!C:/InstantRails/ruby/bin/ruby
-#
-# You may specify the path to the FastCGI crash log (a log of unhandled
-# exceptions which forced the FastCGI instance to exit, great for debugging)
-# and the number of requests to process before running garbage collection.
-#
-# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
-# and the GC period is nil (turned off). A reasonable number of requests
-# could range from 10-100 depending on the memory footprint of your app.
-#
-# Example:
-# # Default log path, normal GC behavior.
-# RailsFCGIHandler.process!
-#
-# # Default log path, 50 requests between GC.
-# RailsFCGIHandler.process! nil, 50
-#
-# # Custom log path, normal GC behavior.
-# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
-#
-require File.dirname(__FILE__) + "/../config/environment"
-require 'fcgi_handler'
-
-RailsFCGIHandler.process!
Deleted: branches/datasets/public/dispatch.rb (2857 => 2858)
--- branches/datasets/public/dispatch.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/dispatch.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,10 +0,0 @@
-#!C:/InstantRails/ruby/bin/ruby
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
\ No newline at end of file
Modified: branches/datasets/public/images/rails.png
(Binary files differ)
Modified: branches/datasets/public/_javascript_s/application.js (2857 => 2858)
--- branches/datasets/public/_javascript_s/application.js 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/_javascript_s/application.js 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,113 +1,2 @@
// Place your application-specific _javascript_ functions and classes here
// This file is automatically included by _javascript__include_tag :defaults
-
-// http://labnol.blogspot.com/2006/01/add-to-favorites-ie-bookmark-firefox.html
-function CreateBookmarkLink() {
-
-title = "<%=h title %>";
-url = "" url %>";
-
-if (window.sidebar) { // Mozilla Firefox Bookmark
- window.sidebar.addPanel(title, url,"");
-} else { // IE, Opera, etc
- return true;
-}
-}
-
-var TopicForm = {
- editNewTitle: function(txtField) {
- $('new_topic').innerHTML = (txtField.value.length > 5) ? txtField.value : 'New Topic';
- }
-}
-
-var LoginForm = {
- checkLogin: function(txt) {
- if(txt.value.match(/^https?:\/\//)) {
- $('password_fields').hide();
- } else {
- $('password_fields').show();
- }
- }
-}
-
-var EditForm = {
- // show the form
- init: function(postId) {
- $('edit-post-' + postId + '_spinner').show();
- this.clearReplyId();
- },
-
- // sets the current post id we're editing
- setReplyId: function(postId) {
- $('edit').setAttribute('post_id', postId.toString());
- $('posts-' + postId + '-row').addClassName('editing');
- if($('reply')) $('reply').hide();
- },
-
- // clears the current post id
- clearReplyId: function() {
- var currentId = this.currentReplyId()
- if(!currentId || currentId == '') return;
-
- var row = $('posts-' + currentId + '-row');
- if(row) row.removeClassName('editing');
- $('edit').setAttribute('post_id', '');
- },
-
- // gets the current post id we're editing
- currentReplyId: function() {
- return $('edit').getAttribute('post_id');
- },
-
- // checks whether we're editing this post already
- isEditing: function(postId) {
- if (this.currentReplyId() == postId.toString())
- {
- $('edit').show();
- $('edit_post_body').focus();
- return true;
- }
- return false;
- },
-
- // close reply, clear current reply id
- cancel: function() {
- this.clearReplyId();
- $('edit').hide()
- }
-}
-
-var ReplyForm = {
- // yes, i use setTimeout for a reason
- init: function() {
- EditForm.cancel();
- $('reply').toggle();
- $('post_body').focus();
- // for Safari which is sometime weird
-// setTimeout('$(\"post_body\").focus();',50);
- }
-}
-
-//Event.addBehavior({
-// '#search,#monitor_submit': function() { this.hide(); }
-//})
-
-function redirectToAddToPack() {
- var url = ""
- location.href = ""
-}
-
-function checkAll(checkboxes){
- for (var i=0; i<checkboxes.length; i++){
- checkbox = document.getElementById(checkboxes[i]);
- checkbox.checked="checked";
- }
-}
-
-function uncheckAll(checkboxes){
- for (var i=0; i<checkboxes.length; i++){
- checkbox = document.getElementById(checkboxes[i]);
- checkbox.checked="";
- }
-}
-
Modified: branches/datasets/public/_javascript_s/controls.js (2857 => 2858)
--- branches/datasets/public/_javascript_s/controls.js 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/_javascript_s/controls.js 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,22 +1,22 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-// (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
+// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
// Contributors:
// Richard Livsey
// Rahul Bhargava
// Rob Wills
-//
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
-// Autocompleter.Base handles all the autocompletion functionality
+// Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar.
//
-// Specific autocompleters need to provide, at the very least,
+// Specific autocompleters need to provide, at the very least,
// a getUpdatedChoices function that will be invoked every time
-// the text inside the monitored textbox changes. This method
+// the text inside the monitored textbox changes. This method
// should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized
@@ -30,68 +30,71 @@
// will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which
-// enables autocompletion on multiple tokens. This is most
-// useful when one of the tokens is \n (a newline), as it
+// enables autocompletion on multiple tokens. This is most
+// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.
if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library");
-var Autocompleter = {}
-Autocompleter.Base = function() {};
-Autocompleter.Base.prototype = {
+var Autocompleter = { };
+Autocompleter.Base = Class.create({
baseInitialize: function(element, update, options) {
- this.element = $(element);
- this.update = $(update);
- this.hasFocus = false;
- this.changed = false;
- this.active = false;
- this.index = 0;
+ element = $(element);
+ this.element = element;
+ this.update = $(update);
+ this.hasFocus = false;
+ this.changed = false;
+ this.active = false;
+ this.index = 0;
this.entryCount = 0;
+ this.oldElementValue = this.element.value;
if(this.setOptions)
this.setOptions(options);
else
- this.options = options || {};
+ this.options = options || { };
this.options.paramName = this.options.paramName || this.element.name;
this.options.tokens = this.options.tokens || [];
this.options.frequency = this.options.frequency || 0.4;
this.options.minChars = this.options.minChars || 1;
- this.options. ||
- function(element, update){
+ this.options. ||
+ function(element, update){
if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute';
Position.clone(element, update, {
- setHeight: false,
+ setHeight: false,
offsetTop: element.offsetHeight
});
}
Effect.Appear(update,{duration:0.15});
};
- this.options. ||
+ this.options. ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
- if(typeof(this.options.tokens) == 'string')
+ if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens);
+ // Force carriage returns as token delimiters anyway
+ if (!this.options.tokens.include('\n'))
+ this.options.tokens.push('\n');
this.observer = null;
-
+
this.element.setAttribute('autocomplete','off');
Element.hide(this.update);
- Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
- Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
+ Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
+ Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
},
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
- if(!this.iefix &&
- (navigator.appVersion.indexOf('MSIE')>0) &&
- (navigator.userAgent.indexOf('Opera')<0) &&
+ if(!this.iefix &&
+ (Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
- new Insertion.After(this.update,
+ new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="" frameborder="0" scrolling="no"></iframe>');
@@ -99,7 +102,7 @@
}
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},
-
+
fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
@@ -139,23 +142,23 @@
case Event.KEY_UP:
this.markPrevious();
this.render();
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+ Event.stop(event);
return;
case Event.KEY_DOWN:
this.markNext();
this.render();
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+ Event.stop(event);
return;
}
- else
- if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
- (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
+ else
+ if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
+ (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
this.changed = true;
this.hasFocus = true;
if(this.observer) clearTimeout(this.observer);
- this.observer =
+ this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
},
@@ -167,36 +170,35 @@
onHover: function(event) {
var element = Event.findElement(event, 'LI');
- if(this.index != element.autocompleteIndex)
+ if(this.index != element.autocompleteIndex)
{
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
},
-
+
onClick: function(event) {
var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex;
this.selectEntry();
this.hide();
},
-
+
onBlur: function(event) {
// needed to make click events working
setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
- this.active = false;
- },
-
+ this.active = false;
+ },
+
render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
- this.index==i ?
- Element.addClassName(this.getEntry(i),"selected") :
+ this.index==i ?
+ Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
-
- if(this.hasFocus) {
+ if(this.hasFocus) {
this.show();
this.active = true;
}
@@ -205,27 +207,27 @@
this.hide();
}
},
-
+
markPrevious: function() {
- if(this.index > 0) this.index--
+ if(this.index > 0) this.index--;
else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true);
},
-
+
markNext: function() {
- if(this.index < this.entryCount-1) this.index++
+ if(this.index < this.entryCount-1) this.index++;
else this.index = 0;
this.getEntry(this.index).scrollIntoView(false);
},
-
+
getEntry: function(index) {
return this.update.firstChild.childNodes[index];
},
-
+
getCurrentEntry: function() {
return this.getEntry(this.index);
},
-
+
selectEntry: function() {
this.active = false;
this.updateElement(this.getCurrentEntry());
@@ -238,23 +240,24 @@
}
var value = '';
if (this.options.select) {
- var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
+ var nodes = $(selectedElement).select('.' + this.options.select) || [];
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
-
- var lastTokenPos = this.findLastToken();
- if (lastTokenPos != -1) {
- var newValue = this.element.value.substr(0, lastTokenPos + 1);
- var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
+
+ var bounds = this.getTokenBounds();
+ if (bounds[0] != -1) {
+ var newValue = this.element.value.substr(0, bounds[0]);
+ var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
if (whitespace)
newValue += whitespace[0];
- this.element.value = newValue + value;
+ this.element.value = newValue + value + this.element.value.substr(bounds[1]);
} else {
this.element.value = value;
}
+ this.oldElementValue = this.element.value;
this.element.focus();
-
+
if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement);
},
@@ -266,20 +269,20 @@
Element.cleanWhitespace(this.update.down());
if(this.update.firstChild && this.update.down().childNodes) {
- this.entryCount =
+ this.entryCount =
this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
- } else {
+ } else {
this.entryCount = 0;
}
this.stopIndicator();
this.index = 0;
-
+
if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry();
this.hide();
@@ -295,40 +298,49 @@
},
onObserverEvent: function() {
- this.changed = false;
+ this.changed = false;
+ this.tokenBounds = null;
if(this.getToken().length>=this.options.minChars) {
- this.startIndicator();
this.getUpdatedChoices();
} else {
this.active = false;
this.hide();
}
+ this.oldElementValue = this.element.value;
},
getToken: function() {
- var tokenPos = this.findLastToken();
- if (tokenPos != -1)
- var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
- else
- var ret = this.element.value;
-
- return /\n/.test(ret) ? '' : ret;
+ var bounds = this.getTokenBounds();
+ return this.element.value.substring(bounds[0], bounds[1]).strip();
},
- findLastToken: function() {
- var lastTokenPos = -1;
-
- for (var i=0; i<this.options.tokens.length; i++) {
- var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
- if (thisTokenPos > lastTokenPos)
- lastTokenPos = thisTokenPos;
+ getTokenBounds: function() {
+ if (null != this.tokenBounds) return this.tokenBounds;
+ var value = this.element.value;
+ if (value.strip().empty()) return [-1, 0];
+ var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
+ var offset = (diff == this.oldElementValue.length ? 1 : 0);
+ var prevTokenPos = -1, nextTokenPos = value.length;
+ var tp;
+ for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
+ tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
+ if (tp > prevTokenPos) prevTokenPos = tp;
+ tp = value.indexOf(this.options.tokens[index], diff + offset);
+ if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
}
- return lastTokenPos;
+ return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
}
-}
+});
-Ajax.Autocompleter = Class.create();
-Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
+Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
+ var boundary = Math.min(newS.length, oldS.length);
+ for (var index = 0; index < boundary; ++index)
+ if (newS[index] != oldS[index])
+ return index;
+ return boundary;
+};
+
+Ajax.Autocompleter = Class.create(Autocompleter.Base, {
initialize: function(element, update, url, options) {
this.baseInitialize(element, update, options);
this.options.asynchronous = true;
@@ -338,13 +350,15 @@
},
getUpdatedChoices: function() {
- entry = encodeURIComponent(this.options.paramName) + '=' +
+ this.startIndicator();
+
+ var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());
this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry;
- if(this.options.defaultParams)
+ if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;
new Ajax.Request(this.url, this.options);
@@ -353,7 +367,6 @@
onComplete: function(request) {
this.updateChoices(request.responseText);
}
-
});
// The local array autocompleter. Used when you'd prefer to
@@ -369,7 +382,7 @@
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
-// text only at the beginning of strings in the
+// text only at the beginning of strings in the
// autocomplete array. Defaults to true, which will
// match text at the beginning of any *word* in the
// strings in the autocomplete array. If you want to
@@ -386,13 +399,12 @@
// - ignoreCase - Whether to ignore case when autocompleting.
// Defaults to true.
//
-// It's possible to pass in a custom function as the 'selector'
+// It's possible to pass in a custom function as the 'selector'
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.
-Autocompleter.Local = Class.create();
-Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
+Autocompleter.Local = Class.create(Autocompleter.Base, {
initialize: function(element, update, array, options) {
this.baseInitialize(element, update, options);
this.options.array = array;
@@ -415,20 +427,20 @@
var entry = instance.getToken();
var count = 0;
- for (var i = 0; i < instance.options.array.length &&
- ret.length < instance.options.choices ; i++) {
+ for (var i = 0; i < instance.options.array.length &&
+ ret.length < instance.options.choices ; i++) {
var elem = instance.options.array[i];
- var foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase()) :
+ var foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry);
while (foundPos != -1) {
- if (foundPos == 0 && elem.length != entry.length) {
- ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
+ if (foundPos == 0 && elem.length != entry.length) {
+ ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>");
break;
- } else if (entry.length >= instance.options.partialChars &&
+ } else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
@@ -438,23 +450,22 @@
}
}
- foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
+ foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1);
}
}
if (partial.length)
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+ ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
return "<ul>" + ret.join('') + "</ul>";
}
- }, options || {});
+ }, options || { });
}
});
-// AJAX in-place editor
-//
-// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
+// AJAX in-place editor and collection editor
+// Full rewrite by Christophe Porteneuve <address@hidden> (April 2007).
// Use this if you notice weird scrolling problems on some browsers,
// the DOM might be a bit confused when this gets called so do this
@@ -463,361 +474,480 @@
setTimeout(function() {
Field.activate(field);
}, 1);
-}
+};
-Ajax.InPlaceEditor = Class.create();
-Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
-Ajax.InPlaceEditor.prototype = {
+Ajax.InPlaceEditor = Class.create({
initialize: function(element, url, options) {
this.url = ""
- this.element = $(element);
-
- this.options = Object.extend({
- paramName: "value",
- okButton: true,
- okText: "ok",
- cancelLink: true,
- cancelText: "cancel",
- savingText: "Saving...",
- clickToEditText: "Click to edit",
- okText: "ok",
- rows: 1,
- onComplete: function(transport, element) {
- new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
- },
- onFailure: function(transport) {
- alert("Error communicating with the server: " + transport.responseText.stripTags());
- },
- callback: function(form) {
- return Form.serialize(form);
- },
- handleLineBreaks: true,
- loadingText: 'Loading...',
- savingClassName: 'inplaceeditor-saving',
- loadingClassName: 'inplaceeditor-loading',
- formClassName: 'inplaceeditor-form',
- highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
- highlightendcolor: "#FFFFFF",
- externalControl: null,
- submitOnBlur: false,
- ajaxOptions: {},
- evalScripts: false
- }, options || {});
-
- if(!this.options.formId && this.element.id) {
- this.options.formId = this.element.id + "-inplaceeditor";
- if ($(this.options.formId)) {
- // there's already a form with that name, don't specify an id
- this.options.formId = null;
- }
+ this.element = element = $(element);
+ this.prepareOptions();
+ this._controls = { };
+ arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
+ Object.extend(this.options, options || { });
+ if (!this.options.formId && this.element.id) {
+ this.options.formId = this.element.id + '-inplaceeditor';
+ if ($(this.options.formId))
+ this.options.formId = '';
}
-
- if (this.options.externalControl) {
+ if (this.options.externalControl)
this.options.externalControl = $(this.options.externalControl);
- }
-
- this.originalBackground = Element.getStyle(this.element, 'background-color');
- if (!this.originalBackground) {
- this.originalBackground = "transparent";
- }
-
+ if (!this.options.externalControl)
+ this.options.externalControlOnly = false;
+ this._originalBackground = this.element.getStyle('background-color') || 'transparent';
this.element.title = this.options.clickToEditText;
-
- this.
- this.mouseoverListener = this.enterHover.bindAsEventListener(this);
- this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
- Event.observe(this.element, 'click', this.onclickListener);
- Event.observe(this.element, 'mouseover', this.mouseoverListener);
- Event.observe(this.element, 'mouseout', this.mouseoutListener);
- if (this.options.externalControl) {
- Event.observe(this.options.externalControl, 'click', this.onclickListener);
- Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
+ this._boundCancelHandler = this.handleFormCancellation.bind(this);
+ this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
+ this._boundFailureHandler = this.handleAJAXFailure.bind(this);
+ this._boundSubmitHandler = this.handleFormSubmission.bind(this);
+ this._boundWrapperHandler = this.wrapUp.bind(this);
+ this.registerListeners();
},
- enterEditMode: function(evt) {
- if (this.saving) return;
- if (this.editing) return;
- this.editing = true;
- this.onEnterEditMode();
- if (this.options.externalControl) {
- Element.hide(this.options.externalControl);
- }
- Element.hide(this.element);
- this.createForm();
- this.element.parentNode.insertBefore(this.form, this.element);
- if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);
- // stop the event to avoid a page refresh in Safari
- if (evt) {
- Event.stop(evt);
- }
- return false;
+ checkForEscapeOrReturn: function(e) {
+ if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
+ if (Event.KEY_ESC == e.keyCode)
+ this.handleFormCancellation(e);
+ else if (Event.KEY_RETURN == e.keyCode)
+ this.handleFormSubmission(e);
},
- createForm: function() {
- this.form = document.createElement("form");
- this.form.id = this.options.formId;
- Element.addClassName(this.form, this.options.formClassName)
- this.form.
-
- this.createEditField();
-
- if (this.options.textarea) {
- var br = document.createElement("br");
- this.form.appendChild(br);
+ createControl: function(mode, handler, extraClasses) {
+ var control = this.options[mode + 'Control'];
+ var text = this.options[mode + 'Text'];
+ if ('button' == control) {
+ var btn = document.createElement('input');
+ btn.type = 'submit';
+ btn.value = text;
+ btn.className = 'editor_' + mode + '_button';
+ if ('cancel' == mode)
+ btn.
+ this._form.appendChild(btn);
+ this._controls[mode] = btn;
+ } else if ('link' == control) {
+ var link = document.createElement('a');
+ link.href = '';
+ link.appendChild(document.createTextNode(text));
+ link. == mode ? this._boundCancelHandler : this._boundSubmitHandler;
+ link.className = 'editor_' + mode + '_link';
+ if (extraClasses)
+ link.className += ' ' + extraClasses;
+ this._form.appendChild(link);
+ this._controls[mode] = link;
}
-
- if (this.options.okButton) {
- okButton = document.createElement("input");
- okButton.type = "submit";
- okButton.value = this.options.okText;
- okButton.className = 'editor_ok_button';
- this.form.appendChild(okButton);
- }
-
- if (this.options.cancelLink) {
- cancelLink = document.createElement("a");
- cancelLink.href = ""
- cancelLink.appendChild(document.createTextNode(this.options.cancelText));
- cancelLink.
- cancelLink.className = 'editor_cancel';
- this.form.appendChild(cancelLink);
- }
},
- hasHTMLLineBreaks: function(string) {
- if (!this.options.handleLineBreaks) return false;
- return string.match(/<br/i) || string.match(/<p>/i);
- },
- convertHTMLLineBreaks: function(string) {
- return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
- },
createEditField: function() {
- var text;
- if(this.options.loadTextURL) {
- text = this.options.loadingText;
- } else {
- text = this.getText();
- }
-
- var obj = this;
-
- if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
- this.options.textarea = false;
- var textField = document.createElement("input");
- textField.obj = this;
- textField.type = "text";
- textField.name = this.options.paramName;
- textField.value = text;
- textField.style.backgroundColor = this.options.highlightcolor;
- textField.className = 'editor_field';
+ var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
+ var fld;
+ if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
+ fld = document.createElement('input');
+ fld.type = 'text';
var size = this.options.size || this.options.cols || 0;
- if (size != 0) textField.size = size;
- if (this.options.submitOnBlur)
- textField.
- this.editField = textField;
+ if (0 < size) fld.size = size;
} else {
- this.options.textarea = true;
- var textArea = document.createElement("textarea");
- textArea.obj = this;
- textArea.name = this.options.paramName;
- textArea.value = this.convertHTMLLineBreaks(text);
- textArea.rows = this.options.rows;
- textArea.cols = this.options.cols || 40;
- textArea.className = 'editor_field';
- if (this.options.submitOnBlur)
- textArea.
- this.editField = textArea;
+ fld = document.createElement('textarea');
+ fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
+ fld.cols = this.options.cols || 40;
}
-
- if(this.options.loadTextURL) {
+ fld.name = this.options.paramName;
+ fld.value = text; // No HTML breaks conversion anymore
+ fld.className = 'editor_field';
+ if (this.options.submitOnBlur)
+ fld.
+ this._controls.editor = fld;
+ if (this.options.loadTextURL)
this.loadExternalText();
- }
- this.form.appendChild(this.editField);
+ this._form.appendChild(this._controls.editor);
},
- getText: function() {
- return this.element.innerHTML;
+ createForm: function() {
+ var ipe = this;
+ function addText(mode, condition) {
+ var text = ipe.options['text' + mode + 'Controls'];
+ if (!text || condition === false) return;
+ ipe._form.appendChild(document.createTextNode(text));
+ };
+ this._form = $(document.createElement('form'));
+ this._form.id = this.options.formId;
+ this._form.addClassName(this.options.formClassName);
+ this._form.
+ this.createEditField();
+ if ('textarea' == this._controls.editor.tagName.toLowerCase())
+ this._form.appendChild(document.createElement('br'));
+ if (this.options.onFormCustomization)
+ this.options.onFormCustomization(this, this._form);
+ addText('Before', this.options.okControl || this.options.cancelControl);
+ this.createControl('ok', this._boundSubmitHandler);
+ addText('Between', this.options.okControl && this.options.cancelControl);
+ this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
+ addText('After', this.options.okControl || this.options.cancelControl);
},
- loadExternalText: function() {
- Element.addClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = true;
- new Ajax.Request(
- this.options.loadTextURL,
- Object.extend({
- asynchronous: true,
- onComplete: this.onLoadedExternalText.bind(this)
- }, this.options.ajaxOptions)
- );
+ destroy: function() {
+ if (this._oldInnerHTML)
+ this.element.innerHTML = this._oldInnerHTML;
+ this.leaveEditMode();
+ this.unregisterListeners();
},
- onLoadedExternalText: function(transport) {
- Element.removeClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = false;
- this.editField.value = transport.responseText.stripTags();
- Field.scrollFreeActivate(this.editField);
+ enterEditMode: function(e) {
+ if (this._saving || this._editing) return;
+ this._editing = true;
+ this.triggerCallback('onEnterEditMode');
+ if (this.options.externalControl)
+ this.options.externalControl.hide();
+ this.element.hide();
+ this.createForm();
+ this.element.parentNode.insertBefore(this._form, this.element);
+ if (!this.options.loadTextURL)
+ this.postProcessEditField();
+ if (e) Event.stop(e);
},
- onclickCancel: function() {
- this.onComplete();
- this.leaveEditMode();
- return false;
+ enterHover: function(e) {
+ if (this.options.hoverClassName)
+ this.element.addClassName(this.options.hoverClassName);
+ if (this._saving) return;
+ this.triggerCallback('onEnterHover');
},
- onFailure: function(transport) {
- this.options.onFailure(transport);
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- this.oldInnerHTML = null;
+ getText: function() {
+ return this.element.innerHTML.unescapeHTML();
+ },
+ handleAJAXFailure: function(transport) {
+ this.triggerCallback('onFailure', transport);
+ if (this._oldInnerHTML) {
+ this.element.innerHTML = this._oldInnerHTML;
+ this._oldInnerHTML = null;
}
- return false;
},
- onSubmit: function() {
- // onLoading resets these so we need to save them away for the Ajax call
- var form = this.form;
- var value = this.editField.value;
-
- // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
- // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
- // to be displayed indefinitely
- this.onLoading();
-
- if (this.options.evalScripts) {
- new Ajax.Request(
- this.url, Object.extend({
- parameters: this.options.callback(form, value),
- onComplete: this.onComplete.bind(this),
- onFailure: this.onFailure.bind(this),
- asynchronous:true,
- evalScripts:true
- }, this.options.ajaxOptions));
- } else {
- new Ajax.Updater(
- { success: this.element,
- // don't update on failure (this could be an option)
- failure: null },
- this.url, Object.extend({
- parameters: this.options.callback(form, value),
- onComplete: this.onComplete.bind(this),
- onFailure: this.onFailure.bind(this)
- }, this.options.ajaxOptions));
+ handleFormCancellation: function(e) {
+ this.wrapUp();
+ if (e) Event.stop(e);
+ },
+ handleFormSubmission: function(e) {
+ var form = this._form;
+ var value = $F(this._controls.editor);
+ this.prepareSubmission();
+ var params = this.options.callback(form, value) || '';
+ if (Object.isString(params))
+ params = params.toQueryParams();
+ params.editorId = this.element.id;
+ if (this.options.htmlResponse) {
+ var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
+ Object.extend(options, {
+ parameters: params,
+ onComplete: this._boundWrapperHandler,
+ onFailure: this._boundFailureHandler
+ });
+ new Ajax.Updater({ success: this.element }, this.url, options);
+ } else {
+ var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+ Object.extend(options, {
+ parameters: params,
+ onComplete: this._boundWrapperHandler,
+ onFailure: this._boundFailureHandler
+ });
+ new Ajax.Request(this.url, options);
}
- // stop the event to avoid a page refresh in Safari
- if (arguments.length > 1) {
- Event.stop(arguments[0]);
- }
- return false;
+ if (e) Event.stop(e);
},
- onLoading: function() {
- this.saving = true;
+ leaveEditMode: function() {
+ this.element.removeClassName(this.options.savingClassName);
this.removeForm();
this.leaveHover();
+ this.element.style.backgroundColor = this._originalBackground;
+ this.element.show();
+ if (this.options.externalControl)
+ this.options.externalControl.show();
+ this._saving = false;
+ this._editing = false;
+ this._oldInnerHTML = null;
+ this.triggerCallback('onLeaveEditMode');
+ },
+ leaveHover: function(e) {
+ if (this.options.hoverClassName)
+ this.element.removeClassName(this.options.hoverClassName);
+ if (this._saving) return;
+ this.triggerCallback('onLeaveHover');
+ },
+ loadExternalText: function() {
+ this._form.addClassName(this.options.loadingClassName);
+ this._controls.editor.disabled = true;
+ var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+ Object.extend(options, {
+ parameters: 'editorId=' + encodeURIComponent(this.element.id),
+ onComplete: Prototype.emptyFunction,
+ onSuccess: function(transport) {
+ this._form.removeClassName(this.options.loadingClassName);
+ var text = transport.responseText;
+ if (this.options.stripLoadedTextTags)
+ text = text.stripTags();
+ this._controls.editor.value = text;
+ this._controls.editor.disabled = false;
+ this.postProcessEditField();
+ }.bind(this),
+ onFailure: this._boundFailureHandler
+ });
+ new Ajax.Request(this.options.loadTextURL, options);
+ },
+ postProcessEditField: function() {
+ var fpc = this.options.fieldPostCreation;
+ if (fpc)
+ $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
+ },
+ prepareOptions: function() {
+ this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
+ Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
+ [this._extraDefaultOptions].flatten().compact().each(function(defs) {
+ Object.extend(this.options, defs);
+ }.bind(this));
+ },
+ prepareSubmission: function() {
+ this._saving = true;
+ this.removeForm();
+ this.leaveHover();
this.showSaving();
},
+ registerListeners: function() {
+ this._listeners = { };
+ var listener;
+ $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
+ listener = this[pair.value].bind(this);
+ this._listeners[pair.key] = listener;
+ if (!this.options.externalControlOnly)
+ this.element.observe(pair.key, listener);
+ if (this.options.externalControl)
+ this.options.externalControl.observe(pair.key, listener);
+ }.bind(this));
+ },
+ removeForm: function() {
+ if (!this._form) return;
+ this._form.remove();
+ this._form = null;
+ this._controls = { };
+ },
showSaving: function() {
- this.oldInnerHTML = this.element.innerHTML;
+ this._oldInnerHTML = this.element.innerHTML;
this.element.innerHTML = this.options.savingText;
- Element.addClassName(this.element, this.options.savingClassName);
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
+ this.element.addClassName(this.options.savingClassName);
+ this.element.style.backgroundColor = this._originalBackground;
+ this.element.show();
},
- removeForm: function() {
- if(this.form) {
- if (this.form.parentNode) Element.remove(this.form);
- this.form = null;
+ triggerCallback: function(cbName, arg) {
+ if ('function' == typeof this.options[cbName]) {
+ this.options[cbName](this, arg);
}
},
- enterHover: function() {
- if (this.saving) return;
- this.element.style.backgroundColor = this.options.highlightcolor;
- if (this.effect) {
- this.effect.cancel();
- }
- Element.addClassName(this.element, this.options.hoverClassName)
+ unregisterListeners: function() {
+ $H(this._listeners).each(function(pair) {
+ if (!this.options.externalControlOnly)
+ this.element.stopObserving(pair.key, pair.value);
+ if (this.options.externalControl)
+ this.options.externalControl.stopObserving(pair.key, pair.value);
+ }.bind(this));
},
- leaveHover: function() {
- if (this.options.backgroundColor) {
- this.element.style.backgroundColor = this.oldBackground;
- }
- Element.removeClassName(this.element, this.options.hoverClassName)
- if (this.saving) return;
- this.effect = new Effect.Highlight(this.element, {
- startcolor: this.options.highlightcolor,
- endcolor: this.options.highlightendcolor,
- restorecolor: this.originalBackground
+ wrapUp: function(transport) {
+ this.leaveEditMode();
+ // Can't use triggerCallback due to backward compatibility: requires
+ // binding + direct element
+ this._boundComplete(transport, this.element);
+ }
+});
+
+Object.extend(Ajax.InPlaceEditor.prototype, {
+ dispose: Ajax.InPlaceEditor.prototype.destroy
+});
+
+Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
+ initialize: function($super, element, url, options) {
+ this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
+ $super(element, url, options);
+ },
+
+ createEditField: function() {
+ var list = document.createElement('select');
+ list.name = this.options.paramName;
+ list.size = 1;
+ this._controls.editor = list;
+ this._collection = this.options.collection || [];
+ if (this.options.loadCollectionURL)
+ this.loadCollection();
+ else
+ this.checkForExternalText();
+ this._form.appendChild(this._controls.editor);
+ },
+
+ loadCollection: function() {
+ this._form.addClassName(this.options.loadingClassName);
+ this.showLoadingText(this.options.loadingCollectionText);
+ var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+ Object.extend(options, {
+ parameters: 'editorId=' + encodeURIComponent(this.element.id),
+ onComplete: Prototype.emptyFunction,
+ onSuccess: function(transport) {
+ var js = transport.responseText.strip();
+ if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
+ throw('Server returned an invalid collection representation.');
+ this._collection = eval(js);
+ this.checkForExternalText();
+ }.bind(this),
+ onFailure: this.onFailure
});
+ new Ajax.Request(this.options.loadCollectionURL, options);
},
- leaveEditMode: function() {
- Element.removeClassName(this.element, this.options.savingClassName);
- this.removeForm();
- this.leaveHover();
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- if (this.options.externalControl) {
- Element.show(this.options.externalControl);
+
+ showLoadingText: function(text) {
+ this._controls.editor.disabled = true;
+ var tempOption = this._controls.editor.firstChild;
+ if (!tempOption) {
+ tempOption = document.createElement('option');
+ tempOption.value = '';
+ this._controls.editor.appendChild(tempOption);
+ tempOption.selected = true;
}
- this.editing = false;
- this.saving = false;
- this.oldInnerHTML = null;
- this.onLeaveEditMode();
+ tempOption.update((text || '').stripScripts().stripTags());
},
- onComplete: function(transport) {
- this.leaveEditMode();
- this.options.onComplete.bind(this)(transport, this.element);
+
+ checkForExternalText: function() {
+ this._text = this.getText();
+ if (this.options.loadTextURL)
+ this.loadExternalText();
+ else
+ this.buildOptionList();
},
- onEnterEditMode: function() {},
- onLeaveEditMode: function() {},
- dispose: function() {
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- }
- this.leaveEditMode();
- Event.stopObserving(this.element, 'click', this.onclickListener);
- Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
- if (this.options.externalControl) {
- Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
- Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
+
+ loadExternalText: function() {
+ this.showLoadingText(this.options.loadingText);
+ var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+ Object.extend(options, {
+ parameters: 'editorId=' + encodeURIComponent(this.element.id),
+ onComplete: Prototype.emptyFunction,
+ onSuccess: function(transport) {
+ this._text = transport.responseText.strip();
+ this.buildOptionList();
+ }.bind(this),
+ onFailure: this.onFailure
+ });
+ new Ajax.Request(this.options.loadTextURL, options);
+ },
+
+ buildOptionList: function() {
+ this._form.removeClassName(this.options.loadingClassName);
+ this._collection = this._collection.map(function(entry) {
+ return 2 === entry.length ? entry : [entry, entry].flatten();
+ });
+ var marker = ('value' in this.options) ? this.options.value : this._text;
+ var textFound = this._collection.any(function(entry) {
+ return entry[0] == marker;
+ }.bind(this));
+ this._controls.editor.update('');
+ var option;
+ this._collection.each(function(entry, index) {
+ option = document.createElement('option');
+ option.value = entry[0];
+ option.selected = textFound ? entry[0] == marker : 0 == index;
+ option.appendChild(document.createTextNode(entry[1]));
+ this._controls.editor.appendChild(option);
+ }.bind(this));
+ this._controls.editor.disabled = false;
+ Field.scrollFreeActivate(this._controls.editor);
}
+});
+
+//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
+//**** This only exists for a while, in order to let ****
+//**** users adapt to the new API. Read up on the new ****
+//**** API and convert your code to it ASAP! ****
+
+Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
+ if (!options) return;
+ function fallback(name, expr) {
+ if (name in options || expr === undefined) return;
+ options[name] = expr;
+ };
+ fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
+ options.cancelLink == options.cancelButton == false ? false : undefined)));
+ fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
+ options.okLink == options.okButton == false ? false : undefined)));
+ fallback('highlightColor', options.highlightcolor);
+ fallback('highlightEndColor', options.highlightendcolor);
};
-Ajax.InPlaceCollectionEditor = Class.create();
-Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
-Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
- createEditField: function() {
- if (!this.cached_selectTag) {
- var selectTag = document.createElement("select");
- var collection = this.options.collection || [];
- var optionTag;
- collection.each(function(e,i) {
- optionTag = document.createElement("option");
- optionTag.value = (e instanceof Array) ? e[0] : e;
- if((typeof this.options.value == 'undefined') &&
- ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
- if(this.options.value==optionTag.value) optionTag.selected = true;
- optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
- selectTag.appendChild(optionTag);
- }.bind(this));
- this.cached_selectTag = selectTag;
+Object.extend(Ajax.InPlaceEditor, {
+ DefaultOptions: {
+ ajaxOptions: { },
+ autoRows: 3, // Use when multi-line w/ rows == 1
+ cancelControl: 'link', // 'link'|'button'|false
+ cancelText: 'cancel',
+ clickToEditText: 'Click to edit',
+ externalControl: null, // id|elt
+ externalControlOnly: false,
+ fieldPostCreation: 'activate', // 'activate'|'focus'|false
+ formClassName: 'inplaceeditor-form',
+ formId: null, // id|elt
+ highlightColor: '#ffff99',
+ highlightEndColor: '#ffffff',
+ hoverClassName: '',
+ htmlResponse: true,
+ loadingClassName: 'inplaceeditor-loading',
+ loadingText: 'Loading...',
+ okControl: 'button', // 'link'|'button'|false
+ okText: 'ok',
+ paramName: 'value',
+ rows: 1, // If 1 and multi-line, uses autoRows
+ savingClassName: 'inplaceeditor-saving',
+ savingText: 'Saving...',
+ size: 0,
+ stripLoadedTextTags: false,
+ submitOnBlur: false,
+ textAfterControls: '',
+ textBeforeControls: '',
+ textBetweenControls: ''
+ },
+ DefaultCallbacks: {
+ callback: function(form) {
+ return Form.serialize(form);
+ },
+ onComplete: function(transport, element) {
+ // For backward compatibility, this one is bound to the IPE, and passes
+ // the element directly. It was too often customized, so we don't break it.
+ new Effect.Highlight(element, {
+ startcolor: this.options.highlightColor, keepBackgroundImage: true });
+ },
+ onEnterEditMode: null,
+ onEnterHover: function(ipe) {
+ ipe.element.style.backgroundColor = ipe.options.highlightColor;
+ if (ipe._effect)
+ ipe._effect.cancel();
+ },
+ onFailure: function(transport, ipe) {
+ alert('Error communication with the server: ' + transport.responseText.stripTags());
+ },
+ onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
+ onLeaveEditMode: null,
+ onLeaveHover: function(ipe) {
+ ipe._effect = new Effect.Highlight(ipe.element, {
+ startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
+ restorecolor: ipe._originalBackground, keepBackgroundImage: true
+ });
}
-
- this.editField = this.cached_selectTag;
- if(this.options.loadTextURL) this.loadExternalText();
- this.form.appendChild(this.editField);
- this.options.callback = function(form, value) {
- return "value=" + encodeURIComponent(value);
- }
+ },
+ Listeners: {
+ click: 'enterEditMode',
+ keydown: 'checkForEscapeOrReturn',
+ mouseover: 'enterHover',
+ mouseout: 'leaveHover'
}
});
-// Delayed observer, like Form.Element.Observer,
+Ajax.InPlaceCollectionEditor.DefaultOptions = {
+ loadingCollectionText: 'Loading options...'
+};
+
+// Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input
// Ideal for live-search fields
-Form.Element.DelayedObserver = Class.create();
-Form.Element.DelayedObserver.prototype = {
+Form.Element.DelayedObserver = Class.create({
initialize: function(element, delay, callback) {
this.delay = delay || 0.5;
this.element = $(element);
this.callback = callback;
this.timer = null;
- this.lastValue = $F(this.element);
+ this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
@@ -830,4 +960,4 @@
this.timer = null;
this.callback(this.element, $F(this.element));
}
-};
+});
\ No newline at end of file
Modified: branches/datasets/public/_javascript_s/dragdrop.js (2857 => 2858)
--- branches/datasets/public/_javascript_s/dragdrop.js 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/_javascript_s/dragdrop.js 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,10 +1,10 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, address@hidden)
-//
+// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, address@hidden)
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
-if(typeof Effect == 'undefined')
+if(Object.isUndefined(Effect))
throw("dragdrop.js requires including script.aculo.us' effects.js library");
var Droppables = {
@@ -20,20 +20,19 @@
greedy: true,
hoverclass: null,
tree: false
- }, arguments[1] || {});
+ }, arguments[1] || { });
// cache containers
if(options.containment) {
options._containers = [];
var containment = options.containment;
- if((typeof containment == 'object') &&
- (containment.constructor == Array)) {
+ if(Object.isArray(containment)) {
containment.each( function(c) { options._containers.push($(c)) });
} else {
options._containers.push($(containment));
}
}
-
+
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
@@ -41,34 +40,34 @@
this.drops.push(options);
},
-
+
findDeepestChild: function(drops) {
deepest = drops[0];
-
+
for (i = 1; i < drops.length; ++i)
if (Element.isParent(drops[i].element, deepest.element))
deepest = drops[i];
-
+
return deepest;
},
isContained: function(element, drop) {
var containmentNode;
if(drop.tree) {
- containmentNode = element.treeNode;
+ containmentNode = element.treeNode;
} else {
containmentNode = element.parentNode;
}
return drop._containers.detect(function(c) { return containmentNode == c });
},
-
+
isAffected: function(point, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
- (Element.classNames(element).detect(
+ (Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, point[0], point[1]) );
},
@@ -87,21 +86,23 @@
show: function(point, element) {
if(!this.drops.length) return;
- var affected = [];
-
- if(this.last_active) this.deactivate(this.last_active);
+ var drop, affected = [];
+
this.drops.each( function(drop) {
if(Droppables.isAffected(point, element, drop))
affected.push(drop);
});
-
- if(affected.length>0) {
+
+ if(affected.length>0)
drop = Droppables.findDeepestChild(affected);
+
+ if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
+ if (drop) {
Position.within(drop.element, point[0], point[1]);
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
-
- Droppables.activate(drop);
+
+ if (drop != this.last_active) Droppables.activate(drop);
}
},
@@ -110,33 +111,35 @@
Position.prepare();
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
- if (this.last_active.onDrop)
+ if (this.last_active.onDrop) {
this.last_active.onDrop(element, this.last_active.element, event);
+ return true;
+ }
},
reset: function() {
if(this.last_active)
this.deactivate(this.last_active);
}
-}
+};
var Draggables = {
drags: [],
observers: [],
-
+
register: function(draggable) {
if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
-
+
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
}
this.drags.push(draggable);
},
-
+
unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable });
if(this.drags.length == 0) {
@@ -145,24 +148,24 @@
Event.stopObserving(document, "keypress", this.eventKeypress);
}
},
-
+
activate: function(draggable) {
- if(draggable.options.delay) {
- this._timeout = setTimeout(function() {
- Draggables._timeout = null;
- window.focus();
- Draggables.activeDraggable = draggable;
- }.bind(this), draggable.options.delay);
+ if(draggable.options.delay) {
+ this._timeout = setTimeout(function() {
+ Draggables._timeout = null;
+ window.focus();
+ Draggables.activeDraggable = draggable;
+ }.bind(this), draggable.options.delay);
} else {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable;
}
},
-
+
deactivate: function() {
this.activeDraggable = null;
},
-
+
updateDrag: function(event) {
if(!this.activeDraggable) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -170,36 +173,36 @@
// the same coordinates, prevent needless redrawing (moz bug?)
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer;
-
+
this.activeDraggable.updateDrag(event, pointer);
},
-
+
endDrag: function(event) {
- if(this._timeout) {
- clearTimeout(this._timeout);
- this._timeout = null;
+ if(this._timeout) {
+ clearTimeout(this._timeout);
+ this._timeout = null;
}
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
this.activeDraggable = null;
},
-
+
keyPress: function(event) {
if(this.activeDraggable)
this.activeDraggable.keyPress(event);
},
-
+
addObserver: function(observer) {
this.observers.push(observer);
this._cacheObserverCallbacks();
},
-
+
removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element });
this._cacheObserverCallbacks();
},
-
+
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
if(this[eventName+'Count'] > 0)
this.observers.each( function(o) {
@@ -207,7 +210,7 @@
});
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
},
-
+
_cacheObserverCallbacks: function() {
['onStart','onEnd','onDrag'].each( function(eventName) {
Draggables[eventName+'Count'] = Draggables.observers.select(
@@ -215,14 +218,11 @@
).length;
});
}
-}
+};
/*--------------------------------------------------------------------------*/
-var Draggable = Class.create();
-Draggable._dragging = {};
-
-Draggable.prototype = {
+var Draggable = Class.create({
initialize: function(element) {
var defaults = {
handle: false,
@@ -233,106 +233,110 @@
});
},
endeffect: function(element) {
- var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+ var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
queue: {scope:'_draggable', position:'end'},
- afterFinish: function(){
- Draggable._dragging[element] = false
+ afterFinish: function(){
+ Draggable._dragging[element] = false
}
- });
+ });
},
zindex: 1000,
revert: false,
+ quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
delay: 0
};
-
- if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')
+
+ if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
Object.extend(defaults, {
starteffect: function(element) {
element._opacity = Element.getOpacity(element);
Draggable._dragging[element] = true;
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
}
});
-
- var options = Object.extend(defaults, arguments[1] || {});
+ var options = Object.extend(defaults, arguments[1] || { });
+
this.element = $(element);
-
- if(options.handle && (typeof options.handle == 'string'))
+
+ if(options.handle && Object.isString(options.handle))
this.handle = this.element.down('.'+options.handle, 0);
-
+
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
-
+
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
options.scroll = $(options.scroll);
this._isScrollChild = Element.childOf(this.element, options.scroll);
}
- Element.makePositioned(this.element); // fix IE
+ Element.makePositioned(this.element); // fix IE
- this.delta = this.currentDelta();
this.options = options;
- this.dragging = false;
+ this.dragging = false;
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
+
Draggables.register(this);
},
-
+
destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Draggables.unregister(this);
},
-
+
currentDelta: function() {
return([
parseInt(Element.getStyle(this.element,'left') || '0'),
parseInt(Element.getStyle(this.element,'top') || '0')]);
},
-
+
initDrag: function(event) {
- if(typeof Draggable._dragging[this.element] != 'undefined' &&
+ if(!Object.isUndefined(Draggable._dragging[this.element]) &&
Draggable._dragging[this.element]) return;
- if(Event.isLeftClick(event)) {
+ if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = ""
- if(src.tagName && (
- src.tagName=='INPUT' ||
- src.tagName=='SELECT' ||
- src.tagName=='OPTION' ||
- src.tagName=='BUTTON' ||
- src.tagName=='TEXTAREA')) return;
-
+ if((tag_name = src.tagName.toUpperCase()) && (
+ tag_name=='INPUT' ||
+ tag_name=='SELECT' ||
+ tag_name=='OPTION' ||
+ tag_name=='BUTTON' ||
+ tag_name=='TEXTAREA')) return;
+
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var pos = Position.cumulativeOffset(this.element);
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-
+
Draggables.activate(this);
Event.stop(event);
}
},
-
+
startDrag: function(event) {
this.dragging = true;
-
+ if(!this.delta)
+ this.delta = this.currentDelta();
+
if(this.options.zindex) {
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
this.element.style.zIndex = this.options.zindex;
}
-
+
if(this.options.ghosting) {
this._clone = this.element.cloneNode(true);
- Position.absolutize(this.element);
+ this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
+ if (!this._originallyAbsolute)
+ Position.absolutize(this.element);
this.element.parentNode.insertBefore(this._clone, this.element);
}
-
+
if(this.options.scroll) {
if (this.options.scroll == window) {
var where = this._getWindowScroll(this.options.scroll);
@@ -343,24 +347,28 @@
this.originalScrollTop = this.options.scroll.scrollTop;
}
}
-
+
Draggables.notify('onStart', this, event);
-
+
if(this.options.starteffect) this.options.starteffect(this.element);
},
-
+
updateDrag: function(event, pointer) {
if(!this.dragging) this.startDrag(event);
- Position.prepare();
- Droppables.show(pointer, this.element);
+
+ if(!this.options.quiet){
+ Position.prepare();
+ Droppables.show(pointer, this.element);
+ }
+
Draggables.notify('onDrag', this, event);
-
+
this.draw(pointer);
if(this.options.change) this.options.change(this);
-
+
if(this.options.scroll) {
this.stopScrolling();
-
+
var p;
if (this.options.scroll == window) {
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
@@ -378,32 +386,46 @@
if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
this.startScrolling(speed);
}
-
+
// fix AppleWebKit rendering
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
-
+ if(Prototype.Browser.WebKit) window.scrollBy(0,0);
+
Event.stop(event);
},
-
+
finishDrag: function(event, success) {
this.dragging = false;
+ if(this.options.quiet){
+ Position.prepare();
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ Droppables.show(pointer, this.element);
+ }
+
if(this.options.ghosting) {
- Position.relativize(this.element);
+ if (!this._originallyAbsolute)
+ Position.relativize(this.element);
+ delete this._originallyAbsolute;
Element.remove(this._clone);
this._clone = null;
}
- if(success) Droppables.fire(event, this.element);
+ var dropped = false;
+ if(success) {
+ dropped = Droppables.fire(event, this.element);
+ if (!dropped) dropped = false;
+ }
+ if(dropped && this.options.onDropped) this.options.onDropped(this.element);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
- if(revert && typeof revert == 'function') revert = revert(this.element);
-
+ if(revert && Object.isFunction(revert)) revert = revert(this.element);
+
var d = this.currentDelta();
if(revert && this.options.reverteffect) {
- this.options.reverteffect(this.element,
- d[1]-this.delta[1], d[0]-this.delta[0]);
+ if (dropped == 0 || revert != 'failure')
+ this.options.reverteffect(this.element,
+ d[1]-this.delta[1], d[0]-this.delta[0]);
} else {
this.delta = d;
}
@@ -411,67 +433,67 @@
if(this.options.zindex)
this.element.style.zIndex = this.originalZ;
- if(this.options.endeffect)
+ if(this.options.endeffect)
this.options.endeffect(this.element);
-
+
Draggables.deactivate(this);
Droppables.reset();
},
-
+
keyPress: function(event) {
if(event.keyCode!=Event.KEY_ESC) return;
this.finishDrag(event, false);
Event.stop(event);
},
-
+
endDrag: function(event) {
if(!this.dragging) return;
this.stopScrolling();
this.finishDrag(event, true);
Event.stop(event);
},
-
+
draw: function(point) {
var pos = Position.cumulativeOffset(this.element);
if(this.options.ghosting) {
var r = Position.realOffset(this.element);
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
}
-
+
var d = this.currentDelta();
pos[0] -= d[0]; pos[1] -= d[1];
-
+
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
}
-
- var p = [0,1].map(function(i){
- return (point[i]-pos[i]-this.offset[i])
+
+ var p = [0,1].map(function(i){
+ return (point[i]-pos[i]-this.offset[i])
}.bind(this));
-
+
if(this.options.snap) {
- if(typeof this.options.snap == 'function') {
+ if(Object.isFunction(this.options.snap)) {
p = this.options.snap(p[0],p[1],this);
} else {
- if(this.options.snap instanceof Array) {
+ if(Object.isArray(this.options.snap)) {
p = p.map( function(v, i) {
- return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
+ return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
} else {
p = p.map( function(v) {
- return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
+ return (v/this.options.snap).round()*this.options.snap }.bind(this));
}
}}
-
+
var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
style.top = p[1] + "px";
-
+
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
},
-
+
stopScrolling: function() {
if(this.scrollInterval) {
clearInterval(this.scrollInterval);
@@ -479,14 +501,14 @@
Draggables._lastScrollPointer = null;
}
},
-
+
startScrolling: function(speed) {
if(!(speed[0] || speed[1])) return;
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
this.lastScrolled = new Date();
this.scrollInterval = setInterval(this.scroll.bind(this), 10);
},
-
+
scroll: function() {
var current = new Date();
var delta = current - this.lastScrolled;
@@ -502,7 +524,7 @@
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
}
-
+
Position.prepare();
Droppables.show(Draggables._lastPointer, this.element);
Draggables.notify('onDrag', this);
@@ -516,10 +538,10 @@
Draggables._lastScrollPointer[1] = 0;
this.draw(Draggables._lastScrollPointer);
}
-
+
if(this.options.change) this.options.change(this);
},
-
+
_getWindowScroll: function(w) {
var T, L, W, H;
with (w.document) {
@@ -538,41 +560,42 @@
H = documentElement.clientHeight;
} else {
W = body.offsetWidth;
- H = body.offsetHeight
+ H = body.offsetHeight;
}
}
return { top: T, left: L, width: W, height: H };
}
-}
+});
+Draggable._dragging = { };
+
/*--------------------------------------------------------------------------*/
-var SortableObserver = Class.create();
-SortableObserver.prototype = {
+var SortableObserver = Class.create({
initialize: function(element, observer) {
this.element = $(element);
this.observer = observer;
this.lastValue = Sortable.serialize(this.element);
},
-
+
onStart: function() {
this.lastValue = Sortable.serialize(this.element);
},
-
+
onEnd: function() {
Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element))
this.observer(this.element)
}
-}
+});
var Sortable = {
SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
-
- sortables: {},
-
+
+ sortables: { },
+
_findRootElement: function(element) {
- while (element.tagName != "BODY") {
+ while (element.tagName.toUpperCase() != "BODY") {
if(element.id && Sortable.sortables[element.id]) return element;
element = element.parentNode;
}
@@ -583,22 +606,23 @@
if(!element) return;
return Sortable.sortables[element.id];
},
-
+
destroy: function(element){
- var s = Sortable.options(element);
-
+ element = $(element);
+ var s = Sortable.sortables[element.id];
+
if(s) {
Draggables.removeObserver(s.element);
s.droppables.each(function(d){ Droppables.remove(d) });
s.draggables.invoke('destroy');
-
+
delete Sortable.sortables[s.element.id];
}
},
create: function(element) {
element = $(element);
- var options = Object.extend({
+ var options = Object.extend({
element: element,
tag: 'li', // assumes li children, override with tag: 'tagname'
dropOnEmpty: false,
@@ -612,13 +636,20 @@
delay: 0,
hoverclass: null,
ghosting: false,
+ quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
format: this.SERIALIZE_RULE,
+
+ // these take arrays of elements or ids and can be
+ // used for better initialization performance
+ elements: false,
+ handles: false,
+
onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction
- }, arguments[1] || {});
+ }, arguments[1] || { });
// clear any old sortable with same element
this.destroy(element);
@@ -626,6 +657,7 @@
// build options for the draggables
var options_for_draggable = {
revert: true,
+ quiet: options.quiet,
scroll: options.scroll,
scrollSpeed: options.scrollSpeed,
scrollSensitivity: options.scrollSensitivity,
@@ -651,24 +683,24 @@
if(options.zindex)
options_for_draggable.zindex = options.zindex;
- // build options for the droppables
+ // build options for the droppables
var options_for_droppable = {
overlap: options.overlap,
containment: options.containment,
tree: options.tree,
hoverclass: options.hoverclass,
onHover: Sortable.onHover
- }
-
+ };
+
var options_for_tree = {
onHover: Sortable.onEmptyHover,
overlap: options.overlap,
containment: options.containment,
hoverclass: options.hoverclass
- }
+ };
// fix for gecko engine
- Element.cleanWhitespace(element);
+ Element.cleanWhitespace(element);
options.draggables = [];
options.droppables = [];
@@ -679,17 +711,16 @@
options.droppables.push(element);
}
- (this.findElements(element, options) || []).each( function(e) {
- // handles are per-draggable
- var handle = options.handle ?
- $(e).down('.'+options.handle,0) : e;
+ (options.elements || this.findElements(element, options) || []).each( function(e,i) {
+ var handle = options.handles ? $(options.handles[i]) :
+ (options.handle ? $(e).select('.' + options.handle)[0] : e);
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
if(options.tree) e.treeNode = element;
- options.droppables.push(e);
+ options.droppables.push(e);
});
-
+
if(options.tree) {
(Sortable.findTreeElements(element, options) || []).each( function(e) {
Droppables.add(e, options_for_tree);
@@ -711,7 +742,7 @@
return Element.findChildren(
element, options.only, options.tree ? true : false, options.tag);
},
-
+
findTreeElements: function(element, options) {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.treeTag);
@@ -728,7 +759,7 @@
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, dropon);
- if(dropon.parentNode!=oldParentNode)
+ if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
@@ -739,26 +770,26 @@
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, nextElement);
- if(dropon.parentNode!=oldParentNode)
+ if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
}
},
-
+
onEmptyHover: function(element, dropon, overlap) {
var oldParentNode = element.parentNode;
var droponOptions = Sortable.options(dropon);
-
+
if(!Element.isParent(dropon, element)) {
var index;
-
+
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null;
-
+
if(children) {
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
+
for (index = 0; index < children.length; index += 1) {
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
offset -= Element.offsetSize (children[index], droponOptions.overlap);
@@ -771,9 +802,9 @@
}
}
}
-
+
dropon.insertBefore(element, child);
-
+
Sortable.options(oldParentNode).onChange(element);
droponOptions.onChange(element);
}
@@ -786,34 +817,34 @@
mark: function(dropon, position) {
// mark on ghosting only
var sortable = Sortable.options(dropon.parentNode);
- if(sortable && !sortable.ghosting) return;
+ if(sortable && !sortable.ghosting) return;
if(!Sortable._marker) {
- Sortable._marker =
+ Sortable._marker =
($('dropmarker') || Element.extend(document.createElement('DIV'))).
hide().addClassName('dropmarker').setStyle({position:'absolute'});
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
- }
+ }
var offsets = Position.cumulativeOffset(dropon);
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
-
+
if(position=='after')
- if(sortable.overlap == 'horizontal')
+ if(sortable.overlap == 'horizontal')
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
else
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
-
+
Sortable._marker.show();
},
-
+
_tree: function(element, options, parent) {
var children = Sortable.findElements(element, options) || [];
-
+
for (var i = 0; i < children.length; ++i) {
var match = children[i].id.match(options.format);
if (!match) continue;
-
+
var child = {
id: encodeURIComponent(match ? match[1] : null),
element: element,
@@ -821,16 +852,16 @@
children: [],
position: parent.children.length,
container: $(children[i]).down(options.treeTag)
- }
-
+ };
+
/* Get the element containing the children and recurse over it */
if (child.container)
- this._tree(child.container, options, child)
-
+ this._tree(child.container, options, child);
+
parent.children.push (child);
}
- return parent;
+ return parent;
},
tree: function(element) {
@@ -842,16 +873,16 @@
only: sortableOptions.only,
name: element.id,
format: sortableOptions.format
- }, arguments[1] || {});
-
+ }, arguments[1] || { });
+
var root = {
id: null,
parent: null,
children: [],
container: element,
position: 0
- }
-
+ };
+
return Sortable._tree(element, options, root);
},
@@ -866,8 +897,8 @@
sequence: function(element) {
element = $(element);
- var options = Object.extend(this.options(element), arguments[1] || {});
-
+ var options = Object.extend(this.options(element), arguments[1] || { });
+
return $(this.findElements(element, options) || []).map( function(item) {
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
});
@@ -875,15 +906,15 @@
setSequence: function(element, new_sequence) {
element = $(element);
- var options = Object.extend(this.options(element), arguments[2] || {});
-
- var nodeMap = {};
+ var options = Object.extend(this.options(element), arguments[2] || { });
+
+ var nodeMap = { };
this.findElements(element, options).each( function(n) {
if (n.id.match(options.format))
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
n.parentNode.removeChild(n);
});
-
+
new_sequence.each(function(ident) {
var n = nodeMap[ident];
if (n) {
@@ -892,16 +923,16 @@
}
});
},
-
+
serialize: function(element) {
element = $(element);
- var options = Object.extend(Sortable.options(element), arguments[1] || {});
+ var options = Object.extend(Sortable.options(element), arguments[1] || { });
var name = encodeURIComponent(
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
-
+
if (options.tree) {
return Sortable.tree(element, arguments[1]).children.map( function (item) {
- return [name + Sortable._constructIndex(item) + "[id]=" +
+ return [name + Sortable._constructIndex(item) + "[id]=" +
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&');
} else {
@@ -910,16 +941,16 @@
}).join('&');
}
}
-}
+};
// Returns true if child is contained within element
Element.isParent = function(child, element) {
if (!child.parentNode || child == element) return false;
if (child.parentNode == element) return true;
return Element.isParent(child.parentNode, element);
-}
+};
-Element.findChildren = function(element, only, recursive, tagName) {
+Element.findChildren = function(element, only, recursive, tagName) {
if(!element.hasChildNodes()) return null;
tagName = tagName.toUpperCase();
if(only)
@@ -935,8 +966,8 @@
});
return (elements.length>0 ? elements.flatten() : []);
-}
+};
Element.offsetSize = function (element, type) {
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
-}
+};
\ No newline at end of file
Modified: branches/datasets/public/_javascript_s/effects.js (2857 => 2858)
--- branches/datasets/public/_javascript_s/effects.js 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/_javascript_s/effects.js 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,84 +1,55 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
-//
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
+// For details, see the script.aculo.us web site: http://script.aculo.us/
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
var color = '#';
- if(this.slice(0,4) == 'rgb(') {
- var cols = this.slice(4,this.length-1).split(',');
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
- } else {
- if(this.slice(0,1) == '#') {
- if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
- if(this.length==7) color = this.toLowerCase();
- }
- }
- return(color.length==7 ? color : (arguments[0] || this));
-}
+ if (this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if (this.slice(0,1) == '#') {
+ if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if (this.length==7) color = this.toLowerCase();
+ }
+ }
+ return (color.length==7 ? color : (arguments[0] || this));
+};
/*--------------------------------------------------------------------------*/
-Element.collectTextNodes = function(element) {
+Element.collectTextNodes = function(element) {
return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
+ return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
}).flatten().join('');
-}
+};
-Element.collectTextNodesIgnoreClass = function(element, className) {
+Element.collectTextNodesIgnoreClass = function(element, className) {
return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : ''));
}).flatten().join('');
-}
+};
Element.setContentZoom = function(element, percent) {
- element = $(element);
- element.setStyle({fontSize: (percent/100) + 'em'});
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ element = $(element);
+ element.setStyle({fontSize: (percent/100) + 'em'});
+ if (Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
-}
+};
-Element.getOpacity = function(element){
- element = $(element);
- var opacity;
- if (opacity = element.getStyle('opacity'))
- return parseFloat(opacity);
- if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
- if(opacity[1]) return parseFloat(opacity[1]) / 100;
- return 1.0;
-}
-
-Element.setOpacity = function(element, value){
- element= $(element);
- if (value == 1){
- element.setStyle({ opacity:
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
- 0.999999 : 1.0 });
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
- } else {
- if(value < 0.00001) value = 0;
- element.setStyle({opacity: value});
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.setStyle(
- { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')' });
- }
- return element;
-}
-
-Element.getInlineOpacity = function(element){
+Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
-}
+};
Element.forceRerendering = function(element) {
try {
@@ -91,32 +62,59 @@
/*--------------------------------------------------------------------------*/
-Array.prototype.call = function() {
- var args = arguments;
- this.each(function(f){ f.apply(this, args) });
-}
-
-/*--------------------------------------------------------------------------*/
-
var Effect = {
_elementDoesNotExistError: {
name: 'ElementDoesNotExistError',
message: 'The specified DOM element does not exist, but is required for this effect to operate'
},
+ Transitions: {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + .5;
+ },
+ reverse: function(pos) {
+ return 1-pos;
+ },
+ flicker: function(pos) {
+ var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
+ return pos > 1 ? 1 : pos;
+ },
+ wobble: function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
+ },
+ pulse: function(pos, pulses) {
+ return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
+ },
+ spring: function(pos) {
+ return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+ },
+ none: function(pos) {
+ return 0;
+ },
+ full: function(pos) {
+ return 1;
+ }
+ },
+ DefaultOptions: {
+ duration: 1.0, // seconds
+ fps: 100, // 100= assume 66fps max.
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+ },
tagifyText: function(element) {
- if(typeof Builder == 'undefined')
- throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
-
var tagifyStyle = 'position:relative';
- if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
-
+ if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+
element = $(element);
$A(element.childNodes).each( function(child) {
- if(child.nodeType==3) {
+ if (child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
- Builder.node('span',{style: tagifyStyle},
- character == ' ' ? String.fromCharCode(160) : character),
+ new Element('span', {style: tagifyStyle}).update(
+ character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
@@ -125,17 +123,17 @@
},
multiple: function(element, effect) {
var elements;
- if(((typeof element == 'object') ||
- (typeof element == 'function')) &&
+ if (((typeof element == 'object') ||
+ Object.isFunction(element)) &&
(element.length))
elements = element;
else
elements = $(element).childNodes;
-
+
var options = Object.extend({
speed: 0.1,
delay: 0.0
- }, arguments[2] || {});
+ }, arguments[2] || { });
var masterDelay = options.delay;
$A(elements).each( function(element, index) {
@@ -152,50 +150,17 @@
effect = (effect || 'appear').toLowerCase();
var options = Object.extend({
queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
- }, arguments[2] || {});
- Effect[element.visible() ?
+ }, arguments[2] || { });
+ Effect[element.visible() ?
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
}
};
-var Effect2 = Effect; // deprecated
+Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
-/* ------------- transitions ------------- */
-
-Effect.Transitions = {
- linear: Prototype.K,
- sinoidal: function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
- },
- reverse: function(pos) {
- return 1-pos;
- },
- flicker: function(pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
- },
- wobble: function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
- },
- pulse: function(pos, pulses) {
- pulses = pulses || 5;
- return (
- Math.round((pos % (1/pulses)) * pulses) == 0 ?
- ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
- 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
- );
- },
- none: function(pos) {
- return 0;
- },
- full: function(pos) {
- return 1;
- }
-};
-
/* ------------- core effects ------------- */
-Effect.ScopedQueue = Class.create();
-Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+Effect.ScopedQueue = Class.create(Enumerable, {
initialize: function() {
this.effects = [];
this.interval = null;
@@ -205,13 +170,13 @@
},
add: function(effect) {
var timestamp = new Date().getTime();
-
- var position = (typeof effect.options.queue == 'string') ?
+
+ var position = Object.isString(effect.options.queue) ?
effect.options.queue : effect.options.queue.position;
-
+
switch(position) {
case 'front':
- // move unstarted effects after this effect
+ // move unstarted effects after this effect
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
e.startOn += effect.finishOn;
e.finishOn += effect.finishOn;
@@ -225,119 +190,127 @@
timestamp = this.effects.pluck('finishOn').max() || timestamp;
break;
}
-
+
effect.startOn += timestamp;
effect.finishOn += timestamp;
- if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+ if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
-
- if(!this.interval)
- this.interval = setInterval(this.loop.bind(this), 40);
+
+ if (!this.interval)
+ this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
this.effects = this.effects.reject(function(e) { return e==effect });
- if(this.effects.length == 0) {
+ if (this.effects.length == 0) {
clearInterval(this.interval);
this.interval = null;
}
},
loop: function() {
var timePos = new Date().getTime();
- this.effects.invoke('loop', timePos);
+ for(var i=0, len=this.effects.length;i<len;i++)
+ this.effects[i] && this.effects[i].loop(timePos);
}
});
Effect.Queues = {
instances: $H(),
get: function(queueName) {
- if(typeof queueName != 'string') return queueName;
-
- if(!this.instances[queueName])
- this.instances[queueName] = new Effect.ScopedQueue();
-
- return this.instances[queueName];
+ if (!Object.isString(queueName)) return queueName;
+
+ return this.instances.get(queueName) ||
+ this.instances.set(queueName, new Effect.ScopedQueue());
}
-}
+};
Effect.Queue = Effect.Queues.get('global');
-Effect.DefaultOptions = {
- transition: Effect.Transitions.sinoidal,
- duration: 1.0, // seconds
- fps: 25.0, // max. 25fps due to Effect.Queue implementation
- sync: false, // true for combining
- from: 0.0,
- to: 1.0,
- delay: 0.0,
- queue: 'parallel'
-}
-
-Effect.Base = function() {};
-Effect.Base.prototype = {
+Effect.Base = Class.create({
position: null,
start: function(options) {
- this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
+ function codeForEvent(options,eventName){
+ return (
+ (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
+ (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
+ );
+ }
+ if (options && options.transition === false) options.transition = Effect.Transitions.linear;
+ this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
this.currentFrame = 0;
this.state = 'idle';
this.startOn = this.options.delay*1000;
- this.finishOn = this.startOn + (this.options.duration*1000);
+ this.finishOn = this.startOn+(this.options.duration*1000);
+ this.fromToDelta = this.options.to-this.options.from;
+ this.totalTime = this.finishOn-this.startOn;
+ this.totalFrames = this.options.fps*this.options.duration;
+
+ this.render = (function() {
+ function dispatch(effect, eventName) {
+ if (effect.options[eventName + 'Internal'])
+ effect.options[eventName + 'Internal'](effect);
+ if (effect.options[eventName])
+ effect.options[eventName](effect);
+ }
+
+ return function(pos) {
+ if (this.state === "idle") {
+ this.state = "running";
+ dispatch(this, 'beforeSetup');
+ if (this.setup) this.setup();
+ dispatch(this, 'afterSetup');
+ }
+ if (this.state === "running") {
+ pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
+ this.position = pos;
+ dispatch(this, 'beforeUpdate');
+ if (this.update) this.update(pos);
+ dispatch(this, 'afterUpdate');
+ }
+ };
+ })();
+
this.event('beforeStart');
- if(!this.options.sync)
- Effect.Queues.get(typeof this.options.queue == 'string' ?
+ if (!this.options.sync)
+ Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).add(this);
},
loop: function(timePos) {
- if(timePos >= this.startOn) {
- if(timePos >= this.finishOn) {
+ if (timePos >= this.startOn) {
+ if (timePos >= this.finishOn) {
this.render(1.0);
this.cancel();
this.event('beforeFinish');
- if(this.finish) this.finish();
+ if (this.finish) this.finish();
this.event('afterFinish');
- return;
+ return;
}
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
- var frame = Math.round(pos * this.options.fps * this.options.duration);
- if(frame > this.currentFrame) {
+ var pos = (timePos - this.startOn) / this.totalTime,
+ frame = (pos * this.totalFrames).round();
+ if (frame > this.currentFrame) {
this.render(pos);
this.currentFrame = frame;
}
}
},
- render: function(pos) {
- if(this.state == 'idle') {
- this.state = 'running';
- this.event('beforeSetup');
- if(this.setup) this.setup();
- this.event('afterSetup');
- }
- if(this.state == 'running') {
- if(this.options.transition) pos = this.options.transition(pos);
- pos *= (this.options.to-this.options.from);
- pos += this.options.from;
- this.position = pos;
- this.event('beforeUpdate');
- if(this.update) this.update(pos);
- this.event('afterUpdate');
- }
- },
cancel: function() {
- if(!this.options.sync)
- Effect.Queues.get(typeof this.options.queue == 'string' ?
+ if (!this.options.sync)
+ Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).remove(this);
this.state = 'finished';
},
event: function(eventName) {
- if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
- if(this.options[eventName]) this.options[eventName](this);
+ if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+ if (this.options[eventName]) this.options[eventName](this);
},
inspect: function() {
- return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
+ var data = ""
+ for(property in this)
+ if (!Object.isFunction(this[property])) data.set(property, this[property]);
+ return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
}
-}
+});
-Effect.Parallel = Class.create();
-Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
+Effect.Parallel = Class.create(Effect.Base, {
initialize: function(effects) {
this.effects = effects || [];
this.start(arguments[1]);
@@ -350,35 +323,45 @@
effect.render(1.0);
effect.cancel();
effect.event('beforeFinish');
- if(effect.finish) effect.finish(position);
+ if (effect.finish) effect.finish(position);
effect.event('afterFinish');
});
}
});
-Effect.Event = Class.create();
-Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+Effect.Tween = Class.create(Effect.Base, {
+ initialize: function(object, from, to) {
+ object = Object.isString(object) ? $(object) : object;
+ var args = $A(arguments), method = args.last(),
+ options = args.length == 5 ? args[3] : null;
+ this.method = Object.isFunction(method) ? method.bind(object) :
+ Object.isFunction(object[method]) ? object[method].bind(object) :
+ function(value) { object[method] = value };
+ this.start(Object.extend({ from: from, to: to }, options || { }));
+ },
+ update: function(position) {
+ this.method(position);
+ }
+});
+
+Effect.Event = Class.create(Effect.Base, {
initialize: function() {
- var options = Object.extend({
- duration: 0
- }, arguments[0] || {});
- this.start(options);
+ this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
},
update: Prototype.emptyFunction
});
-Effect.Opacity = Class.create();
-Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
+Effect.Opacity = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
- if(!this.element) throw(Effect._elementDoesNotExistError);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
// make this work on IE on elements without 'layout'
- if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
var options = Object.extend({
from: this.element.getOpacity() || 0.0,
to: 1.0
- }, arguments[1] || {});
+ }, arguments[1] || { });
this.start(options);
},
update: function(position) {
@@ -386,139 +369,133 @@
}
});
-Effect.Move = Class.create();
-Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
+Effect.Move = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
- if(!this.element) throw(Effect._elementDoesNotExistError);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
x: 0,
y: 0,
mode: 'relative'
- }, arguments[1] || {});
+ }, arguments[1] || { });
this.start(options);
},
setup: function() {
- // Bug in Opera: Opera returns the "real" position of a static element or
- // relative element that does not have top/left explicitly set.
- // ==> Always set top and left for position relative elements in your stylesheets
- // (to 0 if you do not need them)
this.element.makePositioned();
this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
this.originalTop = parseFloat(this.element.getStyle('top') || '0');
- if(this.options.mode == 'absolute') {
- // absolute movement, so we need to calc deltaX and deltaY
+ if (this.options.mode == 'absolute') {
this.options.x = this.options.x - this.originalLeft;
this.options.y = this.options.y - this.originalTop;
}
},
update: function(position) {
this.element.setStyle({
- left: Math.round(this.options.x * position + this.originalLeft) + 'px',
- top: Math.round(this.options.y * position + this.originalTop) + 'px'
+ left: (this.options.x * position + this.originalLeft).round() + 'px',
+ top: (this.options.y * position + this.originalTop).round() + 'px'
});
}
});
// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
- return new Effect.Move(element,
- Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
+ return new Effect.Move(element,
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};
-Effect.Scale = Class.create();
-Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
+Effect.Scale = Class.create(Effect.Base, {
initialize: function(element, percent) {
this.element = $(element);
- if(!this.element) throw(Effect._elementDoesNotExistError);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
scaleX: true,
scaleY: true,
scaleContent: true,
scaleFromCenter: false,
- scaleMode: 'box', // 'box' or 'contents' or {} with provided values
+ scaleMode: 'box', // 'box' or 'contents' or { } with provided values
scaleFrom: 100.0,
scaleTo: percent
- }, arguments[2] || {});
+ }, arguments[2] || { });
this.start(options);
},
setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = this.element.getStyle('position');
-
- this.originalStyle = {};
+
+ this.originalStyle = { };
['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k];
}.bind(this));
-
+
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
-
+
var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) {
- if(fontSize.indexOf(fontSizeType)>0) {
+ if (fontSize.indexOf(fontSizeType)>0) {
this.fontSize = parseFloat(fontSize);
this.fontSizeType = fontSizeType;
}
}.bind(this));
-
+
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
-
+
this.dims = null;
- if(this.options.scaleMode=='box')
+ if (this.options.scaleMode=='box')
this.dims = [this.element.offsetHeight, this.element.offsetWidth];
- if(/^content/.test(this.options.scaleMode))
+ if (/^content/.test(this.options.scaleMode))
this.dims = [this.element.scrollHeight, this.element.scrollWidth];
- if(!this.dims)
+ if (!this.dims)
this.dims = [this.options.scaleMode.originalHeight,
this.options.scaleMode.originalWidth];
},
update: function(position) {
var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
- if(this.options.scaleContent && this.fontSize)
+ if (this.options.scaleContent && this.fontSize)
this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
},
finish: function(position) {
- if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
},
setDimensions: function(height, width) {
- var d = {};
- if(this.options.scaleX) d.width = Math.round(width) + 'px';
- if(this.options.scaleY) d.height = Math.round(height) + 'px';
- if(this.options.scaleFromCenter) {
+ var d = { };
+ if (this.options.scaleX) d.width = width.round() + 'px';
+ if (this.options.scaleY) d.height = height.round() + 'px';
+ if (this.options.scaleFromCenter) {
var topd = (height - this.dims[0])/2;
var leftd = (width - this.dims[1])/2;
- if(this.elementPositioning == 'absolute') {
- if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
- if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+ if (this.elementPositioning == 'absolute') {
+ if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
+ if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
} else {
- if(this.options.scaleY) d.top = -topd + 'px';
- if(this.options.scaleX) d.left = -leftd + 'px';
+ if (this.options.scaleY) d.top = -topd + 'px';
+ if (this.options.scaleX) d.left = -leftd + 'px';
}
}
this.element.setStyle(d);
}
});
-Effect.Highlight = Class.create();
-Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+Effect.Highlight = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
- if(!this.element) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
this.start(options);
},
setup: function() {
// Prevent executing on elements not in the layout flow
- if(this.element.getStyle('display')=='none') { this.cancel(); return; }
+ if (this.element.getStyle('display')=='none') { this.cancel(); return; }
// Disable background image during the effect
- this.oldStyle = {
- backgroundImage: this.element.getStyle('background-image') };
- this.element.setStyle({backgroundImage: 'none'});
- if(!this.options.endcolor)
+ this.oldStyle = { };
+ if (!this.options.keepBackgroundImage) {
+ this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+ this.element.setStyle({backgroundImage: 'none'});
+ }
+ if (!this.options.endcolor)
this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
- if(!this.options.restorecolor)
+ if (!this.options.restorecolor)
this.options.restorecolor = this.element.getStyle('background-color');
// init color calculations
this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
@@ -526,7 +503,7 @@
},
update: function(position) {
this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
- return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
+ return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
},
finish: function() {
this.element.setStyle(Object.extend(this.oldStyle, {
@@ -535,45 +512,36 @@
}
});
-Effect.ScrollTo = Class.create();
-Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
- initialize: function(element) {
- this.element = $(element);
- this.start(arguments[1] || {});
- },
- setup: function() {
- Position.prepare();
- var offsets = Position.cumulativeOffset(this.element);
- if(this.options.offset) offsets[1] += this.options.offset;
- var max = window.innerHeight ?
- window.height - window.innerHeight :
- document.body.scrollHeight -
- (document.documentElement.clientHeight ?
- document.documentElement.clientHeight : document.body.clientHeight);
- this.scrollStart = Position.deltaY;
- this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
- },
- update: function(position) {
- Position.prepare();
- window.scrollTo(Position.deltaX,
- this.scrollStart + (position*this.delta));
- }
-});
+Effect.ScrollTo = function(element) {
+ var options = arguments[1] || { },
+ scrollOffsets = document.viewport.getScrollOffsets(),
+ elementOffsets = $(element).cumulativeOffset();
+ if (options.offset) elementOffsets[1] += options.offset;
+
+ return new Effect.Tween(null,
+ scrollOffsets.top,
+ elementOffsets[1],
+ options,
+ function(p){ scrollTo(scrollOffsets.left, p.round()); }
+ );
+};
+
/* ------------- combination effects ------------- */
Effect.Fade = function(element) {
element = $(element);
var oldOpacity = element.getInlineOpacity();
var options = Object.extend({
- from: element.getOpacity() || 1.0,
- to: 0.0,
- afterFinishInternal: function(effect) {
- if(effect.options.to!=0) return;
- effect.element.hide().setStyle({opacity: oldOpacity});
- }}, arguments[1] || {});
+ from: element.getOpacity() || 1.0,
+ to: 0.0,
+ afterFinishInternal: function(effect) {
+ if (effect.options.to!=0) return;
+ effect.element.hide().setStyle({opacity: oldOpacity});
+ }
+ }, arguments[1] || { });
return new Effect.Opacity(element,options);
-}
+};
Effect.Appear = function(element) {
element = $(element);
@@ -585,15 +553,15 @@
effect.element.forceRerendering();
},
beforeSetup: function(effect) {
- effect.element.setOpacity(effect.options.from).show();
- }}, arguments[1] || {});
+ effect.element.setOpacity(effect.options.from).show();
+ }}, arguments[1] || { });
return new Effect.Opacity(element,options);
-}
+};
Effect.Puff = function(element) {
element = $(element);
- var oldStyle = {
- opacity: element.getInlineOpacity(),
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
position: element.getStyle('position'),
top: element.style.top,
left: element.style.left,
@@ -601,50 +569,50 @@
height: element.style.height
};
return new Effect.Parallel(
- [ new Effect.Scale(element, 200,
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
- Object.extend({ duration: 1.0,
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) {
- Position.absolutize(effect.effects[0].element)
+ Position.absolutize(effect.effects[0].element);
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().setStyle(oldStyle); }
- }, arguments[1] || {})
+ }, arguments[1] || { })
);
-}
+};
Effect.BlindUp = function(element) {
element = $(element);
element.makeClipping();
return new Effect.Scale(element, 0,
- Object.extend({ scaleContent: false,
- scaleX: false,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping();
- }
- }, arguments[1] || {})
+ }
+ }, arguments[1] || { })
);
-}
+};
Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
- effect.element.makeClipping().setStyle({height: '0px'}).show();
- },
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
afterFinishInternal: function(effect) {
effect.element.undoClipping();
}
- }, arguments[1] || {}));
-}
+ }, arguments[1] || { }));
+};
Effect.SwitchOff = function(element) {
element = $(element);
@@ -654,19 +622,19 @@
from: 0,
transition: Effect.Transitions.flicker,
afterFinishInternal: function(effect) {
- new Effect.Scale(effect.element, 1, {
+ new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function(effect) {
+ beforeSetup: function(effect) {
effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
- })
+ });
}
- }, arguments[1] || {}));
-}
+ }, arguments[1] || { }));
+};
Effect.DropOut = function(element) {
element = $(element);
@@ -675,107 +643,115 @@
left: element.getStyle('left'),
opacity: element.getInlineOpacity() };
return new Effect.Parallel(
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
beforeSetup: function(effect) {
- effect.effects[0].element.makePositioned();
+ effect.effects[0].element.makePositioned();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
- }
- }, arguments[1] || {}));
-}
+ }
+ }, arguments[1] || { }));
+};
Effect.Shake = function(element) {
element = $(element);
+ var options = Object.extend({
+ distance: 20,
+ duration: 0.5
+ }, arguments[1] || {});
+ var distance = parseFloat(options.distance);
+ var split = parseFloat(options.duration) / 10.0;
var oldStyle = {
top: element.getStyle('top'),
left: element.getStyle('left') };
- return new Effect.Move(element,
- { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+ return new Effect.Move(element,
+ { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
- { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
- { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
- { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
- { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
- { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+ { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle);
- }}) }}) }}) }}) }}) }});
-}
+ }}); }}); }}); }}); }}); }});
+};
Effect.SlideDown = function(element) {
element = $(element).cleanWhitespace();
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makePositioned();
effect.element.down().makePositioned();
- if(window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping().setStyle({height: '0px'}).show();
+ if (window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
},
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
effect.element.undoClipping().undoPositioned();
effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
- }, arguments[1] || {})
+ }, arguments[1] || { })
);
-}
+};
Effect.SlideUp = function(element) {
element = $(element).cleanWhitespace();
var oldInnerBottom = element.down().getStyle('bottom');
+ var elementDimensions = element.getDimensions();
return new Effect.Scale(element, window.opera ? 0 : 1,
- Object.extend({ scaleContent: false,
- scaleX: false,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
- beforeStartInternal: function(effect) {
+ afterSetup: function(effect) {
effect.element.makePositioned();
effect.element.down().makePositioned();
- if(window.opera) effect.element.setStyle({top: ''});
+ if (window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().show();
- },
+ },
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
- effect.element.down().undoPositioned();
+ effect.element.hide().undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
}
- }, arguments[1] || {})
+ }, arguments[1] || { })
);
-}
+};
-// Bug in opera makes the TD containing this element expand for a instance after finish
+// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
- return new Effect.Scale(element, window.opera ? 1 : 0, {
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
restoreAfterFinish: true,
beforeSetup: function(effect) {
- effect.element.makeClipping();
- },
+ effect.element.makeClipping();
+ },
afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping();
+ effect.element.hide().undoClipping();
}
});
-}
+};
Effect.Grow = function(element) {
element = $(element);
@@ -784,7 +760,7 @@
moveTransition: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.full
- }, arguments[1] || {});
+ }, arguments[1] || { });
var oldStyle = {
top: element.style.top,
left: element.style.left,
@@ -792,13 +768,13 @@
width: element.style.width,
opacity: element.getInlineOpacity() };
- var dims = element.getDimensions();
+ var dims = element.getDimensions();
var initialMoveX, initialMoveY;
var moveX, moveY;
-
+
switch (options.direction) {
case 'top-left':
- initialMoveX = initialMoveY = moveX = moveY = 0;
+ initialMoveX = initialMoveY = moveX = moveY = 0;
break;
case 'top-right':
initialMoveX = dims.width;
@@ -823,11 +799,11 @@
moveY = -dims.height / 2;
break;
}
-
+
return new Effect.Move(element, {
x: initialMoveX,
y: initialMoveY,
- duration: 0.01,
+ duration: 0.01,
beforeSetup: function(effect) {
effect.element.hide().makeClipping().makePositioned();
},
@@ -836,20 +812,20 @@
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) {
- effect.effects[0].element.setStyle({height: '0px'}).show();
+ effect.effects[0].element.setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
- )
+ );
}
});
-}
+};
Effect.Shrink = function(element) {
element = $(element);
@@ -858,7 +834,7 @@
moveTransition: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.none
- }, arguments[1] || {});
+ }, arguments[1] || { });
var oldStyle = {
top: element.style.top,
left: element.style.left,
@@ -868,7 +844,7 @@
var dims = element.getDimensions();
var moveX, moveY;
-
+
switch (options.direction) {
case 'top-left':
moveX = moveY = 0;
@@ -885,38 +861,40 @@
moveX = dims.width;
moveY = dims.height;
break;
- case 'center':
+ case 'center':
moveX = dims.width / 2;
moveY = dims.height / 2;
break;
}
-
+
return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
- ], Object.extend({
+ ], Object.extend({
beforeStartInternal: function(effect) {
- effect.effects[0].element.makePositioned().makeClipping();
+ effect.effects[0].element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
}, options)
);
-}
+};
Effect.Pulsate = function(element) {
element = $(element);
- var options = arguments[1] || {};
- var oldOpacity = element.getInlineOpacity();
- var transition = options.transition || Effect.Transitions.sinoidal;
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
- reverser.bind(transition);
- return new Effect.Opacity(element,
+ var options = arguments[1] || { },
+ oldOpacity = element.getInlineOpacity(),
+ transition = options.transition || Effect.Transitions.linear,
+ reverser = function(pos){
+ return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
+ };
+
+ return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
-}
+};
Effect.Fold = function(element) {
element = $(element);
@@ -926,47 +904,81 @@
width: element.style.width,
height: element.style.height };
element.makeClipping();
- return new Effect.Scale(element, 5, Object.extend({
+ return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
scaleX: false,
afterFinishInternal: function(effect) {
- new Effect.Scale(element, 1, {
- scaleContent: false,
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().setStyle(oldStyle);
} });
- }}, arguments[1] || {}));
+ }}, arguments[1] || { }));
};
-Effect.Morph = Class.create();
-Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
+Effect.Morph = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
- if(!this.element) throw(Effect._elementDoesNotExistError);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
- style: ''
- }, arguments[1] || {});
+ style: { }
+ }, arguments[1] || { });
+
+ if (!Object.isString(options.style)) this.style = $H(options.style);
+ else {
+ if (options.style.include(':'))
+ this.style = options.style.parseStyle();
+ else {
+ this.element.addClassName(options.style);
+ this.style = $H(this.element.getStyles());
+ this.element.removeClassName(options.style);
+ var css = this.element.getStyles();
+ this.style = this.style.reject(function(style) {
+ return style.value == css[style.key];
+ });
+ options.afterFinishInternal = function(effect) {
+ effect.element.addClassName(effect.options.style);
+ effect.transforms.each(function(transform) {
+ effect.element.style[transform.style] = '';
+ });
+ };
+ }
+ }
this.start(options);
},
+
setup: function(){
function parseColor(color){
- if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+ if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
color = color.parseColor();
return $R(0,2).map(function(i){
- return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ return parseInt( color.slice(i*2+1,i*2+3), 16 );
});
}
- this.transforms = this.options.style.parseStyle().map(function(property){
- var originalValue = this.element.getStyle(property[0]);
- return $H({
- style: property[0],
- originalValue: property[1].unit=='color' ?
- parseColor(originalValue) : parseFloat(originalValue || 0),
- targetValue: property[1].unit=='color' ?
- parseColor(property[1].value) : property[1].value,
- unit: property[1].unit
- });
+ this.transforms = this.style.map(function(pair){
+ var property = pair[0], value = pair[1], unit = null;
+
+ if (value.parseColor('#zzzzzz') != '#zzzzzz') {
+ value = value.parseColor();
+ unit = 'color';
+ } else if (property == 'opacity') {
+ value = parseFloat(value);
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ } else if (Element.CSS_LENGTH.test(value)) {
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+ value = parseFloat(components[1]);
+ unit = (components.length == 3) ? components[2] : null;
+ }
+
+ var originalValue = this.element.getStyle(property);
+ return {
+ style: property.camelize(),
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ targetValue: unit=='color' ? parseColor(value) : value,
+ unit: unit
+ };
}.bind(this)).reject(function(transform){
return (
(transform.originalValue == transform.targetValue) ||
@@ -974,36 +986,39 @@
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
- )
+ );
});
},
update: function(position) {
- var style = $H(), value = null;
- this.transforms.each(function(transform){
- value = transform.unit=='color' ?
- $R(0,2).inject('#',function(m,v,i){
- return m+(Math.round(transform.originalValue[i]+
- (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) :
- transform.originalValue + Math.round(
- ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
- style[transform.style] = value;
- });
- this.element.setStyle(style);
+ var style = { }, transform, i = this.transforms.length;
+ while(i--)
+ style[(transform = this.transforms[i]).style] =
+ transform.unit=='color' ? '#'+
+ (Math.round(transform.originalValue[0]+
+ (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
+ (Math.round(transform.originalValue[1]+
+ (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
+ (Math.round(transform.originalValue[2]+
+ (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
+ (transform.originalValue +
+ (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+ (transform.unit === null ? '' : transform.unit);
+ this.element.setStyle(style, true);
}
});
-Effect.Transform = Class.create();
-Object.extend(Effect.Transform.prototype, {
+Effect.Transform = Class.create({
initialize: function(tracks){
this.tracks = [];
- this.options = arguments[1] || {};
+ this.options = arguments[1] || { };
this.addTracks(tracks);
},
addTracks: function(tracks){
tracks.each(function(track){
- var data = ""
+ track = $H(track);
+ var data = ""
this.tracks.push($H({
- ids: $H(track).keys().first(),
+ ids: track.keys().first(),
effect: Effect.Morph,
options: { style: data }
}));
@@ -1013,76 +1028,101 @@
play: function(){
return new Effect.Parallel(
this.tracks.map(function(track){
- var elements = [$(track.ids) || $$(track.ids)].flatten();
- return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
+ var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
+ var elements = [$(ids) || $$(ids)].flatten();
+ return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
}).flatten(),
this.options
);
}
});
-Element.CSS_PROPERTIES = ['azimuth', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
- 'backgroundPosition', 'backgroundRepeat', 'borderBottomColor', 'borderBottomStyle',
- 'borderBottomWidth', 'borderCollapse', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth',
- 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderSpacing', 'borderTopColor',
- 'borderTopStyle', 'borderTopWidth', 'bottom', 'captionSide', 'clear', 'clip', 'color', 'content',
- 'counterIncrement', 'counterReset', 'cssFloat', 'cueAfter', 'cueBefore', 'cursor', 'direction',
- 'display', 'elevation', 'emptyCells', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
- 'fontStyle', 'fontVariant', 'fontWeight', 'height', 'left', 'letterSpacing', 'lineHeight',
- 'listStyleImage', 'listStylePosition', 'listStyleType', 'marginBottom', 'marginLeft', 'marginRight',
- 'marginTop', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'opacity',
- 'orphans', 'outlineColor', 'outlineOffset', 'outlineStyle', 'outlineWidth', 'overflowX', 'overflowY',
- 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'page', 'pageBreakAfter', 'pageBreakBefore',
- 'pageBreakInside', 'pauseAfter', 'pauseBefore', 'pitch', 'pitchRange', 'position', 'quotes',
- 'richness', 'right', 'size', 'speakHeader', 'speakNumeral', 'speakPunctuation', 'speechRate', 'stress',
- 'tableLayout', 'textAlign', 'textDecoration', 'textIndent', 'textShadow', 'textTransform', 'top',
- 'unicodeBidi', 'verticalAlign', 'visibility', 'voiceFamily', 'volume', 'whiteSpace', 'widows',
- 'width', 'wordSpacing', 'zIndex'];
-
+Element.CSS_PROPERTIES = $w(
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+ 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+ 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+ 'fontSize fontWeight height left letterSpacing lineHeight ' +
+ 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+ 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+ 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+ 'right textIndent top width wordSpacing zIndex');
+
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
- var element = Element.extend(document.createElement('div'));
- element.innerHTML = '<div style="' + this + '"></div>';
- var style = element.down().style, styleRules = $H();
-
+ var style, styleRules = $H();
+ if (Prototype.Browser.WebKit)
+ style = new Element('div',{style:this}).style;
+ else {
+ String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
+ style = String.__parseStyleElement.childNodes[0].style;
+ }
+
Element.CSS_PROPERTIES.each(function(property){
- if(style[property]) styleRules[property] = style[property];
+ if (style[property]) styleRules.set(property, style[property]);
});
-
- var result = $H();
-
- styleRules.each(function(pair){
- var property = pair[0], value = pair[1], unit = null;
-
- if(value.parseColor('#zzzzzz') != '#zzzzzz') {
- value = value.parseColor();
- unit = 'color';
- } else if(Element.CSS_LENGTH.test(value))
- var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
- value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;
-
- result[property.underscore().dasherize()] = $H({ value:value, unit:unit });
- }.bind(this));
-
- return result;
+
+ if (Prototype.Browser.IE && this.include('opacity'))
+ styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
+
+ return styleRules;
};
-Element.morph = function(element, style) {
- new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
- return element;
+if (document.defaultView && document.defaultView.getComputedStyle) {
+ Element.getStyles = function(element) {
+ var css = document.defaultView.getComputedStyle($(element), null);
+ return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
+ styles[property] = css[property];
+ return styles;
+ });
+ };
+} else {
+ Element.getStyles = function(element) {
+ element = $(element);
+ var css = element.currentStyle, styles;
+ styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
+ results[property] = css[property];
+ return results;
+ });
+ if (!styles.opacity) styles.opacity = element.getOpacity();
+ return styles;
+ };
+}
+
+Effect.Methods = {
+ morph: function(element, style) {
+ element = $(element);
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
+ return element;
+ },
+ visualEffect: function(element, effect, options) {
+ element = $(element);
+ var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[klass](element, options);
+ return element;
+ },
+ highlight: function(element, options) {
+ element = $(element);
+ new Effect.Highlight(element, options);
+ return element;
+ }
};
-['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
- 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
- function(f) { Element.Methods[f] = Element[f]; }
+$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
+ 'pulsate shake puff squish switchOff dropOut').each(
+ function(effect) {
+ Effect.Methods[effect] = function(element, options){
+ element = $(element);
+ Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
+ return element;
+ };
+ }
);
-Element.Methods.visualEffect = function(element, effect, options) {
- s = effect.gsub(/_/, '-').camelize();
- effect_class = s.charAt(0).toUpperCase() + s.substring(1);
- new Effect[effect_class](element, options);
- return $(element);
-};
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+ function(f) { Effect.Methods[f] = Element[f]; }
+);
-Element.addMethods();
\ No newline at end of file
+Element.addMethods(Effect.Methods);
\ No newline at end of file
Modified: branches/datasets/public/_javascript_s/prototype.js (2857 => 2858)
--- branches/datasets/public/_javascript_s/prototype.js 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/_javascript_s/prototype.js 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,51 +1,157 @@
-/* Prototype _javascript_ framework, version 1.5.0
- * (c) 2005-2007 Sam Stephenson
+/* Prototype _javascript_ framework, version 1.6.0.3
+ * (c) 2005-2008 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
- * For details, see the Prototype web site: http://prototype.conio.net/
+ * For details, see the Prototype web site: http://www.prototypejs.org/
*
-/*--------------------------------------------------------------------------*/
+ *--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.5.0',
+ Version: '1.6.0.3',
+
+ Browser: {
+ IE: !!(window.attachEvent &&
+ navigator.userAgent.indexOf('Opera') === -1),
+ Opera: navigator.userAgent.indexOf('Opera') > -1,
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
+ navigator.userAgent.indexOf('KHTML') === -1,
+ MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+ },
+
BrowserFeatures: {
- XPath: !!document.evaluate
+ XPath: !!document.evaluate,
+ SelectorsAPI: !!document.querySelector,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ document.createElement('div')['__proto__'] &&
+ document.createElement('div')['__proto__'] !==
+ document.createElement('form')['__proto__']
},
- ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
- emptyFunction: function() {},
+ ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+ JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+ emptyFunction: function() { },
K: function(x) { return x }
-}
+};
+if (Prototype.Browser.MobileSafari)
+ Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+
+/* Based on Alex Arnell's inheritance implementation. */
var Class = {
create: function() {
- return function() {
+ var parent = null, properties = $A(arguments);
+ if (Object.isFunction(properties[0]))
+ parent = properties.shift();
+
+ function klass() {
this.initialize.apply(this, arguments);
}
+
+ Object.extend(klass, Class.Methods);
+ klass.superclass = parent;
+ klass.subclasses = [];
+
+ if (parent) {
+ var subclass = function() { };
+ subclass.prototype = parent.prototype;
+ klass.prototype = new subclass;
+ parent.subclasses.push(klass);
+ }
+
+ for (var i = 0; i < properties.length; i++)
+ klass.addMethods(properties[i]);
+
+ if (!klass.prototype.initialize)
+ klass.prototype.initialize = Prototype.emptyFunction;
+
+ klass.prototype.constructor = klass;
+
+ return klass;
}
-}
+};
-var Abstract = new Object();
+Class.Methods = {
+ addMethods: function(source) {
+ var ancestor = this.superclass && this.superclass.prototype;
+ var properties = Object.keys(source);
+ if (!Object.keys({ toString: true }).length)
+ properties.push("toString", "valueOf");
+
+ for (var i = 0, length = properties.length; i < length; i++) {
+ var property = properties[i], value = source[property];
+ if (ancestor && Object.isFunction(value) &&
+ value.argumentNames().first() == "$super") {
+ var method = value;
+ value = (function(m) {
+ return function() { return ancestor[m].apply(this, arguments) };
+ })(property).wrap(method);
+
+ value.valueOf = method.valueOf.bind(method);
+ value.toString = method.toString.bind(method);
+ }
+ this.prototype[property] = value;
+ }
+
+ return this;
+ }
+};
+
+var Abstract = { };
+
Object.extend = function(destination, source) {
- for (var property in source) {
+ for (var property in source)
destination[property] = source[property];
- }
return destination;
-}
+};
Object.extend(Object, {
inspect: function(object) {
try {
- if (object === undefined) return 'undefined';
+ if (Object.isUndefined(object)) return 'undefined';
if (object === null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
+ return object.inspect ? object.inspect() : String(object);
} catch (e) {
if (e instanceof RangeError) return '...';
throw e;
}
},
+ toJSON: function(object) {
+ var type = typeof object;
+ switch (type) {
+ case 'undefined':
+ case 'function':
+ case 'unknown': return;
+ case 'boolean': return object.toString();
+ }
+
+ if (object === null) return 'null';
+ if (object.toJSON) return object.toJSON();
+ if (Object.isElement(object)) return;
+
+ var results = [];
+ for (var property in object) {
+ var value = Object.toJSON(object[property]);
+ if (!Object.isUndefined(value))
+ results.push(property.toJSON() + ': ' + value);
+ }
+
+ return '{' + results.join(', ') + '}';
+ },
+
+ toQueryString: function(object) {
+ return $H(object).toQueryString();
+ },
+
+ toHTML: function(object) {
+ return object && object.toHTML ? object.toHTML() : String.interpret(object);
+ },
+
keys: function(object) {
var keys = [];
for (var property in object)
@@ -61,41 +167,106 @@
},
clone: function(object) {
- return Object.extend({}, object);
+ return Object.extend({ }, object);
+ },
+
+ isElement: function(object) {
+ return !!(object && object.nodeType == 1);
+ },
+
+ isArray: function(object) {
+ return object != null && typeof object == "object" &&
+ 'splice' in object && 'join' in object;
+ },
+
+ isHash: function(object) {
+ return object instanceof Hash;
+ },
+
+ isFunction: function(object) {
+ return typeof object == "function";
+ },
+
+ isString: function(object) {
+ return typeof object == "string";
+ },
+
+ isNumber: function(object) {
+ return typeof object == "number";
+ },
+
+ isUndefined: function(object) {
+ return typeof object == "undefined";
}
});
-Function.prototype.bind = function() {
- var __method = this, args = $A(arguments), object = args.shift();
- return function() {
- return __method.apply(object, args.concat($A(arguments)));
- }
-}
+Object.extend(Function.prototype, {
+ argumentNames: function() {
+ var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
+ .replace(/\s+/g, '').split(',');
+ return names.length == 1 && !names[0] ? [] : names;
+ },
-Function.prototype.bindAsEventListener = function(object) {
- var __method = this, args = $A(arguments), object = args.shift();
- return function(event) {
- return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
- }
-}
+ bind: function() {
+ if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function() {
+ return __method.apply(object, args.concat($A(arguments)));
+ }
+ },
-Object.extend(Number.prototype, {
- toColorPart: function() {
- var digits = this.toString(16);
- if (this < 16) return '0' + digits;
- return digits;
+ bindAsEventListener: function() {
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function(event) {
+ return __method.apply(object, [event || window.event].concat(args));
+ }
},
- succ: function() {
- return this + 1;
+ curry: function() {
+ if (!arguments.length) return this;
+ var __method = this, args = $A(arguments);
+ return function() {
+ return __method.apply(this, args.concat($A(arguments)));
+ }
},
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
+ delay: function() {
+ var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+ return window.setTimeout(function() {
+ return __method.apply(__method, args);
+ }, timeout);
+ },
+
+ defer: function() {
+ var args = [0.01].concat($A(arguments));
+ return this.delay.apply(this, args);
+ },
+
+ wrap: function(wrapper) {
+ var __method = this;
+ return function() {
+ return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+ }
+ },
+
+ methodize: function() {
+ if (this._methodized) return this._methodized;
+ var __method = this;
+ return this._methodized = function() {
+ return __method.apply(null, [this].concat($A(arguments)));
+ };
}
});
+Date.prototype.toJSON = function() {
+ return '"' + this.getUTCFullYear() + '-' +
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+ this.getUTCDate().toPaddedString(2) + 'T' +
+ this.getUTCHours().toPaddedString(2) + ':' +
+ this.getUTCMinutes().toPaddedString(2) + ':' +
+ this.getUTCSeconds().toPaddedString(2) + 'Z"';
+};
+
var Try = {
these: function() {
var returnValue;
@@ -105,17 +276,22 @@
try {
returnValue = lambda();
break;
- } catch (e) {}
+ } catch (e) { }
}
return returnValue;
}
-}
+};
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str) {
+ return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+
/*--------------------------------------------------------------------------*/
-var PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
+var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
@@ -128,6 +304,10 @@
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
+ execute: function() {
+ this.callback(this);
+ },
+
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
@@ -138,16 +318,26 @@
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
- this.callback(this);
+ this.execute();
} finally {
this.currentlyExecuting = false;
}
}
}
-}
-String.interpret = function(value){
- return value == null ? '' : String(value);
-}
+});
+Object.extend(String, {
+ interpret: function(value) {
+ return value == null ? '' : String(value);
+ },
+ specialChar: {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '\\': '\\\\'
+ }
+});
Object.extend(String.prototype, {
gsub: function(pattern, replacement) {
@@ -168,7 +358,7 @@
sub: function(pattern, replacement, count) {
replacement = this.gsub.prepareReplacement(replacement);
- count = count === undefined ? 1 : count;
+ count = Object.isUndefined(count) ? 1 : count;
return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
@@ -178,14 +368,14 @@
scan: function(pattern, iterator) {
this.gsub(pattern, iterator);
- return this;
+ return String(this);
},
truncate: function(length, truncation) {
length = length || 30;
- truncation = truncation === undefined ? '...' : truncation;
+ truncation = Object.isUndefined(truncation) ? '...' : truncation;
return this.length > length ?
- this.slice(0, length - truncation.length) + truncation : this;
+ this.slice(0, length - truncation.length) + truncation : String(this);
},
strip: function() {
@@ -213,35 +403,34 @@
},
escapeHTML: function() {
- var div = document.createElement('div');
- var text = document.createTextNode(this);
- div.appendChild(text);
- return div.innerHTML;
+ var self = arguments.callee;
+ self.text.data = ""
+ return self.div.innerHTML;
},
unescapeHTML: function() {
- var div = document.createElement('div');
+ var div = new Element('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? (div.childNodes.length > 1 ?
- $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+ $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
div.childNodes[0].nodeValue) : '';
},
toQueryParams: function(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
- if (!match) return {};
+ if (!match) return { };
- return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
- var name = decodeURIComponent(pair[0]);
- var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+ var key = decodeURIComponent(pair.shift());
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
+ if (value != undefined) value = decodeURIComponent(value);
- if (hash[name] !== undefined) {
- if (hash[name].constructor != Array)
- hash[name] = [hash[name]];
- if (value) hash[name].push(value);
+ if (key in hash) {
+ if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+ hash[key].push(value);
}
- else hash[name] = value;
+ else hash[key] = value;
}
return hash;
});
@@ -256,6 +445,10 @@
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
},
+ times: function(count) {
+ return count < 1 ? '' : new Array(count + 1).join(this);
+ },
+
camelize: function() {
var parts = this.split('-'), len = parts.length;
if (len == 1) return parts[0];
@@ -270,7 +463,7 @@
return camelized;
},
- capitalize: function(){
+ capitalize: function() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
},
@@ -283,52 +476,130 @@
},
inspect: function(useDoubleQuotes) {
- var escapedString = this.replace(/\\/g, '\\\\');
- if (useDoubleQuotes)
- return '"' + escapedString.replace(/"/g, '\\"') + '"';
- else
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+ var character = String.specialChar[match[0]];
+ return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+ });
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ },
+
+ toJSON: function() {
+ return this.inspect(true);
+ },
+
+ unfilterJSON: function(filter) {
+ return this.sub(filter || Prototype.JSONFilter, '#{1}');
+ },
+
+ isJSON: function() {
+ var str = this;
+ if (str.blank()) return false;
+ str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
+ return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
+ },
+
+ evalJSON: function(sanitize) {
+ var json = this.unfilterJSON();
+ try {
+ if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+ } catch (e) { }
+ throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+ },
+
+ include: function(pattern) {
+ return this.indexOf(pattern) > -1;
+ },
+
+ startsWith: function(pattern) {
+ return this.indexOf(pattern) === 0;
+ },
+
+ endsWith: function(pattern) {
+ var d = this.length - pattern.length;
+ return d >= 0 && this.lastIndexOf(pattern) === d;
+ },
+
+ empty: function() {
+ return this == '';
+ },
+
+ blank: function() {
+ return /^\s*$/.test(this);
+ },
+
+ interpolate: function(object, pattern) {
+ return new Template(this, pattern).evaluate(object);
}
});
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+ escapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ },
+ unescapeHTML: function() {
+ return this.stripTags().replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ }
+});
+
String.prototype.gsub.prepareReplacement = function(replacement) {
- if (typeof replacement == 'function') return replacement;
+ if (Object.isFunction(replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return template.evaluate(match) };
-}
+};
String.prototype.parseQuery = String.prototype.toQueryParams;
-var Template = Class.create();
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-Template.prototype = {
+Object.extend(String.prototype.escapeHTML, {
+ div: document.createElement('div'),
+ text: document.createTextNode('')
+});
+
+String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
+
+var Template = Class.create({
initialize: function(template, pattern) {
this.template = template.toString();
- this.pattern = pattern || Template.Pattern;
+ this.pattern = pattern || Template.Pattern;
},
evaluate: function(object) {
+ if (Object.isFunction(object.toTemplateReplacements))
+ object = object.toTemplateReplacements();
+
return this.template.gsub(this.pattern, function(match) {
- var before = match[1];
+ if (object == null) return '';
+
+ var before = match[1] || '';
if (before == '\\') return match[2];
- return before + String.interpret(object[match[3]]);
+
+ var ctx = object, expr = match[3];
+ var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+ match = pattern.exec(expr);
+ if (match == null) return before;
+
+ while (match != null) {
+ var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+ ctx = ctx[comp];
+ if (null == ctx || '' == match[3]) break;
+ expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+ match = pattern.exec(expr);
+ }
+
+ return before + String.interpret(ctx);
});
}
-}
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-var $break = new Object();
-var $continue = new Object();
+var $break = { };
var Enumerable = {
- each: function(iterator) {
+ each: function(iterator, context) {
var index = 0;
try {
this._each(function(value) {
- try {
- iterator(value, index++);
- } catch (e) {
- if (e != $continue) throw e;
- }
+ iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
@@ -336,43 +607,47 @@
return this;
},
- eachSlice: function(number, iterator) {
+ eachSlice: function(number, iterator, context) {
var index = -number, slices = [], array = this.toArray();
+ if (number < 1) return array;
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
- return slices.map(iterator);
+ return slices.collect(iterator, context);
},
- all: function(iterator) {
+ all: function(iterator, context) {
+ iterator = iterator || Prototype.K;
var result = true;
this.each(function(value, index) {
- result = result && !!(iterator || Prototype.K)(value, index);
+ result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
return result;
},
- any: function(iterator) {
+ any: function(iterator, context) {
+ iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
- if (result = !!(iterator || Prototype.K)(value, index))
+ if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
},
- collect: function(iterator) {
+ collect: function(iterator, context) {
+ iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
- results.push((iterator || Prototype.K)(value, index));
+ results.push(iterator.call(context, value, index));
});
return results;
},
- detect: function(iterator) {
+ detect: function(iterator, context) {
var result;
this.each(function(value, index) {
- if (iterator(value, index)) {
+ if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
@@ -380,26 +655,33 @@
return result;
},
- findAll: function(iterator) {
+ findAll: function(iterator, context) {
var results = [];
this.each(function(value, index) {
- if (iterator(value, index))
+ if (iterator.call(context, value, index))
results.push(value);
});
return results;
},
- grep: function(pattern, iterator) {
+ grep: function(filter, iterator, context) {
+ iterator = iterator || Prototype.K;
var results = [];
+
+ if (Object.isString(filter))
+ filter = new RegExp(filter);
+
this.each(function(value, index) {
- var stringValue = value.toString();
- if (stringValue.match(pattern))
- results.push((iterator || Prototype.K)(value, index));
- })
+ if (filter.match(value))
+ results.push(iterator.call(context, value, index));
+ });
return results;
},
include: function(object) {
+ if (Object.isFunction(this.indexOf))
+ if (this.indexOf(object) != -1) return true;
+
var found = false;
this.each(function(value) {
if (value == object) {
@@ -411,16 +693,16 @@
},
inGroupsOf: function(number, fillWith) {
- fillWith = fillWith === undefined ? null : fillWith;
+ fillWith = Object.isUndefined(fillWith) ? null : fillWith;
return this.eachSlice(number, function(slice) {
while(slice.length < number) slice.push(fillWith);
return slice;
});
},
- inject: function(memo, iterator) {
+ inject: function(memo, iterator, context) {
this.each(function(value, index) {
- memo = iterator(memo, value, index);
+ memo = iterator.call(context, memo, value, index);
});
return memo;
},
@@ -432,30 +714,33 @@
});
},
- max: function(iterator) {
+ max: function(iterator, context) {
+ iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (result == undefined || value >= result)
+ value = iterator.call(context, value, index);
+ if (result == null || value >= result)
result = value;
});
return result;
},
- min: function(iterator) {
+ min: function(iterator, context) {
+ iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (result == undefined || value < result)
+ value = iterator.call(context, value, index);
+ if (result == null || value < result)
result = value;
});
return result;
},
- partition: function(iterator) {
+ partition: function(iterator, context) {
+ iterator = iterator || Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
- ((iterator || Prototype.K)(value, index) ?
+ (iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
@@ -463,24 +748,27 @@
pluck: function(property) {
var results = [];
- this.each(function(value, index) {
+ this.each(function(value) {
results.push(value[property]);
});
return results;
},
- reject: function(iterator) {
+ reject: function(iterator, context) {
var results = [];
this.each(function(value, index) {
- if (!iterator(value, index))
+ if (!iterator.call(context, value, index))
results.push(value);
});
return results;
},
- sortBy: function(iterator) {
+ sortBy: function(iterator, context) {
return this.map(function(value, index) {
- return {value: value, criteria: iterator(value, index)};
+ return {
+ value: value,
+ criteria: iterator.call(context, value, index)
+ };
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
@@ -493,7 +781,7 @@
zip: function() {
var iterator = Prototype.K, args = $A(arguments);
- if (typeof args.last() == 'function')
+ if (Object.isFunction(args.last()))
iterator = args.pop();
var collections = [this].concat(args).map($A);
@@ -509,31 +797,46 @@
inspect: function() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
-}
+};
Object.extend(Enumerable, {
map: Enumerable.collect,
find: Enumerable.detect,
select: Enumerable.findAll,
+ filter: Enumerable.findAll,
member: Enumerable.include,
- entries: Enumerable.toArray
+ entries: Enumerable.toArray,
+ every: Enumerable.all,
+ some: Enumerable.any
});
-var $A = Array.from = function(iterable) {
+function $A(iterable) {
if (!iterable) return [];
- if (iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
+ if (iterable.toArray) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
+}
+
+if (Prototype.Browser.WebKit) {
+ $A = function(iterable) {
+ if (!iterable) return [];
+ // In Safari, only use the `toArray` method if it's not a NodeList.
+ // A NodeList is a function, has an function `item` property, and a numeric
+ // `length` property. Adapted from Google Doctype.
+ if (!(typeof iterable === 'function' && typeof iterable.length ===
+ 'number' && typeof iterable.item === 'function') && iterable.toArray)
+ return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
+ while (length--) results[length] = iterable[length];
return results;
- }
+ };
}
+Array.from = $A;
+
Object.extend(Array.prototype, Enumerable);
-if (!Array.prototype._reverse)
- Array.prototype._reverse = Array.prototype.reverse;
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
Object.extend(Array.prototype, {
_each: function(iterator) {
@@ -562,7 +865,7 @@
flatten: function() {
return this.inject([], function(array, value) {
- return array.concat(value && value.constructor == Array ?
+ return array.concat(Object.isArray(value) ?
value.flatten() : [value]);
});
},
@@ -574,12 +877,6 @@
});
},
- indexOf: function(object) {
- for (var i = 0, length = this.length; i < length; i++)
- if (this[i] == object) return i;
- return -1;
- },
-
reverse: function(inline) {
return (inline !== false ? this : this.toArray())._reverse();
},
@@ -588,12 +885,20 @@
return this.length > 1 ? this : this[0];
},
- uniq: function() {
- return this.inject([], function(array, value) {
- return array.include(value) ? array : array.concat([value]);
+ uniq: function(sorted) {
+ return this.inject([], function(array, value, index) {
+ if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+ array.push(value);
+ return array;
});
},
+ intersect: function(array) {
+ return this.uniq().findAll(function(item) {
+ return array.detect(function(value) { return item === value });
+ });
+ },
+
clone: function() {
return [].concat(this);
},
@@ -604,125 +909,189 @@
inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
+ },
+
+ toJSON: function() {
+ var results = [];
+ this.each(function(object) {
+ var value = Object.toJSON(object);
+ if (!Object.isUndefined(value)) results.push(value);
+ });
+ return '[' + results.join(', ') + ']';
}
});
+// use native browser JS 1.6 implementation if available
+if (Object.isFunction(Array.prototype.forEach))
+ Array.prototype._each = Array.prototype.forEach;
+
+if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
+ i || (i = 0);
+ var length = this.length;
+ if (i < 0) i = length + i;
+ for (; i < length; i++)
+ if (this[i] === item) return i;
+ return -1;
+};
+
+if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
+ i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+ var n = this.slice(0, i).reverse().indexOf(item);
+ return (n < 0) ? n : i - n - 1;
+};
+
Array.prototype.toArray = Array.prototype.clone;
-function $w(string){
+function $w(string) {
+ if (!Object.isString(string)) return [];
string = string.strip();
return string ? string.split(/\s+/) : [];
}
-if(window.opera){
- Array.prototype.concat = function(){
+if (Prototype.Browser.Opera){
+ Array.prototype.concat = function() {
var array = [];
- for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
- for(var i = 0, length = arguments.length; i < length; i++) {
- if(arguments[i].constructor == Array) {
- for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+ for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ if (Object.isArray(arguments[i])) {
+ for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
array.push(arguments[i][j]);
} else {
array.push(arguments[i]);
}
}
return array;
- }
+ };
}
-var Hash = function(obj) {
- Object.extend(this, obj || {});
-};
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ return this.toPaddedString(2, 16);
+ },
-Object.extend(Hash, {
- toQueryString: function(obj) {
- var parts = [];
+ succ: function() {
+ return this + 1;
+ },
- this.prototype._each.call(obj, function(pair) {
- if (!pair.key) return;
+ times: function(iterator, context) {
+ $R(0, this, true).each(iterator, context);
+ return this;
+ },
- if (pair.value && pair.value.constructor == Array) {
- var values = pair.value.compact();
- if (values.length < 2) pair.value = values.reduce();
- else {
- key = encodeURIComponent(pair.key);
- values.each(function(value) {
- value = value != undefined ? encodeURIComponent(value) : '';
- parts.push(key + '=' + encodeURIComponent(value));
- });
- return;
- }
- }
- if (pair.value == undefined) pair[1] = '';
- parts.push(pair.map(encodeURIComponent).join('='));
- });
+ toPaddedString: function(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ },
- return parts.join('&');
+ toJSON: function() {
+ return isFinite(this) ? this.toString() : 'null';
}
});
-Object.extend(Hash.prototype, Enumerable);
-Object.extend(Hash.prototype, {
- _each: function(iterator) {
- for (var key in this) {
- var value = this[key];
- if (value && value == Hash.prototype[key]) continue;
+$w('abs round ceil floor').each(function(method){
+ Number.prototype[method] = Math[method].methodize();
+});
+function $H(object) {
+ return new Hash(object);
+};
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
+var Hash = Class.create(Enumerable, (function() {
- keys: function() {
- return this.pluck('key');
- },
+ function toQueryPair(key, value) {
+ if (Object.isUndefined(value)) return key;
+ return key + '=' + encodeURIComponent(String.interpret(value));
+ }
- values: function() {
- return this.pluck('value');
- },
+ return {
+ initialize: function(object) {
+ this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+ },
- merge: function(hash) {
- return $H(hash).inject(this, function(mergedHash, pair) {
- mergedHash[pair.key] = pair.value;
- return mergedHash;
- });
- },
-
- remove: function() {
- var result;
- for(var i = 0, length = arguments.length; i < length; i++) {
- var value = this[arguments[i]];
- if (value !== undefined){
- if (result === undefined) result = value;
- else {
- if (result.constructor != Array) result = [result];
- result.push(value)
- }
+ _each: function(iterator) {
+ for (var key in this._object) {
+ var value = this._object[key], pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
}
- delete this[arguments[i]];
- }
- return result;
- },
+ },
- toQueryString: function() {
- return Hash.toQueryString(this);
- },
+ set: function(key, value) {
+ return this._object[key] = value;
+ },
- inspect: function() {
- return '#<Hash:{' + this.map(function(pair) {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
+ get: function(key) {
+ // simulating poorly supported hasOwnProperty
+ if (this._object[key] !== Object.prototype[key])
+ return this._object[key];
+ },
+
+ unset: function(key) {
+ var value = this._object[key];
+ delete this._object[key];
+ return value;
+ },
+
+ toObject: function() {
+ return Object.clone(this._object);
+ },
+
+ keys: function() {
+ return this.pluck('key');
+ },
+
+ values: function() {
+ return this.pluck('value');
+ },
+
+ index: function(value) {
+ var match = this.detect(function(pair) {
+ return pair.value === value;
+ });
+ return match && match.key;
+ },
+
+ merge: function(object) {
+ return this.clone().update(object);
+ },
+
+ update: function(object) {
+ return new Hash(object).inject(this, function(result, pair) {
+ result.set(pair.key, pair.value);
+ return result;
+ });
+ },
+
+ toQueryString: function() {
+ return this.inject([], function(results, pair) {
+ var key = encodeURIComponent(pair.key), values = pair.value;
+
+ if (values && typeof values == 'object') {
+ if (Object.isArray(values))
+ return results.concat(values.map(toQueryPair.curry(key)));
+ } else results.push(toQueryPair(key, values));
+ return results;
+ }).join('&');
+ },
+
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ },
+
+ toJSON: function() {
+ return Object.toJSON(this.toObject());
+ },
+
+ clone: function() {
+ return new Hash(this);
+ }
}
-});
+})());
-function $H(object) {
- if (object && object.constructor == Hash) return object;
- return new Hash(object);
-};
-ObjectRange = Class.create();
-Object.extend(ObjectRange.prototype, Enumerable);
-Object.extend(ObjectRange.prototype, {
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
+Hash.from = $H;
+var ObjectRange = Class.create(Enumerable, {
initialize: function(start, end, exclusive) {
this.start = start;
this.end = end;
@@ -748,7 +1117,7 @@
var $R = function(start, end, exclusive) {
return new ObjectRange(start, end, exclusive);
-}
+};
var Ajax = {
getTransport: function() {
@@ -760,7 +1129,7 @@
},
activeRequestCount: 0
-}
+};
Ajax.Responders = {
responders: [],
@@ -780,10 +1149,10 @@
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
- if (typeof responder[callback] == 'function') {
+ if (Object.isFunction(responder[callback])) {
try {
responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {}
+ } catch (e) { }
}
});
}
@@ -792,49 +1161,45 @@
Object.extend(Ajax.Responders, Enumerable);
Ajax.Responders.register({
- onCreate: function() {
- Ajax.activeRequestCount++;
- },
- onComplete: function() {
- Ajax.activeRequestCount--;
- }
+ onCreate: function() { Ajax.activeRequestCount++ },
+ onComplete: function() { Ajax.activeRequestCount-- }
});
-Ajax.Base = function() {};
-Ajax.Base.prototype = {
- setOptions: function(options) {
+Ajax.Base = Class.create({
+ initialize: function(options) {
this.options = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
encoding: 'UTF-8',
- parameters: ''
- }
- Object.extend(this.options, options || {});
+ parameters: '',
+ evalJSON: true,
+ evalJS: true
+ };
+ Object.extend(this.options, options || { });
this.options.method = this.options.method.toLowerCase();
- if (typeof this.options.parameters == 'string')
+
+ if (Object.isString(this.options.parameters))
this.options.parameters = this.options.parameters.toQueryParams();
+ else if (Object.isHash(this.options.parameters))
+ this.options.parameters = this.options.parameters.toObject();
}
-}
+});
-Ajax.Request = Class.create();
-Ajax.Request.Events =
- ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+Ajax.Request = Class.create(Ajax.Base, {
_complete: false,
- initialize: function(url, options) {
+ initialize: function($super, url, options) {
+ $super(options);
this.transport = Ajax.getTransport();
- this.setOptions(options);
this.request(url);
},
request: function(url) {
this.url = ""
this.method = this.options.method;
- var params = this.options.parameters;
+ var params = Object.clone(this.options.parameters);
if (!['get', 'post'].include(this.method)) {
// simulate other verbs over post
@@ -842,29 +1207,32 @@
this.method = 'post';
}
- params = Hash.toQueryString(params);
- if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+ this.parameters = params;
- // when GET, append parameters to URL
- if (this.method == 'get' && params)
- this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+ if (params = Object.toQueryString(params)) {
+ // when GET, append parameters to URL
+ if (this.method == 'get')
+ this.url += (this.url.include('?') ? '&' : '?') + params;
+ else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ params += '&_=';
+ }
try {
- Ajax.Responders.dispatch('onCreate', this, this.transport);
+ var response = new Ajax.Response(this);
+ if (this.options.onCreate) this.options.onCreate(response);
+ Ajax.Responders.dispatch('onCreate', this, response);
this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
- if (this.options.asynchronous)
- setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+ if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
this.transport.
this.setRequestHeaders();
- var body = this.method == 'post' ? (this.options.postBody || params) : null;
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+ this.transport.send(this.body);
- this.transport.send(body);
-
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
@@ -905,7 +1273,7 @@
if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
- if (typeof extras.push == 'function')
+ if (Object.isFunction(extras.push))
for (var i = 0, length = extras.length; i < length; i += 2)
headers[extras[i]] = extras[i+1];
else
@@ -917,32 +1285,39 @@
},
success: function() {
- return !this.transport.status
- || (this.transport.status >= 200 && this.transport.status < 300);
+ var status = this.getStatus();
+ return !status || (status >= 200 && status < 300);
},
+ getStatus: function() {
+ try {
+ return this.transport.status || 0;
+ } catch (e) { return 0 }
+ },
+
respondToReadyState: function(readyState) {
- var state = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
+ var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
if (state == 'Complete') {
try {
this._complete = true;
- (this.options['on' + this.transport.status]
+ (this.options['on' + response.status]
|| this.options['on' + (this.success() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
+ || Prototype.emptyFunction)(response, response.headerJSON);
} catch (e) {
this.dispatchException(e);
}
- if ((this.getHeader('Content-type') || 'text/_javascript_').strip().
- match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
- this.evalResponse();
+ var contentType = response.getHeader('Content-type');
+ if (this.options.evalJS == 'force'
+ || (this.options.evalJS && this.isSameOrigin() && contentType
+ && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+ this.evalResponse();
}
try {
- (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + state, this, transport, json);
+ (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+ Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
} catch (e) {
this.dispatchException(e);
}
@@ -953,22 +1328,24 @@
}
},
- getHeader: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) { return null }
+ isSameOrigin: function() {
+ var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+ return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+ protocol: location.protocol,
+ domain: document.domain,
+ port: location.port ? ':' + location.port : ''
+ }));
},
- evalJSON: function() {
+ getHeader: function(name) {
try {
- var json = this.getHeader('X-JSON');
- return json ? eval('(' + json + ')') : null;
+ return this.transport.getResponseHeader(name) || null;
} catch (e) { return null }
},
evalResponse: function() {
try {
- return eval(this.transport.responseText);
+ return eval((this.transport.responseText || '').unfilterJSON());
} catch (e) {
this.dispatchException(e);
}
@@ -980,57 +1357,128 @@
}
});
-Ajax.Updater = Class.create();
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
- initialize: function(container, url, options) {
+Ajax.Response = Class.create({
+ initialize: function(request){
+ this.request = request;
+ var transport = this.transport = request.transport,
+ readyState = this.readyState = transport.readyState;
+
+ if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+ this.status = this.getStatus();
+ this.statusText = this.getStatusText();
+ this.responseText = String.interpret(transport.responseText);
+ this.headerJSON = this._getHeaderJSON();
+ }
+
+ if(readyState == 4) {
+ var xml = transport.responseXML;
+ this.responseXML = Object.isUndefined(xml) ? null : xml;
+ this.responseJSON = this._getResponseJSON();
+ }
+ },
+
+ status: 0,
+ statusText: '',
+
+ getStatus: Ajax.Request.prototype.getStatus,
+
+ getStatusText: function() {
+ try {
+ return this.transport.statusText || '';
+ } catch (e) { return '' }
+ },
+
+ getHeader: Ajax.Request.prototype.getHeader,
+
+ getAllHeaders: function() {
+ try {
+ return this.getAllResponseHeaders();
+ } catch (e) { return null }
+ },
+
+ getResponseHeader: function(name) {
+ return this.transport.getResponseHeader(name);
+ },
+
+ getAllResponseHeaders: function() {
+ return this.transport.getAllResponseHeaders();
+ },
+
+ _getHeaderJSON: function() {
+ var json = this.getHeader('X-JSON');
+ if (!json) return null;
+ json = decodeURIComponent(escape(json));
+ try {
+ return json.evalJSON(this.request.options.sanitizeJSON ||
+ !this.request.isSameOrigin());
+ } catch (e) {
+ this.request.dispatchException(e);
+ }
+ },
+
+ _getResponseJSON: function() {
+ var options = this.request.options;
+ if (!options.evalJSON || (options.evalJSON != 'force' &&
+ !(this.getHeader('Content-type') || '').include('application/json')) ||
+ this.responseText.blank())
+ return null;
+ try {
+ return this.responseText.evalJSON(options.sanitizeJSON ||
+ !this.request.isSameOrigin());
+ } catch (e) {
+ this.request.dispatchException(e);
+ }
+ }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+ initialize: function($super, container, url, options) {
this.container = {
success: (container.success || container),
failure: (container.failure || (container.success ? null : container))
- }
+ };
- this.transport = Ajax.getTransport();
- this.setOptions(options);
-
- var || Prototype.emptyFunction;
- this.options. param) {
- this.updateContent();
- onComplete(transport, param);
+ options = Object.clone(options);
+ var
+ options. json) {
+ this.updateContent(response.responseText);
+ if (Object.isFunction(onComplete)) onComplete(response, json);
}).bind(this);
- this.request(url);
+ $super(url, options);
},
- updateContent: function() {
- var receiver = this.container[this.success() ? 'success' : 'failure'];
- var response = this.transport.responseText;
+ updateContent: function(responseText) {
+ var receiver = this.container[this.success() ? 'success' : 'failure'],
+ options = this.options;
- if (!this.options.evalScripts) response = response.stripScripts();
+ if (!options.evalScripts) responseText = responseText.stripScripts();
if (receiver = $(receiver)) {
- if (this.options.insertion)
- new this.options.insertion(receiver, response);
- else
- receiver.update(response);
+ if (options.insertion) {
+ if (Object.isString(options.insertion)) {
+ var insertion = { }; insertion[options.insertion] = responseText;
+ receiver.insert(insertion);
+ }
+ else options.insertion(receiver, responseText);
+ }
+ else receiver.update(responseText);
}
-
- if (this.success()) {
- if (this.onComplete)
- setTimeout(this.onComplete.bind(this), 10);
- }
}
});
-Ajax.PeriodicalUpdater = Class.create();
-Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
- initialize: function(container, url, options) {
- this.setOptions(options);
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+ initialize: function($super, container, url, options) {
+ $super(options);
this.
this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);
- this.updater = {};
+ this.updater = { };
this.container = container;
this.url = ""
@@ -1048,15 +1496,14 @@
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
- updateComplete: function(request) {
+ updateComplete: function(response) {
if (this.options.decay) {
- this.decay = (request.responseText == this.lastText ?
+ this.decay = (response.responseText == this.lastText ?
this.decay * this.options.decay : 1);
- this.lastText = request.responseText;
+ this.lastText = response.responseText;
}
- this.timer = setTimeout(this.onTimerEvent.bind(this),
- this.decay * this.frequency * 1000);
+ this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {
@@ -1069,7 +1516,7 @@
elements.push($(arguments[i]));
return elements;
}
- if (typeof element == 'string')
+ if (Object.isString(element))
element = document.getElementById(element);
return Element.extend(element);
}
@@ -1080,64 +1527,53 @@
var query = document.evaluate(_expression_, $(parentElement) || document,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0, length = query.snapshotLength; i < length; i++)
- results.push(query.snapshotItem(i));
+ results.push(Element.extend(query.snapshotItem(i)));
return results;
};
}
-document.getElementsByClassName = function(className, parentElement) {
- if (Prototype.BrowserFeatures.XPath) {
- var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
- return document._getElementsByXPath(q, parentElement);
- } else {
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- var elements = [], child;
- for (var i = 0, length = children.length; i < length; i++) {
- child = children[i];
- if (Element.hasClassName(child, className))
- elements.push(Element.extend(child));
- }
- return elements;
- }
-};
-
/*--------------------------------------------------------------------------*/
-if (!window.Element)
- var Element = new Object();
+if (!window.Node) var Node = { };
-Element.extend = function(element) {
- if (!element || _nativeExtensions || element.nodeType == 3) return element;
+if (!Node.ELEMENT_NODE) {
+ // DOM level 2 ECMAScript Language Binding
+ Object.extend(Node, {
+ ELEMENT_NODE: 1,
+ ATTRIBUTE_NODE: 2,
+ TEXT_NODE: 3,
+ CDATA_SECTION_NODE: 4,
+ ENTITY_REFERENCE_NODE: 5,
+ ENTITY_NODE: 6,
+ PROCESSING_INSTRUCTION_NODE: 7,
+ COMMENT_NODE: 8,
+ DOCUMENT_NODE: 9,
+ DOCUMENT_TYPE_NODE: 10,
+ DOCUMENT_FRAGMENT_NODE: 11,
+ NOTATION_NODE: 12
+ });
+}
- if (!element._extended && element.tagName && element != window) {
- var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
-
- if (element.tagName == 'FORM')
- Object.extend(methods, Form.Methods);
- if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
- Object.extend(methods, Form.Element.Methods);
-
- Object.extend(methods, Element.Methods.Simulated);
-
- for (var property in methods) {
- var value = methods[property];
- if (typeof value == 'function' && !(property in element))
- element[property] = cache.findOrStore(value);
+(function() {
+ var element = this.Element;
+ this.Element = function(tagName, attributes) {
+ attributes = attributes || { };
+ tagName = tagName.toLowerCase();
+ var cache = Element.cache;
+ if (Prototype.Browser.IE && attributes.name) {
+ tagName = '<' + tagName + ' name="' + attributes.name + '">';
+ delete attributes.name;
+ return Element.writeAttribute(document.createElement(tagName), attributes);
}
- }
+ if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+ return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+ };
+ Object.extend(this.Element, element || { });
+ if (element) this.Element.prototype = element.prototype;
+}).call(window);
- element._extended = true;
- return element;
-};
+Element.cache = { };
-Element.extend.cache = {
- findOrStore: function(value) {
- return this[value] = this[value] || function() {
- return value.apply(null, [this].concat($A(arguments)));
- }
- }
-};
-
Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
@@ -1150,12 +1586,14 @@
},
hide: function(element) {
- $(element).style.display = 'none';
+ element = $(element);
+ element.style.display = 'none';
return element;
},
show: function(element) {
- $(element).style.display = '';
+ element = $(element);
+ element.style.display = '';
return element;
},
@@ -1165,28 +1603,78 @@
return element;
},
- update: function(element, html) {
- html = typeof html == 'undefined' ? '' : html.toString();
- $(element).innerHTML = html.stripScripts();
- setTimeout(function() {html.evalScripts()}, 10);
+ update: function(element, content) {
+ element = $(element);
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) return element.update().insert(content);
+ content = Object.toHTML(content);
+ element.innerHTML = content.stripScripts();
+ content.evalScripts.bind(content).defer();
return element;
},
- replace: function(element, html) {
+ replace: function(element, content) {
element = $(element);
- html = typeof html == 'undefined' ? '' : html.toString();
- if (element.outerHTML) {
- element.outerHTML = html.stripScripts();
- } else {
+ if (content && content.toElement) content = content.toElement();
+ else if (!Object.isElement(content)) {
+ content = Object.toHTML(content);
var range = element.ownerDocument.createRange();
- range.selectNodeContents(element);
- element.parentNode.replaceChild(
- range.createContextualFragment(html.stripScripts()), element);
+ range.selectNode(element);
+ content.evalScripts.bind(content).defer();
+ content = range.createContextualFragment(content.stripScripts());
}
- setTimeout(function() {html.evalScripts()}, 10);
+ element.parentNode.replaceChild(content, element);
return element;
},
+ insert: function(element, insertions) {
+ element = $(element);
+
+ if (Object.isString(insertions) || Object.isNumber(insertions) ||
+ Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+ insertions = {bottom:insertions};
+
+ var content, insert, tagName, childNodes;
+
+ for (var position in insertions) {
+ content = insertions[position];
+ position = position.toLowerCase();
+ insert = Element._insertionTranslations[position];
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) {
+ insert(element, content);
+ continue;
+ }
+
+ content = Object.toHTML(content);
+
+ tagName = ((position == 'before' || position == 'after')
+ ? element.parentNode : element).tagName.toUpperCase();
+
+ childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+ if (position == 'top' || position == 'after') childNodes.reverse();
+ childNodes.each(insert.curry(element));
+
+ content.evalScripts.bind(content).defer();
+ }
+
+ return element;
+ },
+
+ wrap: function(element, wrapper, attributes) {
+ element = $(element);
+ if (Object.isElement(wrapper))
+ $(wrapper).writeAttribute(attributes || { });
+ else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+ else wrapper = new Element('div', wrapper);
+ if (element.parentNode)
+ element.parentNode.replaceChild(wrapper, element);
+ wrapper.appendChild(element);
+ return wrapper;
+ },
+
inspect: function(element) {
element = $(element);
var result = '<' + element.tagName.toLowerCase();
@@ -1212,9 +1700,15 @@
},
descendants: function(element) {
- return $A($(element).getElementsByTagName('*'));
+ return $(element).select("*");
},
+ firstDescendant: function(element) {
+ element = $(element).firstChild;
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ return $(element);
+ },
+
immediateDescendants: function(element) {
if (!(element = $(element).firstChild)) return [];
while (element && element.nodeType != 1) element = element.nextSibling;
@@ -1236,48 +1730,95 @@
},
match: function(element, selector) {
- if (typeof selector == 'string')
+ if (Object.isString(selector))
selector = new Selector(selector);
return selector.match($(element));
},
up: function(element, _expression_, index) {
- return Selector.findElement($(element).ancestors(), _expression_, index);
+ element = $(element);
+ if (arguments.length == 1) return $(element.parentNode);
+ var ancestors = element.ancestors();
+ return Object.isNumber(_expression_) ? ancestors[_expression_] :
+ Selector.findElement(ancestors, _expression_, index);
},
down: function(element, _expression_, index) {
- return Selector.findElement($(element).descendants(), _expression_, index);
+ element = $(element);
+ if (arguments.length == 1) return element.firstDescendant();
+ return Object.isNumber(_expression_) ? element.descendants()[_expression_] :
+ Element.select(element, _expression_)[index || 0];
},
previous: function(element, _expression_, index) {
- return Selector.findElement($(element).previousSiblings(), _expression_, index);
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+ var previousSiblings = element.previousSiblings();
+ return Object.isNumber(_expression_) ? previousSiblings[_expression_] :
+ Selector.findElement(previousSiblings, _expression_, index);
},
next: function(element, _expression_, index) {
- return Selector.findElement($(element).nextSiblings(), _expression_, index);
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+ var nextSiblings = element.nextSiblings();
+ return Object.isNumber(_expression_) ? nextSiblings[_expression_] :
+ Selector.findElement(nextSiblings, _expression_, index);
},
- getElementsBySelector: function() {
+ select: function() {
var args = $A(arguments), element = $(args.shift());
return Selector.findChildElements(element, args);
},
- getElementsByClassName: function(element, className) {
- return document.getElementsByClassName(className, element);
+ adjacent: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element.parentNode, args).without(element);
},
+ identify: function(element) {
+ element = $(element);
+ var id = element.readAttribute('id'), self = arguments.callee;
+ if (id) return id;
+ do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+ element.writeAttribute('id', id);
+ return id;
+ },
+
readAttribute: function(element, name) {
element = $(element);
- if (document.all && !window.opera) {
- var t = Element._attributeTranslations;
+ if (Prototype.Browser.IE) {
+ var t = Element._attributeTranslations.read;
if (t.values[name]) return t.values[name](element, name);
- if (t.names[name]) name = t.names[name];
- var attribute = element.attributes[name];
- if(attribute) return attribute.nodeValue;
+ if (t.names[name]) name = t.names[name];
+ if (name.include(':')) {
+ return (!element.attributes || !element.attributes[name]) ? null :
+ element.attributes[name].value;
+ }
}
return element.getAttribute(name);
},
+ writeAttribute: function(element, name, value) {
+ element = $(element);
+ var attributes = { }, t = Element._attributeTranslations.write;
+
+ if (typeof name == 'object') attributes = name;
+ else attributes[name] = Object.isUndefined(value) ? true : value;
+
+ for (var attr in attributes) {
+ name = t.names[attr] || attr;
+ value = attributes[attr];
+ if (t.values[attr]) name = t.values[attr](element, value);
+ if (value === false || value === null)
+ element.removeAttribute(name);
+ else if (value === true)
+ element.setAttribute(name, name);
+ else element.setAttribute(name, value);
+ }
+ return element;
+ },
+
getHeight: function(element) {
return $(element).getDimensions().height;
},
@@ -1293,41 +1834,30 @@
hasClassName: function(element, className) {
if (!(element = $(element))) return;
var elementClassName = element.className;
- if (elementClassName.length == 0) return false;
- if (elementClassName == className ||
- elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- return true;
- return false;
+ return (elementClassName.length > 0 && (elementClassName == className ||
+ new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
},
addClassName: function(element, className) {
if (!(element = $(element))) return;
- Element.classNames(element).add(className);
+ if (!element.hasClassName(className))
+ element.className += (element.className ? ' ' : '') + className;
return element;
},
removeClassName: function(element, className) {
if (!(element = $(element))) return;
- Element.classNames(element).remove(className);
+ element.className = element.className.replace(
+ new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
return element;
},
toggleClassName: function(element, className) {
if (!(element = $(element))) return;
- Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
- return element;
+ return element[element.hasClassName(className) ?
+ 'removeClassName' : 'addClassName'](className);
},
- observe: function() {
- Event.observe.apply(Event, arguments);
- return $A(arguments).first();
- },
-
- stopObserving: function() {
- Event.stopObserving.apply(Event, arguments);
- return $A(arguments).first();
- },
-
// removes whitespace-only text node children
cleanWhitespace: function(element) {
element = $(element);
@@ -1342,80 +1872,75 @@
},
empty: function(element) {
- return $(element).innerHTML.match(/^\s*$/);
+ return $(element).innerHTML.blank();
},
descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
+
+ if (element.compareDocumentPosition)
+ return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+ if (ancestor.contains)
+ return ancestor.contains(element) && ancestor !== element;
+
while (element = element.parentNode)
if (element == ancestor) return true;
+
return false;
},
scrollTo: function(element) {
element = $(element);
- var pos = Position.cumulativeOffset(element);
+ var pos = element.cumulativeOffset();
window.scrollTo(pos[0], pos[1]);
return element;
},
getStyle: function(element, style) {
element = $(element);
- if (['float','cssFloat'].include(style))
- style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
- style = style.camelize();
+ style = style == 'float' ? 'cssFloat' : style.camelize();
var value = element.style[style];
- if (!value) {
- if (document.defaultView && document.defaultView.getComputedStyle) {
- var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css[style] : null;
- } else if (element.currentStyle) {
- value = element.currentStyle[style];
- }
+ if (!value || value == 'auto') {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css[style] : null;
}
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+ return value == 'auto' ? null : value;
+ },
- if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
- value = element['offset'+style.capitalize()] + 'px';
+ getOpacity: function(element) {
+ return $(element).getStyle('opacity');
+ },
- if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
- if (Element.getStyle(element, 'position') == 'static') value = 'auto';
- if(style == 'opacity') {
- if(value) return parseFloat(value);
- if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
- if(value[1]) return parseFloat(value[1]) / 100;
- return 1.0;
+ setStyle: function(element, styles) {
+ element = $(element);
+ var elementStyle = element.style, match;
+ if (Object.isString(styles)) {
+ element.style.cssText += ';' + styles;
+ return styles.include('opacity') ?
+ element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
}
- return value == 'auto' ? null : value;
+ for (var property in styles)
+ if (property == 'opacity') element.setOpacity(styles[property]);
+ else
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
+ (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+ property] = styles[property];
+
+ return element;
},
- setStyle: function(element, style) {
+ setOpacity: function(element, value) {
element = $(element);
- for (var name in style) {
- var value = style[name];
- if(name == 'opacity') {
- if (value == 1) {
- value = (/Gecko/.test(navigator.userAgent) &&
- !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
- } else if(value == '') {
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
- } else {
- if(value < 0.00001) value = 0;
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')';
- }
- } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
- element.style[name.camelize()] = value;
- }
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
return element;
},
getDimensions: function(element) {
element = $(element);
- var display = $(element).getStyle('display');
+ var display = element.getStyle('display');
if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
@@ -1444,7 +1969,7 @@
element.style.position = 'relative';
// Opera returns the offset relative to the positioning context, when an
// element is position relative but top and left have not been defined
- if (window.opera) {
+ if (Prototype.Browser.Opera) {
element.style.top = 0;
element.style.left = 0;
}
@@ -1468,8 +1993,8 @@
makeClipping: function(element) {
element = $(element);
if (element._overflow) return element;
- element._overflow = element.style.overflow || 'auto';
- if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+ element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+ if (element._overflow !== 'hidden')
element.style.overflow = 'hidden';
return element;
},
@@ -1480,393 +2005,1441 @@
element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
element._overflow = null;
return element;
- }
-};
+ },
-Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+ cumulativeOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return Element._returnOffset(valueL, valueT);
+ },
-Element._attributeTranslations = {};
+ positionedOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ if (element.tagName.toUpperCase() == 'BODY') break;
+ var p = Element.getStyle(element, 'position');
+ if (p !== 'static') break;
+ }
+ } while (element);
+ return Element._returnOffset(valueL, valueT);
+ },
-Element._attributeTranslations.names = {
- colspan: "colSpan",
- rowspan: "rowSpan",
- valign: "vAlign",
- datetime: "dateTime",
- accesskey: "accessKey",
- tabindex: "tabIndex",
- enctype: "encType",
- maxlength: "maxLength",
- readonly: "readOnly",
- longdesc: "longDesc"
-};
+ absolutize: function(element) {
+ element = $(element);
+ if (element.getStyle('position') == 'absolute') return element;
+ // Position.prepare(); // To be done manually by Scripty when it needs it.
-Element._attributeTranslations.values = {
- _getAttr: function(element, attribute) {
- return element.getAttribute(attribute, 2);
+ var offsets = element.positionedOffset();
+ var top = offsets[1];
+ var left = offsets[0];
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ element._originalLeft = left - parseFloat(element.style.left || 0);
+ element._originalTop = top - parseFloat(element.style.top || 0);
+ element._originalWidth = element.style.width;
+ element._originalHeight = element.style.height;
+
+ element.style.position = 'absolute';
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.width = width + 'px';
+ element.style.height = height + 'px';
+ return element;
},
- _flag: function(element, attribute) {
- return $(element).hasAttribute(attribute) ? attribute : null;
+ relativize: function(element) {
+ element = $(element);
+ if (element.getStyle('position') == 'relative') return element;
+ // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+ element.style.position = 'relative';
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.height = element._originalHeight;
+ element.style.width = element._originalWidth;
+ return element;
},
- style: function(element) {
- return element.style.cssText.toLowerCase();
+ cumulativeScrollOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return Element._returnOffset(valueL, valueT);
},
- title: function(element) {
- var node = element.getAttributeNode('title');
- return node.specified ? node.nodeValue : null;
+ getOffsetParent: function(element) {
+ if (element.offsetParent) return $(element.offsetParent);
+ if (element == document.body) return $(element);
+
+ while ((element = element.parentNode) && element != document.body)
+ if (Element.getStyle(element, 'position') != 'static')
+ return $(element);
+
+ return $(document.body);
+ },
+
+ viewportOffset: function(forElement) {
+ var valueT = 0, valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if (element.offsetParent == document.body &&
+ Element.getStyle(element, 'position') == 'absolute') break;
+
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ }
+ } while (element = element.parentNode);
+
+ return Element._returnOffset(valueL, valueT);
+ },
+
+ clonePosition: function(element, source) {
+ var options = Object.extend({
+ setLeft: true,
+ setTop: true,
+ setWidth: true,
+ setHeight: true,
+ offsetTop: 0,
+ offsetLeft: 0
+ }, arguments[2] || { });
+
+ // find page position of source
+ source = $(source);
+ var p = source.viewportOffset();
+
+ // find coordinate system to use
+ element = $(element);
+ var delta = [0, 0];
+ var parent = null;
+ // delta [0,0] will do fine with position: fixed elements,
+ // position:absolute needs offsetParent deltas
+ if (Element.getStyle(element, 'position') == 'absolute') {
+ parent = element.getOffsetParent();
+ delta = parent.viewportOffset();
+ }
+
+ // correct by body offsets (fixes Safari)
+ if (parent == document.body) {
+ delta[0] -= document.body.offsetLeft;
+ delta[1] -= document.body.offsetTop;
+ }
+
+ // set position
+ if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
+ if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
+ if (options.setWidth) element.style.width = source.offsetWidth + 'px';
+ if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+ return element;
}
};
-Object.extend(Element._attributeTranslations.values, {
- href: Element._attributeTranslations.values._getAttr,
- src: Element._attributeTranslations.values._getAttr,
- disabled: Element._attributeTranslations.values._flag,
- checked: Element._attributeTranslations.values._flag,
- readonly: Element._attributeTranslations.values._flag,
- multiple: Element._attributeTranslations.values._flag
+Element.Methods.identify.counter = 1;
+
+Object.extend(Element.Methods, {
+ getElementsBySelector: Element.Methods.select,
+ childElements: Element.Methods.immediateDescendants
});
-Element.Methods.Simulated = {
- hasAttribute: function(element, attribute) {
- var t = Element._attributeTranslations;
- attribute = t.names[attribute] || attribute;
- return $(element).getAttributeNode(attribute).specified;
+Element._attributeTranslations = {
+ write: {
+ names: {
+ className: 'class',
+ htmlFor: 'for'
+ },
+ values: { }
}
};
-// IE is missing .innerHTML support for TABLE-related elements
-if (document.all && !window.opera){
- Element.Methods.update = function(element, html) {
+if (Prototype.Browser.Opera) {
+ Element.Methods.getStyle = Element.Methods.getStyle.wrap(
+ function(proceed, element, style) {
+ switch (style) {
+ case 'left': case 'top': case 'right': case 'bottom':
+ if (proceed(element, 'position') === 'static') return null;
+ case 'height': case 'width':
+ // returns '0px' for hidden elements; we want it to return null
+ if (!Element.visible(element)) return null;
+
+ // returns the border-box dimensions rather than the content-box
+ // dimensions, so we subtract padding and borders from the value
+ var dim = parseInt(proceed(element, style), 10);
+
+ if (dim !== element['offset' + style.capitalize()])
+ return dim + 'px';
+
+ var properties;
+ if (style === 'height') {
+ properties = ['border-top-width', 'padding-top',
+ 'padding-bottom', 'border-bottom-width'];
+ }
+ else {
+ properties = ['border-left-width', 'padding-left',
+ 'padding-right', 'border-right-width'];
+ }
+ return properties.inject(dim, function(memo, property) {
+ var val = proceed(element, property);
+ return val === null ? memo : memo - parseInt(val, 10);
+ }) + 'px';
+ default: return proceed(element, style);
+ }
+ }
+ );
+
+ Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
+ function(proceed, element, attribute) {
+ if (attribute === 'title') return element.title;
+ return proceed(element, attribute);
+ }
+ );
+}
+
+else if (Prototype.Browser.IE) {
+ // IE doesn't report offsets correctly for static elements, so we change them
+ // to "relative" to get the values, then change them back.
+ Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
+ function(proceed, element) {
+ element = $(element);
+ // IE throws an error if element is not in document
+ try { element.offsetParent }
+ catch(e) { return $(document.body) }
+ var position = element.getStyle('position');
+ if (position !== 'static') return proceed(element);
+ element.setStyle({ position: 'relative' });
+ var value = proceed(element);
+ element.setStyle({ position: position });
+ return value;
+ }
+ );
+
+ $w('positionedOffset viewportOffset').each(function(method) {
+ Element.Methods[method] = Element.Methods[method].wrap(
+ function(proceed, element) {
+ element = $(element);
+ try { element.offsetParent }
+ catch(e) { return Element._returnOffset(0,0) }
+ var position = element.getStyle('position');
+ if (position !== 'static') return proceed(element);
+ // Trigger hasLayout on the offset parent so that IE6 reports
+ // accurate offsetTop and offsetLeft values for position: fixed.
+ var offsetParent = element.getOffsetParent();
+ if (offsetParent && offsetParent.getStyle('position') === 'fixed')
+ offsetParent.setStyle({ zoom: 1 });
+ element.setStyle({ position: 'relative' });
+ var value = proceed(element);
+ element.setStyle({ position: position });
+ return value;
+ }
+ );
+ });
+
+ Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
+ function(proceed, element) {
+ try { element.offsetParent }
+ catch(e) { return Element._returnOffset(0,0) }
+ return proceed(element);
+ }
+ );
+
+ Element.Methods.getStyle = function(element, style) {
element = $(element);
- html = typeof html == 'undefined' ? '' : html.toString();
- var tagName = element.tagName.toUpperCase();
- if (['THEAD','TBODY','TR','TD'].include(tagName)) {
- var div = document.createElement('div');
- switch (tagName) {
- case 'THEAD':
- case 'TBODY':
- div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
- depth = 2;
- break;
- case 'TR':
- div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
- depth = 3;
- break;
- case 'TD':
- div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
- depth = 4;
+ style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value && element.currentStyle) value = element.currentStyle[style];
+
+ if (style == 'opacity') {
+ if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if (value[1]) return parseFloat(value[1]) / 100;
+ return 1.0;
+ }
+
+ if (value == 'auto') {
+ if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+ return element['offset' + style.capitalize()] + 'px';
+ return null;
+ }
+ return value;
+ };
+
+ Element.Methods.setOpacity = function(element, value) {
+ function stripAlpha(filter){
+ return filter.replace(/alpha\([^\)]*\)/gi,'');
+ }
+ element = $(element);
+ var currentStyle = element.currentStyle;
+ if ((currentStyle && !currentStyle.hasLayout) ||
+ (!currentStyle && element.style.zoom == 'normal'))
+ element.style.zoom = 1;
+
+ var filter = element.getStyle('filter'), style = element.style;
+ if (value == 1 || value === '') {
+ (filter = stripAlpha(filter)) ?
+ style.filter = filter : style.removeAttribute('filter');
+ return element;
+ } else if (value < 0.00001) value = 0;
+ style.filter = stripAlpha(filter) +
+ 'alpha(opacity=' + (value * 100) + ')';
+ return element;
+ };
+
+ Element._attributeTranslations = {
+ read: {
+ names: {
+ 'class': 'className',
+ 'for': 'htmlFor'
+ },
+ values: {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+ _getAttrNode: function(element, attribute) {
+ var node = element.getAttributeNode(attribute);
+ return node ? node.value : "";
+ },
+ _getEv: function(element, attribute) {
+ attribute = element.getAttribute(attribute);
+ return attribute ? attribute.toString().slice(23, -2) : null;
+ },
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+ title: function(element) {
+ return element.title;
+ }
}
- $A(element.childNodes).each(function(node){
- element.removeChild(node)
- });
- depth.times(function(){ div = div.firstChild });
+ }
+ };
- $A(div.childNodes).each(
- function(node){ element.appendChild(node) });
- } else {
- element.innerHTML = html.stripScripts();
+ Element._attributeTranslations.write = {
+ names: Object.extend({
+ cellpadding: 'cellPadding',
+ cellspacing: 'cellSpacing'
+ }, Element._attributeTranslations.read.names),
+ values: {
+ checked: function(element, value) {
+ element.checked = !!value;
+ },
+
+ style: function(element, value) {
+ element.style.cssText = value ? value : '';
+ }
}
- setTimeout(function() {html.evalScripts()}, 10);
+ };
+
+ Element._attributeTranslations.has = {};
+
+ $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+ 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
+ Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+ Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+ });
+
+ (function(v) {
+ Object.extend(v, {
+ href: v._getAttr,
+ src: v._getAttr,
+ type: v._getAttr,
+ action: v._getAttrNode,
+ disabled: v._flag,
+ checked: v._flag,
+ readonly: v._flag,
+ multiple: v._flag,
+ onload: v._getEv,
+ onunload: v._getEv,
+ onclick: v._getEv,
+ ondblclick: v._getEv,
+ onmousedown: v._getEv,
+ onmouseup: v._getEv,
+ onmouseover: v._getEv,
+ onmousemove: v._getEv,
+ onmouseout: v._getEv,
+ onfocus: v._getEv,
+ onblur: v._getEv,
+ onkeypress: v._getEv,
+ onkeydown: v._getEv,
+ onkeyup: v._getEv,
+ onsubmit: v._getEv,
+ onreset: v._getEv,
+ onselect: v._getEv,
+ onchange: v._getEv
+ });
+ })(Element._attributeTranslations.read.values);
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1) ? 0.999999 :
+ (value === '') ? '' : (value < 0.00001) ? 0 : value;
return element;
+ };
+}
+
+else if (Prototype.Browser.WebKit) {
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
+
+ if (value == 1)
+ if(element.tagName.toUpperCase() == 'IMG' && element.width) {
+ element.width++; element.width--;
+ } else try {
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch (e) { }
+
+ return element;
+ };
+
+ // Safari returns margins on body which is incorrect if the child is absolutely
+ // positioned. For performance reasons, redefine Element#cumulativeOffset for
+ // KHTML/WebKit only.
+ Element.Methods.cumulativeOffset = function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == document.body)
+ if (Element.getStyle(element, 'position') == 'absolute') break;
+
+ element = element.offsetParent;
+ } while (element);
+
+ return Element._returnOffset(valueL, valueT);
+ };
+}
+
+if (Prototype.Browser.IE || Prototype.Browser.Opera) {
+ // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
+ Element.Methods.update = function(element, content) {
+ element = $(element);
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) return element.update().insert(content);
+
+ content = Object.toHTML(content);
+ var tagName = element.tagName.toUpperCase();
+
+ if (tagName in Element._insertionTranslations.tags) {
+ $A(element.childNodes).each(function(node) { element.removeChild(node) });
+ Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+ .each(function(node) { element.appendChild(node) });
+ }
+ else element.innerHTML = content.stripScripts();
+
+ content.evalScripts.bind(content).defer();
+ return element;
+ };
+}
+
+if ('outerHTML' in document.createElement('div')) {
+ Element.Methods.replace = function(element, content) {
+ element = $(element);
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) {
+ element.parentNode.replaceChild(content, element);
+ return element;
+ }
+
+ content = Object.toHTML(content);
+ var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+ if (Element._insertionTranslations.tags[tagName]) {
+ var nextSibling = element.next();
+ var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+ parent.removeChild(element);
+ if (nextSibling)
+ fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+ else
+ fragments.each(function(node) { parent.appendChild(node) });
+ }
+ else element.outerHTML = content.stripScripts();
+
+ content.evalScripts.bind(content).defer();
+ return element;
+ };
+}
+
+Element._returnOffset = function(l, t) {
+ var result = [l, t];
+ result.left = l;
+ result.top = t;
+ return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html) {
+ var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+ if (t) {
+ div.innerHTML = t[0] + html + t[1];
+ t[2].times(function() { div = div.firstChild });
+ } else div.innerHTML = html;
+ return $A(div.childNodes);
+};
+
+Element._insertionTranslations = {
+ before: function(element, node) {
+ element.parentNode.insertBefore(node, element);
+ },
+ top: function(element, node) {
+ element.insertBefore(node, element.firstChild);
+ },
+ bottom: function(element, node) {
+ element.appendChild(node);
+ },
+ after: function(element, node) {
+ element.parentNode.insertBefore(node, element.nextSibling);
+ },
+ tags: {
+ TABLE: ['<table>', '</table>', 1],
+ TBODY: ['<table><tbody>', '</tbody></table>', 2],
+ TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
+ TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+ SELECT: ['<select>', '</select>', 1]
}
};
+(function() {
+ Object.extend(this.tags, {
+ THEAD: this.tags.TBODY,
+ TFOOT: this.tags.TBODY,
+ TH: this.tags.TD
+ });
+}).call(Element._insertionTranslations);
+
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ attribute = Element._attributeTranslations.has[attribute] || attribute;
+ var node = $(element).getAttributeNode(attribute);
+ return !!(node && node.specified);
+ }
+};
+
+Element.Methods.ByTag = { };
+
Object.extend(Element, Element.Methods);
-var _nativeExtensions = false;
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+ document.createElement('div')['__proto__']) {
+ window.HTMLElement = { };
+ window.HTMLElement.prototype = document.createElement('div')['__proto__'];
+ Prototype.BrowserFeatures.ElementExtensions = true;
+}
-if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
- ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
- var className = 'HTML' + tag + 'Element';
- if(window[className]) return;
- var klass = window[className] = {};
- klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+Element.extend = (function() {
+ if (Prototype.BrowserFeatures.SpecificElementExtensions)
+ return Prototype.K;
+
+ var Methods = { }, ByTag = Element.Methods.ByTag;
+
+ var extend = Object.extend(function(element) {
+ if (!element || element._extendedByPrototype ||
+ element.nodeType != 1 || element == window) return element;
+
+ var methods = Object.clone(Methods),
+ tagName = element.tagName.toUpperCase(), property, value;
+
+ // extend methods for specific tags
+ if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+ for (property in methods) {
+ value = methods[property];
+ if (Object.isFunction(value) && !(property in element))
+ element[property] = value.methodize();
+ }
+
+ element._extendedByPrototype = Prototype.emptyFunction;
+ return element;
+
+ }, {
+ refresh: function() {
+ // extend methods for all tags (Safari doesn't need this)
+ if (!Prototype.BrowserFeatures.ElementExtensions) {
+ Object.extend(Methods, Element.Methods);
+ Object.extend(Methods, Element.Methods.Simulated);
+ }
+ }
});
+ extend.refresh();
+ return extend;
+})();
+
+Element.hasAttribute = function(element, attribute) {
+ if (element.hasAttribute) return element.hasAttribute(attribute);
+ return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
Element.addMethods = function(methods) {
- Object.extend(Element.Methods, methods || {});
+ var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+ if (!methods) {
+ Object.extend(Form, Form.Methods);
+ Object.extend(Form.Element, Form.Element.Methods);
+ Object.extend(Element.Methods.ByTag, {
+ "FORM": Object.clone(Form.Methods),
+ "INPUT": Object.clone(Form.Element.Methods),
+ "SELECT": Object.clone(Form.Element.Methods),
+ "TEXTAREA": Object.clone(Form.Element.Methods)
+ });
+ }
+
+ if (arguments.length == 2) {
+ var tagName = methods;
+ methods = arguments[1];
+ }
+
+ if (!tagName) Object.extend(Element.Methods, methods || { });
+ else {
+ if (Object.isArray(tagName)) tagName.each(extend);
+ else extend(tagName);
+ }
+
+ function extend(tagName) {
+ tagName = tagName.toUpperCase();
+ if (!Element.Methods.ByTag[tagName])
+ Element.Methods.ByTag[tagName] = { };
+ Object.extend(Element.Methods.ByTag[tagName], methods);
+ }
+
function copy(methods, destination, onlyIfAbsent) {
|| false;
- var cache = Element.extend.cache;
for (var property in methods) {
var value = methods[property];
+ if (!Object.isFunction(value)) continue;
if (!onlyIfAbsent || !(property in destination))
- destination[property] = cache.findOrStore(value);
+ destination[property] = value.methodize();
}
}
- if (typeof HTMLElement != 'undefined') {
+ function findDOMClass(tagName) {
+ var klass;
+ var trans = {
+ "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+ "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+ "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+ "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+ "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+ "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+ "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+ "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+ "FrameSet", "IFRAME": "IFrame"
+ };
+ if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName.capitalize() + 'Element';
+ if (window[klass]) return window[klass];
+
+ window[klass] = { };
+ window[klass].prototype = document.createElement(tagName)['__proto__'];
+ return window[klass];
+ }
+
+ if (F.ElementExtensions) {
copy(Element.Methods, HTMLElement.prototype);
copy(Element.Methods.Simulated, HTMLElement.prototype, true);
- copy(Form.Methods, HTMLFormElement.prototype);
- [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
- copy(Form.Element.Methods, klass.prototype);
- });
- _nativeExtensions = true;
}
-}
-var Toggle = new Object();
-Toggle.display = Element.toggle;
+ if (F.SpecificElementExtensions) {
+ for (var tag in Element.Methods.ByTag) {
+ var klass = findDOMClass(tag);
+ if (Object.isUndefined(klass)) continue;
+ copy(T[tag], klass.prototype);
+ }
+ }
-/*--------------------------------------------------------------------------*/
+ Object.extend(Element, Element.Methods);
+ delete Element.ByTag;
-Abstract.Insertion = function(adjacency) {
- this.adjacency = adjacency;
-}
+ if (Element.extend.refresh) Element.extend.refresh();
+ Element.cache = { };
+};
-Abstract.Insertion.prototype = {
- initialize: function(element, content) {
- this.element = $(element);
- this.content = content.stripScripts();
+document.viewport = {
+ getDimensions: function() {
+ var dimensions = { }, B = Prototype.Browser;
+ $w('width height').each(function(d) {
+ var D = d.capitalize();
+ if (B.WebKit && !document.evaluate) {
+ // Safari <3.0 needs self.innerWidth/Height
+ dimensions[d] = self['inner' + D];
+ } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
+ // Opera <9.5 needs document.body.clientWidth/Height
+ dimensions[d] = document.body['client' + D]
+ } else {
+ dimensions[d] = document.documentElement['client' + D];
+ }
+ });
+ return dimensions;
+ },
- if (this.adjacency && this.element.insertAdjacentHTML) {
- try {
- this.element.insertAdjacentHTML(this.adjacency, this.content);
- } catch (e) {
- var tagName = this.element.tagName.toUpperCase();
- if (['TBODY', 'TR'].include(tagName)) {
- this.insertContent(this.contentFromAnonymousTable());
- } else {
- throw e;
- }
- }
+ getWidth: function() {
+ return this.getDimensions().width;
+ },
+
+ getHeight: function() {
+ return this.getDimensions().height;
+ },
+
+ getScrollOffsets: function() {
+ return Element._returnOffset(
+ window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+ window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+ }
+};
+/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license. Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create({
+ initialize: function(_expression_) {
+ this._expression_ = _expression_.strip();
+
+ if (this.shouldUseSelectorsAPI()) {
+ this.mode = 'selectorsAPI';
+ } else if (this.shouldUseXPath()) {
+ this.mode = 'xpath';
+ this.compileXPathMatcher();
} else {
- this.range = this.element.ownerDocument.createRange();
- if (this.initializeRange) this.initializeRange();
- this.insertContent([this.range.createContextualFragment(this.content)]);
+ this.mode = "normal";
+ this.compileMatcher();
}
- setTimeout(function() {content.evalScripts()}, 10);
},
- contentFromAnonymousTable: function() {
- var div = document.createElement('div');
- div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
+ shouldUseXPath: function() {
+ if (!Prototype.BrowserFeatures.XPath) return false;
-var Insertion = new Object();
+ var e = this._expression_;
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
+ // Safari 3 chokes on :*-of-type and :empty
+ if (Prototype.Browser.WebKit &&
+ (e.include("-of-type") || e.include(":empty")))
+ return false;
+
+ // XPath can't do namespaced attributes, nor can it read
+ // the "checked" property from DOM nodes
+ if ((/(\[[\w-]*?:|:checked)/).test(e))
+ return false;
+
+ return true;
},
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
+ shouldUseSelectorsAPI: function() {
+ if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
+ if (!Selector._div) Selector._div = new Element('div');
+
+ // Make sure the browser treats the selector as valid. Test on an
+ // isolated element to minimize cost of this check.
+ try {
+ Selector._div.querySelector(this._expression_);
+ } catch(e) {
+ return false;
+ }
+
+ return true;
},
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
+ compileMatcher: function() {
+ var e = this._expression_, ps = Selector.patterns, h = Selector.handlers,
+ c = Selector.criteria, le, p, m;
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
+ if (Selector._cache[e]) {
+ this.matcher = Selector._cache[e];
+ return;
+ }
+
+ this.matcher = ["this.matcher = function(root) {",
+ "var r = root, h = Selector.handlers, c = false, n;"];
+
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ p = ps[i];
+ if (m = e.match(p)) {
+ this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
+ new Template(c[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.matcher.push("return h.unique(n);\n}");
+ eval(this.matcher.join('\n'));
+ Selector._cache[this._expression_] = this.matcher;
},
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
+ compileXPathMatcher: function() {
+ var e = this._expression_, ps = Selector.patterns,
+ x = Selector.xpath, le, m;
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
+ if (Selector._cache[e]) {
+ this.xpath = Selector._cache[e]; return;
+ }
+
+ this.matcher = ['.//*'];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ if (m = e.match(ps[i])) {
+ this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
+ new Template(x[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.xpath = this.matcher.join('');
+ Selector._cache[this._expression_] = this.xpath;
},
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
+ findElements: function(root) {
+ root = root || document;
+ var e = this._expression_, results;
-/*--------------------------------------------------------------------------*/
+ switch (this.mode) {
+ case 'selectorsAPI':
+ // querySelectorAll queries document-wide, then filters to descendants
+ // of the context element. That's not what we want.
+ // Add an explicit context to the selector if necessary.
+ if (root !== document) {
+ var oldId = root.id, id = $(root).identify();
+ e = "#" + id + " " + e;
+ }
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
+ results = $A(root.querySelectorAll(e)).map(Element.extend);
+ root.id = oldId;
+
+ return results;
+ case 'xpath':
+ return document._getElementsByXPath(this.xpath, root);
+ default:
+ return this.matcher(root);
+ }
},
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
+ match: function(element) {
+ this.tokens = [];
+
+ var e = this._expression_, ps = Selector.patterns, as = Selector.assertions;
+ var le, p, m;
+
+ while (e && le !== e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ p = ps[i];
+ if (m = e.match(p)) {
+ // use the Selector.assertions methods unless the selector
+ // is too complex.
+ if (as[i]) {
+ this.tokens.push([i, Object.clone(m)]);
+ e = e.replace(m[0], '');
+ } else {
+ // reluctantly do a document-wide search
+ // and look for a match in the array
+ return this.findElements(document).include(element);
+ }
+ }
+ }
+ }
+
+ var match = true, name, matches;
+ for (var i = 0, token; token = this.tokens[i]; i++) {
+ name = token[0], matches = token[1];
+ if (!Selector.assertions[name](element, matches)) {
+ match = false; break;
+ }
+ }
+
+ return match;
},
- set: function(className) {
- this.element.className = className;
+ toString: function() {
+ return this._expression_;
},
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set($A(this).concat(classNameToAdd).join(' '));
+ inspect: function() {
+ return "#<Selector:" + this._expression_.inspect() + ">";
+ }
+});
+
+Object.extend(Selector, {
+ _cache: { },
+
+ xpath: {
+ descendant: "//*",
+ child: "/*",
+ adjacent: "/following-sibling::*[1]",
+ laterSibling: '/following-sibling::*',
+ tagName: function(m) {
+ if (m[1] == '*') return '';
+ return "[local-name()='" + m[1].toLowerCase() +
+ "' or local-name()='" + m[1].toUpperCase() + "']";
+ },
+ className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+ id: "address@hidden'#{1}']",
+ attrPresence: function(m) {
+ m[1] = m[1].toLowerCase();
+ return new Template("address@hidden").evaluate(m);
+ },
+ attr: function(m) {
+ m[1] = m[1].toLowerCase();
+ m[3] = m[5] || m[6];
+ return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+ },
+ pseudo: function(m) {
+ var h = Selector.xpath.pseudos[m[1]];
+ if (!h) return '';
+ if (Object.isFunction(h)) return h(m);
+ return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+ },
+ operators: {
+ '=': "address@hidden'#{3}']",
+ '!=': "address@hidden'#{3}']",
+ '^=': "[starts-with(@#{1}, '#{3}')]",
+ '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+ '*=': "[contains(@#{1}, '#{3}')]",
+ '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+ '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+ },
+ pseudos: {
+ 'first-child': '[not(preceding-sibling::*)]',
+ 'last-child': '[not(following-sibling::*)]',
+ 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
+ 'empty': "[count(*) = 0 and (count(text()) = 0)]",
+ 'checked': "address@hidden",
+ 'disabled': "[(@disabled) and (@type!='hidden')]",
+ 'enabled': "[not(@disabled) and (@type!='hidden')]",
+ 'not': function(m) {
+ var e = m[6], p = Selector.patterns,
+ x = Selector.xpath, le, v;
+
+ var exclusion = [];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in p) {
+ if (m = e.match(p[i])) {
+ v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
+ exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+ return "[not(" + exclusion.join(" and ") + ")]";
+ },
+ 'nth-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+ },
+ 'nth-last-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+ },
+ 'nth-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("position() ", m);
+ },
+ 'nth-last-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+ },
+ 'first-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+ },
+ 'last-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+ },
+ 'only-of-type': function(m) {
+ var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+ },
+ nth: function(fragment, m) {
+ var mm, formula = m[6], predicate;
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ if (mm = formula.match(/^(\d+)$/)) // digit only
+ return '[' + fragment + "= " + mm[1] + ']';
+ if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (mm[1] == "-") mm[1] = -1;
+ var a = mm[1] ? Number(mm[1]) : 1;
+ var b = mm[2] ? Number(mm[2]) : 0;
+ predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+ "((#{fragment} - #{b}) div #{a} >= 0)]";
+ return new Template(predicate).evaluate({
+ fragment: fragment, a: a, b: b });
+ }
+ }
+ }
},
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set($A(this).without(classNameToRemove).join(' '));
+ criteria: {
+ tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
+ className: 'n = h.className(n, r, "#{1}", c); c = false;',
+ id: 'n = h.id(n, r, "#{1}", c); c = false;',
+ attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
+ attr: function(m) {
+ m[3] = (m[5] || m[6]);
+ return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
+ },
+ pseudo: function(m) {
+ if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+ return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+ },
+ descendant: 'c = "descendant";',
+ child: 'c = "child";',
+ adjacent: 'c = "adjacent";',
+ laterSibling: 'c = "laterSibling";'
},
- toString: function() {
- return $A(this).join(' ');
- }
-};
+ patterns: {
+ // combinators must be listed first
+ // (and descendant needs to be last combinator)
+ laterSibling: /^\s*~\s*/,
+ child: /^\s*>\s*/,
+ adjacent: /^\s*\+\s*/,
+ descendant: /^\s/,
-Object.extend(Element.ClassNames.prototype, Enumerable);
-var Selector = Class.create();
-Selector.prototype = {
- initialize: function(_expression_) {
- this.params = {classNames: []};
- this._expression_ = _expression_.toString().strip();
- this.parseExpression();
- this.compileMatcher();
+ // selectors follow
+ tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
+ id: /^#([\w\-\*]+)(\b|$)/,
+ className: /^\.([\w\-\*]+)(\b|$)/,
+ pseudo:
+/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
+ attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
+ attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
},
- parseExpression: function() {
- function abort(message) { throw 'Parse error in selector: ' + message; }
+ // for Selector.match and Element#match
+ assertions: {
+ tagName: function(element, matches) {
+ return matches[1].toUpperCase() == element.tagName.toUpperCase();
+ },
- if (this._expression_ == '') abort('empty _expression_');
+ className: function(element, matches) {
+ return Element.hasClassName(element, matches[1]);
+ },
- var params = this.params, expr = this._expression_, match, modifier, clause, rest;
- while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
- params.attributes = params.attributes || [];
- params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
- expr = match[1];
+ id: function(element, matches) {
+ return element.id === matches[1];
+ },
+
+ attrPresence: function(element, matches) {
+ return Element.hasAttribute(element, matches[1]);
+ },
+
+ attr: function(element, matches) {
+ var nodeValue = Element.readAttribute(element, matches[1]);
+ return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
}
+ },
- if (expr == '*') return this.params.wildcard = true;
+ handlers: {
+ // UTILITY FUNCTIONS
+ // joins two collections
+ concat: function(a, b) {
+ for (var i = 0, node; node = b[i]; i++)
+ a.push(node);
+ return a;
+ },
- while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
- modifier = match[1], clause = match[2], rest = match[3];
- switch (modifier) {
- case '#': params.id = clause; break;
- case '.': params.classNames.push(clause); break;
- case '':
- case undefined: params.tagName = clause.toUpperCase(); break;
- default: abort(expr.inspect());
+ // marks an array of nodes for counting
+ mark: function(nodes) {
+ var _true = Prototype.emptyFunction;
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._countedByPrototype = _true;
+ return nodes;
+ },
+
+ unmark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._countedByPrototype = undefined;
+ return nodes;
+ },
+
+ // mark each child node with its position (for nth calls)
+ // "ofType" flag indicates whether we're indexing for nth-of-type
+ // rather than nth-child
+ index: function(parentNode, reverse, ofType) {
+ parentNode._countedByPrototype = Prototype.emptyFunction;
+ if (reverse) {
+ for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+ var node = nodes[i];
+ if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
+ }
+ } else {
+ for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+ if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
}
- expr = rest;
- }
+ },
- if (expr.length > 0) abort(expr.inspect());
- },
+ // filters out duplicates and extends all nodes
+ unique: function(nodes) {
+ if (nodes.length == 0) return nodes;
+ var results = [], n;
+ for (var i = 0, l = nodes.length; i < l; i++)
+ if (!(n = nodes[i])._countedByPrototype) {
+ n._countedByPrototype = Prototype.emptyFunction;
+ results.push(Element.extend(n));
+ }
+ return Selector.handlers.unmark(results);
+ },
- buildMatchExpression: function() {
- var params = this.params, conditions = [], clause;
+ // COMBINATOR FUNCTIONS
+ descendant: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName('*'));
+ return results;
+ },
- if (params.wildcard)
- conditions.push('true');
- if (clause = params.id)
- conditions.push('element.readAttribute("id") == ' + clause.inspect());
- if (clause = params.tagName)
- conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
- if ((clause = params.classNames).length > 0)
- for (var i = 0, length = clause.length; i < length; i++)
- conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
- if (clause = params.attributes) {
- clause.each(function(attribute) {
- var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
- var splitValueBy = function(delimiter) {
- return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+ child: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ for (var j = 0, child; child = node.childNodes[j]; j++)
+ if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+ }
+ return results;
+ },
+
+ adjacent: function(nodes) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ var next = this.nextElementSibling(node);
+ if (next) results.push(next);
+ }
+ return results;
+ },
+
+ laterSibling: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, Element.nextSiblings(node));
+ return results;
+ },
+
+ nextElementSibling: function(node) {
+ while (node = node.nextSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ previousElementSibling: function(node) {
+ while (node = node.previousSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ // TOKEN FUNCTIONS
+ tagName: function(nodes, root, tagName, combinator) {
+ var uTagName = tagName.toUpperCase();
+ var results = [], h = Selector.handlers;
+ if (nodes) {
+ if (combinator) {
+ // fastlane for ordinary descendant combinators
+ if (combinator == "descendant") {
+ for (var i = 0, node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName(tagName));
+ return results;
+ } else nodes = this[combinator](nodes);
+ if (tagName == "*") return nodes;
}
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.tagName.toUpperCase() === uTagName) results.push(node);
+ return results;
+ } else return root.getElementsByTagName(tagName);
+ },
- switch (attribute.operator) {
- case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
- case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
- case '|=': conditions.push(
- splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
- ); break;
- case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
- case '':
- case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
- default: throw 'Unknown operator ' + attribute.operator + ' in selector';
+ id: function(nodes, root, id, combinator) {
+ var targetNode = $(id), h = Selector.handlers;
+ if (!targetNode) return [];
+ if (!nodes && root == document) return [targetNode];
+ if (nodes) {
+ if (combinator) {
+ if (combinator == 'child') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (targetNode.parentNode == node) return [targetNode];
+ } else if (combinator == 'descendant') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.descendantOf(targetNode, node)) return [targetNode];
+ } else if (combinator == 'adjacent') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Selector.handlers.previousElementSibling(targetNode) == node)
+ return [targetNode];
+ } else nodes = h[combinator](nodes);
}
- });
- }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node == targetNode) return [targetNode];
+ return [];
+ }
+ return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+ },
- return conditions.join(' && ');
- },
+ className: function(nodes, root, className, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ return Selector.handlers.byClassName(nodes, root, className);
+ },
- compileMatcher: function() {
- this.match = new Function('element', 'if (!element.tagName) return false; \
- element = $(element); \
- return ' + this.buildMatchExpression());
+ byClassName: function(nodes, root, className) {
+ if (!nodes) nodes = Selector.handlers.descendant([root]);
+ var needle = ' ' + className + ' ';
+ for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+ nodeClassName = node.className;
+ if (nodeClassName.length == 0) continue;
+ if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+ results.push(node);
+ }
+ return results;
+ },
+
+ attrPresence: function(nodes, root, attr, combinator) {
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ var results = [];
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.hasAttribute(node, attr)) results.push(node);
+ return results;
+ },
+
+ attr: function(nodes, root, attr, value, operator, combinator) {
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ var handler = Selector.operators[operator], results = [];
+ for (var i = 0, node; node = nodes[i]; i++) {
+ var nodeValue = Element.readAttribute(node, attr);
+ if (nodeValue === null) continue;
+ if (handler(nodeValue, value)) results.push(node);
+ }
+ return results;
+ },
+
+ pseudo: function(nodes, name, value, root, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ return Selector.pseudos[name](nodes, value, root);
+ }
},
- findElements: function(scope) {
- var element;
+ pseudos: {
+ 'first-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.previousElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'last-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.nextElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'only-child': function(nodes, value, root) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+ results.push(node);
+ return results;
+ },
+ 'nth-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root);
+ },
+ 'nth-last-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true);
+ },
+ 'nth-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, false, true);
+ },
+ 'nth-last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true, true);
+ },
+ 'first-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, false, true);
+ },
+ 'last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, true, true);
+ },
+ 'only-of-type': function(nodes, formula, root) {
+ var p = Selector.pseudos;
+ return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+ },
- if (element = $(this.params.id))
- if (this.match(element))
- if (!scope || Element.childOf(element, scope))
- return [element];
+ // handles the an+b logic
+ getIndices: function(a, b, total) {
+ if (a == 0) return b > 0 ? [b] : [];
+ return $R(1, total).inject([], function(memo, i) {
+ if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+ return memo;
+ });
+ },
- scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+ // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+ nth: function(nodes, formula, root, reverse, ofType) {
+ if (nodes.length == 0) return [];
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ var h = Selector.handlers, results = [], indexed = [], m;
+ h.mark(nodes);
+ for (var i = 0, node; node = nodes[i]; i++) {
+ if (!node.parentNode._countedByPrototype) {
+ h.index(node.parentNode, reverse, ofType);
+ indexed.push(node.parentNode);
+ }
+ }
+ if (formula.match(/^\d+$/)) { // just a number
+ formula = Number(formula);
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.nodeIndex == formula) results.push(node);
+ } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (m[1] == "-") m[1] = -1;
+ var a = m[1] ? Number(m[1]) : 1;
+ var b = m[2] ? Number(m[2]) : 0;
+ var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+ for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+ for (var j = 0; j < l; j++)
+ if (node.nodeIndex == indices[j]) results.push(node);
+ }
+ }
+ h.unmark(nodes);
+ h.unmark(indexed);
+ return results;
+ },
- var results = [];
- for (var i = 0, length = scope.length; i < length; i++)
- if (this.match(element = scope[i]))
- results.push(Element.extend(element));
+ 'empty': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ // IE treats comments as element nodes
+ if (node.tagName == '!' || node.firstChild) continue;
+ results.push(node);
+ }
+ return results;
+ },
- return results;
+ 'not': function(nodes, selector, root) {
+ var h = Selector.handlers, selectorType, m;
+ var exclusions = new Selector(selector).findElements(root);
+ h.mark(exclusions);
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node._countedByPrototype) results.push(node);
+ h.unmark(exclusions);
+ return results;
+ },
+
+ 'enabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node.disabled && (!node.type || node.type !== 'hidden'))
+ results.push(node);
+ return results;
+ },
+
+ 'disabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.disabled) results.push(node);
+ return results;
+ },
+
+ 'checked': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.checked) results.push(node);
+ return results;
+ }
},
- toString: function() {
- return this._expression_;
- }
-}
+ operators: {
+ '=': function(nv, v) { return nv == v; },
+ '!=': function(nv, v) { return nv != v; },
+ '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
+ '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
+ '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
+ '$=': function(nv, v) { return nv.endsWith(v); },
+ '*=': function(nv, v) { return nv.include(v); },
+ '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+ '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
+ '-').include('-' + (v || "").toUpperCase() + '-'); }
+ },
-Object.extend(Selector, {
+ split: function(_expression_) {
+ var expressions = [];
+ _expression_.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+ expressions.push(m[1].strip());
+ });
+ return expressions;
+ },
+
matchElements: function(elements, _expression_) {
- var selector = new Selector(_expression_);
- return elements.select(selector.match.bind(selector)).map(Element.extend);
+ var matches = $$(_expression_), h = Selector.handlers;
+ h.mark(matches);
+ for (var i = 0, results = [], element; element = elements[i]; i++)
+ if (element._countedByPrototype) results.push(element);
+ h.unmark(matches);
+ return results;
},
findElement: function(elements, _expression_, index) {
- if (typeof _expression_ == 'number') index = _expression_, _expression_ = false;
+ if (Object.isNumber(_expression_)) {
+ index = _expression_; _expression_ = false;
+ }
return Selector.matchElements(elements, _expression_ || '*')[index || 0];
},
findChildElements: function(element, expressions) {
- return expressions.map(function(_expression_) {
- return _expression_.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
- var selector = new Selector(expr);
- return results.inject([], function(elements, result) {
- return elements.concat(selector.findElements(result || element));
- });
- });
- }).flatten();
+ expressions = Selector.split(expressions.join(','));
+ var results = [], h = Selector.handlers;
+ for (var i = 0, l = expressions.length, selector; i < l; i++) {
+ selector = new Selector(expressions[i].strip());
+ h.concat(results, selector.findElements(element));
+ }
+ return (l > 1) ? h.unique(results) : results;
}
});
+if (Prototype.Browser.IE) {
+ Object.extend(Selector.handlers, {
+ // IE returns comment nodes on getElementsByTagName("*").
+ // Filter them out.
+ concat: function(a, b) {
+ for (var i = 0, node; node = b[i]; i++)
+ if (node.tagName !== "!") a.push(node);
+ return a;
+ },
+
+ // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
+ unmark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node.removeAttribute('_countedByPrototype');
+ return nodes;
+ }
+ });
+}
+
function $$() {
return Selector.findChildElements(document, $A(arguments));
}
@@ -1876,13 +3449,19 @@
return form;
},
- serializeElements: function(elements, getHash) {
- var data = "" function(result, element) {
+ serializeElements: function(elements, options) {
+ if (typeof options != 'object') options = { hash: !!options };
+ else if (Object.isUndefined(options.hash)) options.hash = true;
+ var key, value, submitted = false, submit = options.submit;
+
+ var data = "" }, function(result, element) {
if (!element.disabled && element.name) {
- var key = element.name, value = $(element).getValue();
- if (value != undefined) {
- if (result[key]) {
- if (result[key].constructor != Array) result[key] = [result[key]];
+ key = element.name; value = $(element).getValue();
+ if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
+ submit !== false && (!submit || key == submit) && (submitted = true)))) {
+ if (key in result) {
+ // a key is already present; construct an array of values
+ if (!Object.isArray(result[key])) result[key] = [result[key]];
result[key].push(value);
}
else result[key] = value;
@@ -1891,13 +3470,13 @@
return result;
});
- return getHash ? data : Hash.toQueryString(data);
+ return options.hash ? data : Object.toQueryString(data);
}
};
Form.Methods = {
- serialize: function(form, getHash) {
- return Form.serializeElements(Form.getElements(form), getHash);
+ serialize: function(form, options) {
+ return Form.serializeElements(Form.getElements(form), options);
},
getElements: function(form) {
@@ -1928,37 +3507,54 @@
disable: function(form) {
form = $(form);
- form.getElements().each(function(element) {
- element.blur();
- element.disabled = 'true';
- });
+ Form.getElements(form).invoke('disable');
return form;
},
enable: function(form) {
form = $(form);
- form.getElements().each(function(element) {
- element.disabled = '';
- });
+ Form.getElements(form).invoke('enable');
return form;
},
findFirstElement: function(form) {
- return $(form).getElements().find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ var elements = $(form).getElements().findAll(function(element) {
+ return 'hidden' != element.type && !element.disabled;
});
+ var firstByIndex = elements.findAll(function(element) {
+ return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+ }).sortBy(function(element) { return element.tabIndex }).first();
+
+ return firstByIndex ? firstByIndex : elements.find(function(element) {
+ return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
},
focusFirstElement: function(form) {
form = $(form);
form.findFirstElement().activate();
return form;
+ },
+
+ request: function(form, options) {
+ form = $(form), options = Object.clone(options || { });
+
+ var params = options.parameters, action = "" || '';
+ if (action.blank()) action = ""
+ options.parameters = form.serialize(true);
+
+ if (params) {
+ if (Object.isString(params)) params = params.toQueryParams();
+ Object.extend(options.parameters, params);
+ }
+
+ if (form.hasAttribute('method') && !options.method)
+ options.method = form.method;
+
+ return new Ajax.Request(action, options);
}
-}
+};
-Object.extend(Form, Form.Methods);
-
/*--------------------------------------------------------------------------*/
Form.Element = {
@@ -1971,7 +3567,7 @@
$(element).select();
return element;
}
-}
+};
Form.Element.Methods = {
serialize: function(element) {
@@ -1979,9 +3575,9 @@
if (!element.disabled && element.name) {
var value = element.getValue();
if (value != undefined) {
- var pair = {};
+ var pair = { };
pair[element.name] = value;
- return Hash.toQueryString(pair);
+ return Object.toQueryString(pair);
}
}
return '';
@@ -1993,6 +3589,13 @@
return Form.Element.Serializers[method](element);
},
+ setValue: function(element, value) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ Form.Element.Serializers[method](element, value);
+ return element;
+ },
+
clear: function(element) {
$(element).value = '';
return element;
@@ -2004,10 +3607,12 @@
activate: function(element) {
element = $(element);
- element.focus();
- if (element.select && ( element.tagName.toLowerCase() != 'input' ||
- !['button', 'reset', 'submit'].include(element.type) ) )
- element.select();
+ try {
+ element.focus();
+ if (element.select && (element.tagName.toLowerCase() != 'input' ||
+ !['button', 'reset', 'submit'].include(element.type)))
+ element.select();
+ } catch (e) { }
return element;
},
@@ -2019,40 +3624,57 @@
enable: function(element) {
element = $(element);
- element.blur();
element.disabled = false;
return element;
}
-}
+};
-Object.extend(Form.Element, Form.Element.Methods);
+/*--------------------------------------------------------------------------*/
+
var Field = Form.Element;
-var $F = Form.Element.getValue;
+var $F = Form.Element.Methods.getValue;
/*--------------------------------------------------------------------------*/
Form.Element.Serializers = {
- input: function(element) {
+ input: function(element, value) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
- return Form.Element.Serializers.inputSelector(element);
+ return Form.Element.Serializers.inputSelector(element, value);
default:
- return Form.Element.Serializers.textarea(element);
+ return Form.Element.Serializers.textarea(element, value);
}
},
- inputSelector: function(element) {
- return element.checked ? element.value : null;
+ inputSelector: function(element, value) {
+ if (Object.isUndefined(value)) return element.checked ? element.value : null;
+ else element.checked = !!value;
},
- textarea: function(element) {
- return element.value;
+ textarea: function(element, value) {
+ if (Object.isUndefined(value)) return element.value;
+ else element.value = value;
},
- select: function(element) {
- return this[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
+ select: function(element, value) {
+ if (Object.isUndefined(value))
+ return this[element.type == 'select-one' ?
+ 'selectOne' : 'selectMany'](element);
+ else {
+ var opt, currentValue, single = !Object.isArray(value);
+ for (var i = 0, length = element.length; i < length; i++) {
+ opt = element.options[i];
+ currentValue = this.optionValue(opt);
+ if (single) {
+ if (currentValue == value) {
+ opt.selected = true;
+ return;
+ }
+ }
+ else opt.selected = value.include(currentValue);
+ }
+ }
},
selectOne: function(element) {
@@ -2075,45 +3697,34 @@
// extend element because hasAttribute may not be native
return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
-}
+};
/*--------------------------------------------------------------------------*/
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
+Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
+ initialize: function($super, element, frequency, callback) {
+ $super(callback, frequency);
this.element = $(element);
- this.callback = callback;
-
this.lastValue = this.getValue();
- this.registerCallback();
},
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
+ execute: function() {
var value = this.getValue();
- var changed = ('string' == typeof this.lastValue && 'string' == typeof value
- ? this.lastValue != value : String(this.lastValue) != String(value));
- if (changed) {
+ if (Object.isString(this.lastValue) && Object.isString(value) ?
+ this.lastValue != value : String(this.lastValue) != String(value)) {
this.callback(this.element, value);
this.lastValue = value;
}
}
-}
+});
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+Form.Element.Observer = Class.create(Abstract.TimedObserver, {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+Form.Observer = Class.create(Abstract.TimedObserver, {
getValue: function() {
return Form.serialize(this.element);
}
@@ -2121,8 +3732,7 @@
/*--------------------------------------------------------------------------*/
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
+Abstract.EventObserver = Class.create({
initialize: function(element, callback) {
this.element = $(element);
this.callback = callback;
@@ -2143,7 +3753,7 @@
},
registerFormCallbacks: function() {
- Form.getElements(this.element).each(this.registerCallback.bind(this));
+ Form.getElements(this.element).each(this.registerCallback, this);
},
registerCallback: function(element) {
@@ -2159,24 +3769,20 @@
}
}
}
-}
+});
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+Form.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {
return Form.serialize(this.element);
}
});
-if (!window.Event) {
- var Event = new Object();
-}
+if (!window.Event) var Event = { };
Object.extend(Event, {
KEY_BACKSPACE: 8,
@@ -2192,102 +3798,368 @@
KEY_END: 35,
KEY_PAGEUP: 33,
KEY_PAGEDOWN: 34,
+ KEY_INSERT: 45,
- element: function(event) {
- return event.target || event.srcElement;
- },
+ cache: { },
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
+ relatedTarget: function(event) {
+ var element;
+ switch(event.type) {
+ case 'mouseover': element = event.fromElement; break;
+ case 'mouseout': element = event.toElement; break;
+ default: return null;
+ }
+ return Element.extend(element);
+ }
+});
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
+Event.Methods = (function() {
+ var isButton;
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
+ if (Prototype.Browser.IE) {
+ var buttonMap = { 0: 1, 1: 4, 2: 2 };
+ isButton = function(event, code) {
+ return event.button == buttonMap[code];
+ };
- stop: function(event) {
- if (event.preventDefault) {
+ } else if (Prototype.Browser.WebKit) {
+ isButton = function(event, code) {
+ switch (code) {
+ case 0: return event.which == 1 && !event.metaKey;
+ case 1: return event.which == 1 && event.metaKey;
+ default: return false;
+ }
+ };
+
+ } else {
+ isButton = function(event, code) {
+ return event.which ? (event.which === code + 1) : (event.button === code);
+ };
+ }
+
+ return {
+ isLeftClick: function(event) { return isButton(event, 0) },
+ isMiddleClick: function(event) { return isButton(event, 1) },
+ isRightClick: function(event) { return isButton(event, 2) },
+
+ element: function(event) {
+ event = Event.extend(event);
+
+ var node = event.target,
+ type = event.type,
+ currentTarget = event.currentTarget;
+
+ if (currentTarget && currentTarget.tagName) {
+ // Firefox screws up the "click" event when moving between radio buttons
+ // via arrow keys. It also screws up the "load" and "error" events on images,
+ // reporting the document as the target instead of the original image.
+ if (type === 'load' || type === 'error' ||
+ (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
+ && currentTarget.type === 'radio'))
+ node = currentTarget;
+ }
+ if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
+ return Element.extend(node);
+ },
+
+ findElement: function(event, _expression_) {
+ var element = Event.element(event);
+ if (!_expression_) return element;
+ var elements = [element].concat(element.ancestors());
+ return Selector.findElement(elements, _expression_, 0);
+ },
+
+ pointer: function(event) {
+ var docElement = document.documentElement,
+ body = document.body || { scrollLeft: 0, scrollTop: 0 };
+ return {
+ x: event.pageX || (event.clientX +
+ (docElement.scrollLeft || body.scrollLeft) -
+ (docElement.clientLeft || 0)),
+ y: event.pageY || (event.clientY +
+ (docElement.scrollTop || body.scrollTop) -
+ (docElement.clientTop || 0))
+ };
+ },
+
+ pointerX: function(event) { return Event.pointer(event).x },
+ pointerY: function(event) { return Event.pointer(event).y },
+
+ stop: function(event) {
+ Event.extend(event);
event.preventDefault();
event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
+ event.stopped = true;
}
- },
+ };
+})();
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
+Event.extend = (function() {
+ var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+ m[name] = Event.Methods[name].methodize();
+ return m;
+ });
- observers: false,
+ if (Prototype.Browser.IE) {
+ Object.extend(methods, {
+ stopPropagation: function() { this.cancelBubble = true },
+ preventDefault: function() { this.returnValue = false },
+ inspect: function() { return "[object Event]" }
+ });
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
+ return function(event) {
+ if (!event) return false;
+ if (event._extendedByPrototype) return event;
+
+ event._extendedByPrototype = Prototype.emptyFunction;
+ var pointer = Event.pointer(event);
+ Object.extend(event, {
+ target: event.srcElement,
+ relatedTarget: Event.relatedTarget(event),
+ pageX: pointer.x,
+ pageY: pointer.y
+ });
+ return Object.extend(event, methods);
+ };
+
+ } else {
+ Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
+ Object.extend(Event.prototype, methods);
+ return Prototype.K;
+ }
+})();
+
+Object.extend(Event, (function() {
+ var cache = Event.cache;
+
+ function getEventID(element) {
+ if (element._prototypeEventID) return element._prototypeEventID[0];
+ arguments.callee.id = arguments.callee.id || 1;
+ return element._prototypeEventID = [++arguments.callee.id];
+ }
+
+ function getDOMEventName(eventName) {
+ if (eventName && eventName.include(':')) return "dataavailable";
+ return eventName;
+ }
+
+ function getCacheForID(id) {
+ return cache[id] = cache[id] || { };
+ }
+
+ function getWrappersForEventName(id, eventName) {
+ var c = getCacheForID(id);
+ return c[eventName] = c[eventName] || [];
+ }
+
+ function createWrapper(element, eventName, handler) {
+ var id = getEventID(element);
+ var c = getWrappersForEventName(id, eventName);
+ if (c.pluck("handler").include(handler)) return false;
+
+ var wrapper = function(event) {
+ if (!Event || !Event.extend ||
+ (event.eventName && event.eventName != eventName))
+ return false;
+
+ Event.extend(event);
+ handler.call(element, event);
+ };
+
+ wrapper.handler = handler;
+ c.push(wrapper);
+ return wrapper;
+ }
+
+ function findWrapper(id, eventName, handler) {
+ var c = getWrappersForEventName(id, eventName);
+ return c.find(function(wrapper) { return wrapper.handler == handler });
+ }
+
+ function destroyWrapper(id, eventName, handler) {
+ var c = getCacheForID(id);
+ if (!c[eventName]) return false;
+ c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+ }
+
+ function destroyCache() {
+ for (var id in cache)
+ for (var eventName in cache[id])
+ cache[id][eventName] = null;
+ }
+
+
+ // Internet Explorer needs to remove event handlers on page unload
+ // in order to avoid memory leaks.
+ if (window.attachEvent) {
+ window.attachEvent("onunload", destroyCache);
+ }
+
+ // Safari has a dummy event handler on page unload so that it won't
+ // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
+ // object when page is returned to via the back button using its bfcache.
+ if (Prototype.Browser.WebKit) {
+ window.addEventListener('unload', Prototype.emptyFunction, false);
+ }
+
+ return {
+ observe: function(element, eventName, handler) {
+ element = $(element);
+ var name = getDOMEventName(eventName);
+
+ var wrapper = createWrapper(element, eventName, handler);
+ if (!wrapper) return element;
+
+ if (element.addEventListener) {
+ element.addEventListener(name, wrapper, false);
+ } else {
+ element.attachEvent("on" + name, wrapper);
+ }
+
+ return element;
+ },
+
+ stopObserving: function(element, eventName, handler) {
+ element = $(element);
+ var id = getEventID(element), name = getDOMEventName(eventName);
+
+ if (!handler && eventName) {
+ getWrappersForEventName(id, eventName).each(function(wrapper) {
+ element.stopObserving(eventName, wrapper.handler);
+ });
+ return element;
+
+ } else if (!eventName) {
+ Object.keys(getCacheForID(id)).each(function(eventName) {
+ element.stopObserving(eventName);
+ });
+ return element;
+ }
+
+ var wrapper = findWrapper(id, eventName, handler);
+ if (!wrapper) return element;
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, wrapper, false);
+ } else {
+ element.detachEvent("on" + name, wrapper);
+ }
+
+ destroyWrapper(id, eventName, handler);
+
+ return element;
+ },
+
+ fire: function(element, eventName, memo) {
+ element = $(element);
+ if (element == document && document.createEvent && !element.dispatchEvent)
+ element = document.documentElement;
+
+ var event;
+ if (document.createEvent) {
+ event = document.createEvent("HTMLEvents");
+ event.initEvent("dataavailable", true, true);
+ } else {
+ event = document.createEventObject();
+ event.eventType = "ondataavailable";
+ }
+
+ event.eventName = eventName;
+ event.memo = memo || { };
+
+ if (document.createEvent) {
+ element.dispatchEvent(event);
+ } else {
+ element.fireEvent(event.eventType, event);
+ }
+
+ return Event.extend(event);
}
- },
+ };
+})());
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0, length = Event.observers.length; i < length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
+Object.extend(Event, Event.Methods);
+
+Element.addMethods({
+ fire: Event.fire,
+ observe: Event.observe,
+ stopObserving: Event.stopObserving
+});
+
+Object.extend(document, {
+ fire: Element.Methods.fire.methodize(),
+ observe: Element.Methods.observe.methodize(),
+ stopObserving: Element.Methods.stopObserving.methodize(),
+ loaded: false
+});
+
+(function() {
+ /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+ Matthias Miller, Dean Edwards and John Resig. */
+
+ var timer;
+
+ function fireContentLoadedEvent() {
+ if (document.loaded) return;
+ if (timer) window.clearInterval(timer);
+ document.fire("dom:loaded");
+ document.loaded = true;
+ }
+
+ if (document.addEventListener) {
+ if (Prototype.Browser.WebKit) {
+ timer = window.setInterval(function() {
+ if (/loaded|complete/.test(document.readyState))
+ fireContentLoadedEvent();
+ }, 0);
+
+ Event.observe(window, "load", fireContentLoadedEvent);
+
+ } else {
+ document.addEventListener("DOMContentLoaded",
+ fireContentLoadedEvent, false);
}
- Event.observers = false;
- },
- observe: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
+ } else {
+ document.write("<script id=__onDOMContentLoaded defer src=""
+ $("__onDOMContentLoaded"). {
+ if (this.readyState == "complete") {
+ this.
+ fireContentLoadedEvent();
+ }
+ };
+ }
+})();
+/*------------------------------- DEPRECATED -------------------------------*/
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.attachEvent))
- name = 'keydown';
+Hash.toQueryString = Object.toQueryString;
- Event._observeAndCache(element, name, observer, useCapture);
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+ Before: function(element, content) {
+ return Element.insert(element, {before:content});
},
- stopObserving: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
+ Top: function(element, content) {
+ return Element.insert(element, {top:content});
+ },
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.detachEvent))
- name = 'keydown';
+ Bottom: function(element, content) {
+ return Element.insert(element, {bottom:content});
+ },
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- try {
- element.detachEvent('on' + name, observer);
- } catch (e) {}
- }
+ After: function(element, content) {
+ return Element.insert(element, {after:content});
}
-});
+};
-/* prevent memory leaks in IE */
-if (navigator.appVersion.match(/\bMSIE\b/))
- Event.observe(window, 'unload', Event.unloadCache, false);
+var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+// This should be moved to script.aculo.us; notice the deprecated methods
+// further below, that map to the newer Element methods.
var Position = {
// set to true if needed, warning: firefox performance problems
// NOT neeeded for page scrolling, only if draggable contained in
@@ -2307,59 +4179,13 @@
|| 0;
},
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- if(element.tagName=='BODY') break;
- var p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
// caches x/y coordinate pair to use with overlap
within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
this.xcomp = x;
this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
+ this.offset = Element.cumulativeOffset(element);
return (y >= this.offset[1] &&
y < this.offset[1] + element.offsetHeight &&
@@ -2368,11 +4194,11 @@
},
withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
+ var offsetcache = Element.cumulativeScrollOffset(element);
this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
+ this.offset = Element.cumulativeOffset(element);
return (this.ycomp >= this.offset[1] &&
this.ycomp < this.offset[1] + element.offsetHeight &&
@@ -2391,125 +4217,104 @@
element.offsetWidth;
},
- page: function(forElement) {
- var valueT = 0, valueL = 0;
+ // Deprecation layer -- use newer Element methods now (1.5.2).
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
+ cumulativeOffset: Element.Methods.cumulativeOffset,
- // Safari fix
- if (element.offsetParent==document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
+ positionedOffset: Element.Methods.positionedOffset,
- } while (element = element.offsetParent);
+ absolutize: function(element) {
+ Position.prepare();
+ return Element.absolutize(element);
+ },
- element = forElement;
- do {
- if (!window.opera || element.tagName=='BODY') {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- }
- } while (element = element.parentNode);
-
- return [valueL, valueT];
+ relativize: function(element) {
+ Position.prepare();
+ return Element.relativize(element);
},
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
+ realOffset: Element.Methods.cumulativeScrollOffset,
- // find page position of source
- source = $(source);
- var p = Position.page(source);
+ offsetParent: Element.Methods.getOffsetParent,
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
+ page: Element.Methods.viewportOffset,
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
+ clone: function(source, target, options) {
+ options = options || { };
+ return Element.clonePosition(target, source, options);
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
+ function iter(name) {
+ return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+ }
+
+ instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+ function(element, className) {
+ className = className.toString().strip();
+ var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+ return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+ } : function(element, className) {
+ className = className.toString().strip();
+ var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+ if (!classNames && !className) return elements;
+
+ var nodes = $(element).getElementsByTagName('*');
+ className = ' ' + className + ' ';
+
+ for (var i = 0, child, cn; child = nodes[i]; i++) {
+ if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+ (classNames && classNames.all(function(name) {
+ return !name.toString().blank() && cn.include(' ' + name + ' ');
+ }))))
+ elements.push(Element.extend(child));
}
+ return elements;
+ };
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
+ return function(className, parentElement) {
+ return $(parentElement || document.body).getElementsByClassName(className);
+ };
+}(Element.Methods);
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
+/*--------------------------------------------------------------------------*/
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+ initialize: function(element) {
+ this.element = $(element);
+ },
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
+ _each: function(iterator) {
+ this.element.className.split(/\s+/).select(function(name) {
+ return name.length > 0;
+ })._each(iterator);
+ },
- element.style.position = 'absolute';
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.width = width + 'px';
- element.style.height = height + 'px';
+ set: function(className) {
+ this.element.className = className;
},
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
+ add: function(classNameToAdd) {
+ if (this.include(classNameToAdd)) return;
+ this.set($A(this).concat(classNameToAdd).join(' '));
+ },
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+ remove: function(classNameToRemove) {
+ if (!this.include(classNameToRemove)) return;
+ this.set($A(this).without(classNameToRemove).join(' '));
+ },
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
+ toString: function() {
+ return $A(this).join(' ');
}
-}
+};
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
+Object.extend(Element.ClassNames.prototype, Enumerable);
- element = element.offsetParent;
- } while (element);
+/*--------------------------------------------------------------------------*/
- return [valueL, valueT];
- }
-}
-
Element.addMethods();
\ No newline at end of file
Modified: branches/datasets/public/stylesheets/styles.css (2857 => 2858)
--- branches/datasets/public/stylesheets/styles.css 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/public/stylesheets/styles.css 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1886,6 +1886,10 @@
#packItems .user {
}
+.deletedPackItem {
+ color: gray;
+}
+
table.quick_add {
border-collapse: collapse;
width: 99%;
Modified: branches/datasets/script/about (2857 => 2858)
--- branches/datasets/script/about 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/about 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,4 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/about'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
+require 'commands/about'
Deleted: branches/datasets/script/breakpointer (2857 => 2858)
--- branches/datasets/script/breakpointer 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/breakpointer 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/breakpointer'
\ No newline at end of file
Modified: branches/datasets/script/console (2857 => 2858)
--- branches/datasets/script/console 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/console 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/console'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+require 'commands/console'
Modified: branches/datasets/script/destroy (2857 => 2858)
--- branches/datasets/script/destroy 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/destroy 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/destroy'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+require 'commands/destroy'
Modified: branches/datasets/script/generate (2857 => 2858)
--- branches/datasets/script/generate 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/generate 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/generate'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+require 'commands/generate'
Modified: branches/datasets/script/performance/benchmarker (2857 => 2858)
--- branches/datasets/script/performance/benchmarker 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/performance/benchmarker 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
+require File.expand_path('../../../config/boot', __FILE__)
require 'commands/performance/benchmarker'
Modified: branches/datasets/script/performance/profiler (2857 => 2858)
--- branches/datasets/script/performance/profiler 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/performance/profiler 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
+require File.expand_path('../../../config/boot', __FILE__)
require 'commands/performance/profiler'
Modified: branches/datasets/script/plugin (2857 => 2858)
--- branches/datasets/script/plugin 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/plugin 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/plugin'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+require 'commands/plugin'
Modified: branches/datasets/script/runner (2857 => 2858)
--- branches/datasets/script/runner 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/runner 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/runner'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+require 'commands/runner'
Modified: branches/datasets/script/server (2857 => 2858)
--- branches/datasets/script/server 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/script/server 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/server'
\ No newline at end of file
+require File.expand_path('../../config/boot', __FILE__)
+require 'commands/server'
Modified: branches/datasets/test/functional/announcements_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/announcements_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/announcements_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,18 +1,11 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'announcements_controller'
-# Re-raise errors caught by the controller.
-class AnnouncementsController; def rescue_action(e) raise e end; end
-
-class AnnouncementsControllerTest < Test::Unit::TestCase
+class AnnouncementsControllerTest < ActionController::TestCase
fixtures :announcements
fixtures :users
def setup
- @controller = AnnouncementsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
-
@first_id = announcements(:first_announcement).id
end
@@ -38,7 +31,7 @@
assert_response :redirect
assert_equal "Only administrators have access to create, update and delete announcements.", flash[:error]
- follow_redirect
+ get :index
assert_response :success
assert_template 'index'
end
@@ -50,7 +43,7 @@
assert_response :redirect
assert_equal "Only administrators have access to create, update and delete announcements.", flash[:error]
- follow_redirect
+ get :index
assert_response :success
assert_template 'index'
end
Modified: branches/datasets/test/functional/api_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/api_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/api_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,19 +6,16 @@
include ActionView::Helpers::UrlHelper
include ActionController::UrlWriter
-# Re-raise errors caught by the controller.
-class ApiController; def rescue_action(e) raise e end; end
+class ApiControllerTest < ActionController::TestCase
-class ApiControllerTest < Test::Unit::TestCase
-
- fixtures :workflows, :users, :content_types, :licenses, :ontologies, :predicates, :packs
-
def setup
@controller = ApiController.new
@request = TestRequestWithQuery.new
@response = ActionController::TestResponse.new
end
+ fixtures :workflows, :users, :content_types, :licenses, :ontologies, :predicates, :packs
+
def test_workflows
existing_workflows = Workflow.find(:all)
Modified: branches/datasets/test/functional/authorization_test.rb (2857 => 2858)
--- branches/datasets/test/functional/authorization_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/authorization_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,10 +6,7 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'workflows_controller'
-# Re-raise errors caught by the controller.
-class WorkflowsController; def rescue_action(e) raise e end; end
-
-class AuthorizationTest < Test::Unit::TestCase
+class AuthorizationTest < ActionController::TestCase
fixtures :workflows, :users, :contributions, :workflow_versions, :content_blobs, :blobs, :packs, :policies, :permissions, :networks, :friendships, :memberships, :licenses
def test_truth
Modified: branches/datasets/test/functional/blobs_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/blobs_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/blobs_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'blobs_controller'
-# Re-raise errors caught by the controller.
-class BlobsController; def rescue_action(e) raise e end; end
-
-class BlobsControllerTest < Test::Unit::TestCase
+class BlobsControllerTest < ActionController::TestCase
fixtures :blobs, :users, :contributions, :content_blobs, :workflows, :packs, :policies, :permissions, :networks, :content_types
- def setup
- @controller = BlobsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
get :index
assert_response :success
Modified: branches/datasets/test/functional/blog_posts_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/blog_posts_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/blog_posts_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,11 +6,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'blog_posts_controller'
-# Re-raise errors caught by the controller.
-class BlogPostsController; def rescue_action(e) raise e end; end
+class BlogPostsControllerTest < ActionController::TestCase
-class BlogPostsControllerTest < Test::Unit::TestCase
-
def test_true
assert true
end
Modified: branches/datasets/test/functional/blogs_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/blogs_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/blogs_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,11 +6,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'blogs_controller'
-# Re-raise errors caught by the controller.
-class BlogsController; def rescue_action(e) raise e end; end
+class BlogsControllerTest < ActionController::TestCase
-class BlogsControllerTest < Test::Unit::TestCase
-
def test_true
assert true
end
Modified: branches/datasets/test/functional/bookmarks_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/bookmarks_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/bookmarks_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,16 +6,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'bookmarks_controller'
-# Re-raise errors caught by the controller.
-class BookmarksController; def rescue_action(e) raise e end; end
+class BookmarksControllerTest < ActionController::TestCase
-class BookmarksControllerTest < Test::Unit::TestCase
- def setup
- @controller = BookmarksController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/citations_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/citations_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/citations_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,18 +1,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'citations_controller'
-# Re-raise errors caught by the controller.
-class CitationsController; def rescue_action(e) raise e end; end
-
-class CitationsControllerTest < Test::Unit::TestCase
+class CitationsControllerTest < ActionController::TestCase
fixtures :citations, :workflows, :workflow_versions, :content_blobs, :users, :contributions, :blobs, :packs, :policies, :permissions
- def setup
- @controller = CitationsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
login_as(:john)
get :index, :workflow_id => '1'
Modified: branches/datasets/test/functional/experiments_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/experiments_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/experiments_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,17 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'experiments_controller'
-# Re-raise errors caught by the controller.
-class ExperimentsController; def rescue_action(e) raise e end; end
-
-class ExperimentsControllerTest < Test::Unit::TestCase
+class ExperimentsControllerTest < ActionController::TestCase
fixtures :experiments, :users
def setup
- @controller = ExperimentsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
-
@first_id = experiments(:experiment_1).id
end
Modified: branches/datasets/test/functional/feedback_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/feedback_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/feedback_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'feedback_controller'
-# Re-raise errors caught by the controller.
-class FeedbackController; def rescue_action(e) raise e end; end
+class FeedbackControllerTest < ActionController::TestCase
-class FeedbackControllerTest < Test::Unit::TestCase
- def setup
- @controller = FeedbackController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/friendships_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/friendships_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/friendships_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'friendships_controller'
-# Re-raise errors caught by the controller.
-class FriendshipsController; def rescue_action(e) raise e end; end
-
-class FriendshipsControllerTest < Test::Unit::TestCase
+class FriendshipsControllerTest < ActionController::TestCase
fixtures :friendships, :users, :profiles
- def setup
- @controller = FriendshipsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
login_as(:john)
get :index, :user_id => users(:john).id
Modified: branches/datasets/test/functional/group_announcements_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/group_announcements_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/group_announcements_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,18 +1,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'group_announcements_controller'
-# Re-raise errors caught by the controller.
-class GroupAnnouncementsController; def rescue_action(e) raise e end; end
-
-class GroupAnnouncementsControllerTest < Test::Unit::TestCase
+class GroupAnnouncementsControllerTest < ActionController::TestCase
fixtures :group_announcements, :networks, :users
- def setup
- @controller = GroupAnnouncementsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
get :index, :group_id => networks(:dilbert_appreciation_network).id
assert_response :success
Modified: branches/datasets/test/functional/home_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/home_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/home_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,7 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'home_controller'
-# Re-raise errors caught by the controller.
-class HomeController; def rescue_action(e) raise e end; end
-
-class HomeControllerTest < Test::Unit::TestCase
- def setup
- @controller = HomeController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
+class HomeControllerTest < ActionController::TestCase
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/jobs_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/jobs_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/jobs_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,18 +1,11 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'jobs_controller'
-# Re-raise errors caught by the controller.
-class JobsController; def rescue_action(e) raise e end; end
-
# tests should be uncommented and fixed when fixture data for jobs is available
-class JobsControllerTest < Test::Unit::TestCase
+class JobsControllerTest < ActionController::TestCase
fixtures :jobs
def setup
- @controller = JobsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
-
# no fixtures for jobs currently
address@hidden = jobs(:first).id
end
Modified: branches/datasets/test/functional/key_permissions_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/key_permissions_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/key_permissions_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,7 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'key_permissions_controller'
-# Re-raise errors caught by the controller.
-class KeyPermissionsController; def rescue_action(e) raise e end; end
-
-class KeyPermissionsControllerTest < Test::Unit::TestCase
- def setup
- @controller = KeyPermissionsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
+class KeyPermissionsControllerTest < ActionController::TestCase
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/license_attributes_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/license_attributes_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/license_attributes_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'license_attributes_controller'
-# Re-raise errors caught by the controller.
-class LicenseAttributesController; def rescue_action(e) raise e end; end
+class LicenseAttributesControllerTest < ActionController::TestCase
-class LicenseAttributesControllerTest < Test::Unit::TestCase
- def setup
- @controller = LicenseAttributesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/licenses_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/licenses_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/licenses_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'licenses_controller'
-# Re-raise errors caught by the controller.
-class LicensesController; def rescue_action(e) raise e end; end
+class LicensesControllerTest < ActionController::TestCase
-class LicensesControllerTest < Test::Unit::TestCase
- def setup
- @controller = LicensesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/mashup_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/mashup_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/mashup_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'mashup_controller'
-# Re-raise errors caught by the controller.
-class MashupController; def rescue_action(e) raise e end; end
+class MashupControllerTest < ActionController::TestCase
-class MashupControllerTest < Test::Unit::TestCase
- def setup
- @controller = MashupController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/memberships_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/memberships_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/memberships_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'memberships_controller'
-# Re-raise errors caught by the controller.
-class MembershipsController; def rescue_action(e) raise e end; end
-
-class MembershipsControllerTest < Test::Unit::TestCase
+class MembershipsControllerTest < ActionController::TestCase
fixtures :memberships, :users, :networks
- def setup
- @controller = MembershipsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
login_as(:john)
get :index, :user_id => users(:john).id
Modified: branches/datasets/test/functional/messages_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/messages_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/messages_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'messages_controller'
-# Re-raise errors caught by the controller.
-class MessagesController; def rescue_action(e) raise e end; end
-
-class MessagesControllerTest < Test::Unit::TestCase
+class MessagesControllerTest < ActionController::TestCase
fixtures :messages, :users
- def setup
- @controller = MessagesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
login_as(:john)
get :index
Modified: branches/datasets/test/functional/networks_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/networks_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/networks_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'networks_controller'
-# Re-raise errors caught by the controller.
-class NetworksController; def rescue_action(e) raise e end; end
-
-class NetworksControllerTest < Test::Unit::TestCase
+class NetworksControllerTest < ActionController::TestCase
fixtures :networks, :users, :content_types
- def setup
- @controller = NetworksController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
get :index
assert_response :success
Modified: branches/datasets/test/functional/openid_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/openid_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/openid_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,17 +1,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'openid_controller'
-# Re-raise errors caught by the controller.
-class OpenidController; def rescue_action(e) raise e end; end
-
# NOTE: if you get the message 'undefined method `require_gem' for main:Object (NoMethodError)'
# when running these tests, change 'require_gem' to 'gem' in openid_controller
-class OpenidControllerTest < Test::Unit::TestCase
- def setup
- @controller = OpenidController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
+class OpenidControllerTest < ActionController::TestCase
# Replace this with your real tests.
def test_truth
Modified: branches/datasets/test/functional/packs_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/packs_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/packs_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,17 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'packs_controller'
-# Re-raise errors caught by the controller.
-class PacksController; def rescue_action(e) raise e end; end
-
-class PacksControllerTest < Test::Unit::TestCase
+class PacksControllerTest < ActionController::TestCase
fixtures :packs, :users, :contributions, :workflows, :blobs, :content_blobs, :policies, :permissions, :networks
def setup
- @controller = PacksController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
-
@first_id = packs(:pack_1).id
end
Modified: branches/datasets/test/functional/pictures_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/pictures_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/pictures_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'pictures_controller'
-# Re-raise errors caught by the controller.
-class PicturesController; def rescue_action(e) raise e end; end
-
-class PicturesControllerTest < Test::Unit::TestCase
+class PicturesControllerTest < ActionController::TestCase
fixtures :pictures, :users, :picture_selections, :profiles
- def setup
- @controller = PicturesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
login_as(:john)
get :index, :user_id => users(:john).id
Modified: branches/datasets/test/functional/profiles_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/profiles_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/profiles_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'profiles_controller'
-# Re-raise errors caught by the controller.
-class ProfilesController; def rescue_action(e) raise e end; end
-
-class ProfilesControllerTest < Test::Unit::TestCase
+class ProfilesControllerTest < ActionController::TestCase
fixtures :profiles, :users, :pictures, :picture_selections
- def setup
- @controller = ProfilesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
get :index
assert_response :success
Modified: branches/datasets/test/functional/reviews_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/reviews_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/reviews_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,17 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'reviews_controller'
-# Re-raise errors caught by the controller.
-class ReviewsController; def rescue_action(e) raise e end; end
-
-class ReviewsControllerTest < Test::Unit::TestCase
+class ReviewsControllerTest < ActionController::TestCase
fixtures :reviews, :users, :workflows, :workflow_versions, :contributions, :blobs, :packs, :policies, :permissions, :content_types
def setup
- @controller = ReviewsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
-
@first_id = reviews(:dilbert_review).id
end
@@ -45,14 +38,17 @@
def test_create
num_reviews = Review.count
+ existing_reviews = Review.find(:all)
login_as(:john)
post :create, :review => { :title => 'my review', :review => 'very good, well done' }, :workflow_id => reviews(:dilbert_review).reviewable_id
- assert_response :redirect
- assert_redirected_to :action ="" 'show'
-
assert_equal num_reviews + 1, Review.count
+
+ review = (Review.find(:all) - existing_reviews).first
+
+ assert_response :redirect
+ assert_redirected_to workflow_review_path(reviews(:dilbert_review).reviewable_id, review)
end
def test_edit
Modified: branches/datasets/test/functional/runners_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/runners_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/runners_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,17 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'runners_controller'
-# Re-raise errors caught by the controller.
-class RunnersController; def rescue_action(e) raise e end; end
-
-class RunnersControllerTest < Test::Unit::TestCase
+class RunnersControllerTest < ActionController::TestCase
fixtures :taverna_enactors, :users
def setup
- @controller = RunnersController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
-
@first_id = taverna_enactors(:taverna_enactor_1).id
end
Modified: branches/datasets/test/functional/search_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/search_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/search_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'search_controller'
-# Re-raise errors caught by the controller.
-class SearchController; def rescue_action(e) raise e end; end
+class SearchControllerTest < ActionController::TestCase
-class SearchControllerTest < Test::Unit::TestCase
- def setup
- @controller = SearchController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Deleted: branches/datasets/test/functional/session_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/session_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/session_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,23 +0,0 @@
-# myExperiment: test/functional/session_controller_test.rb
-#
-# Copyright (c) 2007 University of Manchester and the University of Southampton.
-# See license.txt for details.
-
-require File.dirname(__FILE__) + '/../test_helper'
-require 'session_controller'
-
-# Re-raise errors caught by the controller.
-class SessionController; def rescue_action(e) raise e end; end
-
-class SessionControllerTest < Test::Unit::TestCase
- def setup
- @controller = SessionController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
Copied: branches/datasets/test/functional/sessions_controller_test.rb (from rev 2857, trunk/test/functional/sessions_controller_test.rb) (0 => 2858)
--- branches/datasets/test/functional/sessions_controller_test.rb (rev 0)
+++ branches/datasets/test/functional/sessions_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -0,0 +1,15 @@
+# myExperiment: test/functional/sessions_controller_test.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+require File.dirname(__FILE__) + '/../test_helper'
+require 'sessions_controller'
+
+class SessionsControllerTest < ActionController::TestCase
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Modified: branches/datasets/test/functional/status_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/status_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/status_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'status_controller'
-# Re-raise errors caught by the controller.
-class StatusController; def rescue_action(e) raise e end; end
+class StatusControllerTest < ActionController::TestCase
-class StatusControllerTest < Test::Unit::TestCase
- def setup
- @controller = StatusController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/tags_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/tags_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/tags_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,16 +6,8 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'tags_controller'
-# Re-raise errors caught by the controller.
-class TagsController; def rescue_action(e) raise e end; end
+class TagsControllerTest < ActionController::TestCase
-class TagsControllerTest < Test::Unit::TestCase
- def setup
- @controller = TagsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
# Replace this with your real tests.
def test_truth
assert true
Modified: branches/datasets/test/functional/users_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/users_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/users_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'users_controller'
-# Re-raise errors caught by the controller.
-class UsersController; def rescue_action(e) raise e end; end
-
-class UsersControllerTest < Test::Unit::TestCase
+class UsersControllerTest < ActionController::TestCase
fixtures :users, :profiles
- def setup
- @controller = UsersController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
get :index
assert_response :success
Modified: branches/datasets/test/functional/workflows_controller_test.rb (2857 => 2858)
--- branches/datasets/test/functional/workflows_controller_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/functional/workflows_controller_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,18 +6,9 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'workflows_controller'
-# Re-raise errors caught by the controller.
-class WorkflowsController; def rescue_action(e) raise e end; end
-
-class WorkflowsControllerTest < Test::Unit::TestCase
+class WorkflowsControllerTest < ActionController::TestCase
fixtures :workflows, :users, :contributions, :workflow_versions, :content_blobs, :blobs, :packs, :policies, :permissions, :networks, :content_types
- def setup
- @controller = WorkflowsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
def test_should_get_index
get :index
assert_response :success
Modified: branches/datasets/test/test_helper.rb (2857 => 2858)
--- branches/datasets/test/test_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/test_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,11 +1,8 @@
-# Setting RAILS_ENV to 'test' causes a crash.
ENV["RAILS_ENV"] = "test"
-
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
-
require 'test_help'
-class Test::Unit::TestCase
+class ActiveSupport::TestCase
# Transactional fixtures accelerate your tests by wrapping each test method
# in a transaction that's rolled back on completion. This ensures that the
# test database remains unchanged so your fixtures don't have to be reloaded
@@ -18,6 +15,10 @@
# in MySQL. Turn off transactional fixtures in this case; however, if you
# don't care one way or the other, switching from MyISAM to InnoDB tables
# is recommended.
+ #
+ # The only drawback to using transactional fixtures is when you actually
+ # need to test transactions. Since your test is bracketed by a transaction,
+ # any transactions started in your code will be automatically rolled back.
self.use_transactional_fixtures = true
# Instantiated fixtures are slow, but give you @david where otherwise you
@@ -27,9 +28,31 @@
# then set this back to true.
self.use_instantiated_fixtures = false
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
+ #
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
+ # -- they do not yet inherit this setting
+ fixtures :all
+
# Add more helper methods to be used by all tests here...
def login_as(user)
@request.session[:user_id] = user ? users(user).id : nil
end
end
+
+if Rails::VERSION::MAJOR > 1
+ module ActionController
+ module UrlWriter
+
+ alias_method :original_url_for, :url_for
+
+ def url_for(options)
+ options[:host] = "test.host"
+ original_url_for(options)
+ end
+
+ end
+ end
+end
+
Modified: branches/datasets/test/unit/activity_limit_test.rb (2857 => 2858)
--- branches/datasets/test/unit/activity_limit_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/activity_limit_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ActivityLimitTest < Test::Unit::TestCase
+class ActivityLimitTest < ActiveSupport::TestCase
fixtures :activity_limits
# Replace this with your real tests.
Modified: branches/datasets/test/unit/announcement_test.rb (2857 => 2858)
--- branches/datasets/test/unit/announcement_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/announcement_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class AnnouncementTest < Test::Unit::TestCase
+class AnnouncementTest < ActiveSupport::TestCase
fixtures :announcements
# Replace this with your real tests.
Modified: branches/datasets/test/unit/authorisation_test.rb (2857 => 2858)
--- branches/datasets/test/unit/authorisation_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/authorisation_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class AuthorisationTest < Test::Unit::TestCase
+class AuthorisationTest < ActiveSupport::TestCase
fixtures :workflows
fixtures :blobs
fixtures :contributions
Modified: branches/datasets/test/unit/blob_test.rb (2857 => 2858)
--- branches/datasets/test/unit/blob_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/blob_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class BlobTest < Test::Unit::TestCase
+class BlobTest < ActiveSupport::TestCase
fixtures :blobs
# Replace this with your real tests.
Modified: branches/datasets/test/unit/blog_post_test.rb (2857 => 2858)
--- branches/datasets/test/unit/blog_post_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/blog_post_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class BlogPostTest < Test::Unit::TestCase
+class BlogPostTest < ActiveSupport::TestCase
fixtures :blog_posts
# Replace this with your real tests.
Modified: branches/datasets/test/unit/blog_test.rb (2857 => 2858)
--- branches/datasets/test/unit/blog_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/blog_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class BlogTest < Test::Unit::TestCase
+class BlogTest < ActiveSupport::TestCase
fixtures :blogs
# Replace this with your real tests.
Modified: branches/datasets/test/unit/citation_test.rb (2857 => 2858)
--- branches/datasets/test/unit/citation_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/citation_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class CitationTest < Test::Unit::TestCase
+class CitationTest < ActiveSupport::TestCase
fixtures :citations
# Replace this with your real tests.
Modified: branches/datasets/test/unit/content_blob_test.rb (2857 => 2858)
--- branches/datasets/test/unit/content_blob_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/content_blob_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ContentBlobTest < Test::Unit::TestCase
+class ContentBlobTest < ActiveSupport::TestCase
fixtures :content_blobs
# Replace this with your real tests.
Modified: branches/datasets/test/unit/contribution_test.rb (2857 => 2858)
--- branches/datasets/test/unit/contribution_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/contribution_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ContributionTest < Test::Unit::TestCase
+class ContributionTest < ActiveSupport::TestCase
fixtures :contributions
# Replace this with your real tests.
Modified: branches/datasets/test/unit/contributions_test.rb (2857 => 2858)
--- branches/datasets/test/unit/contributions_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/contributions_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ContributionsTest < Test::Unit::TestCase
+class ContributionsTest < ActiveSupport::TestCase
fixtures :contributions
# Replace this with your real tests.
Modified: branches/datasets/test/unit/download_test.rb (2857 => 2858)
--- branches/datasets/test/unit/download_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/download_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class DownloadTest < Test::Unit::TestCase
+class DownloadTest < ActiveSupport::TestCase
fixtures :downloads
# Replace this with your real tests.
Modified: branches/datasets/test/unit/experiment_test.rb (2857 => 2858)
--- branches/datasets/test/unit/experiment_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/experiment_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ExperimentTest < Test::Unit::TestCase
+class ExperimentTest < ActiveSupport::TestCase
fixtures :experiments
# Replace this with your real tests.
Modified: branches/datasets/test/unit/friendship_test.rb (2857 => 2858)
--- branches/datasets/test/unit/friendship_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/friendship_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class FriendshipTest < Test::Unit::TestCase
+class FriendshipTest < ActiveSupport::TestCase
fixtures :friendships
# Replace this with your real tests.
Modified: branches/datasets/test/unit/group_announcement_test.rb (2857 => 2858)
--- branches/datasets/test/unit/group_announcement_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/group_announcement_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class GroupAnnouncementTest < Test::Unit::TestCase
+class GroupAnnouncementTest < ActiveSupport::TestCase
fixtures :group_announcements
# Replace this with your real tests.
Modified: branches/datasets/test/unit/job_test.rb (2857 => 2858)
--- branches/datasets/test/unit/job_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/job_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class JobTest < Test::Unit::TestCase
+class JobTest < ActiveSupport::TestCase
fixtures :jobs
# Replace this with your real tests.
Modified: branches/datasets/test/unit/key_permission_test.rb (2857 => 2858)
--- branches/datasets/test/unit/key_permission_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/key_permission_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class KeyPermissionTest < Test::Unit::TestCase
+class KeyPermissionTest < ActiveSupport::TestCase
fixtures :key_permissions
# Replace this with your real tests.
Modified: branches/datasets/test/unit/license_attribute_test.rb (2857 => 2858)
--- branches/datasets/test/unit/license_attribute_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/license_attribute_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class LicenseAttributeTest < Test::Unit::TestCase
+class LicenseAttributeTest < ActiveSupport::TestCase
fixtures :license_attributes
# Replace this with your real tests.
Modified: branches/datasets/test/unit/license_option_test.rb (2857 => 2858)
--- branches/datasets/test/unit/license_option_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/license_option_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class LicenseOptionTest < Test::Unit::TestCase
+class LicenseOptionTest < ActiveSupport::TestCase
fixtures :license_options
# Replace this with your real tests.
Modified: branches/datasets/test/unit/license_test.rb (2857 => 2858)
--- branches/datasets/test/unit/license_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/license_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class LicenseTest < Test::Unit::TestCase
+class LicenseTest < ActiveSupport::TestCase
fixtures :licenses
# Replace this with your real tests.
Modified: branches/datasets/test/unit/mailer_test.rb (2857 => 2858)
--- branches/datasets/test/unit/mailer_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/mailer_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class MailerTest < Test::Unit::TestCase
+class MailerTest < ActiveSupport::TestCase
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures'
CHARSET = "utf-8"
Modified: branches/datasets/test/unit/membership_test.rb (2857 => 2858)
--- branches/datasets/test/unit/membership_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/membership_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class MembershipTest < Test::Unit::TestCase
+class MembershipTest < ActiveSupport::TestCase
fixtures :memberships
# Replace this with your real tests.
Modified: branches/datasets/test/unit/message_test.rb (2857 => 2858)
--- branches/datasets/test/unit/message_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/message_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class MessageTest < Test::Unit::TestCase
+class MessageTest < ActiveSupport::TestCase
fixtures :messages
# Replace this with your real tests.
Modified: branches/datasets/test/unit/network_test.rb (2857 => 2858)
--- branches/datasets/test/unit/network_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/network_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class NetworkTest < Test::Unit::TestCase
+class NetworkTest < ActiveSupport::TestCase
fixtures :networks
# Replace this with your real tests.
Modified: branches/datasets/test/unit/pack_contributable_entries_test.rb (2857 => 2858)
--- branches/datasets/test/unit/pack_contributable_entries_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/pack_contributable_entries_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PackContributableEntriesTest < Test::Unit::TestCase
+class PackContributableEntriesTest < ActiveSupport::TestCase
fixtures :pack_contributable_entries
# Replace this with your real tests.
Modified: branches/datasets/test/unit/pack_remote_entries_test.rb (2857 => 2858)
--- branches/datasets/test/unit/pack_remote_entries_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/pack_remote_entries_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PackRemoteEntriesTest < Test::Unit::TestCase
+class PackRemoteEntriesTest < ActiveSupport::TestCase
fixtures :pack_remote_entries
# Replace this with your real tests.
Modified: branches/datasets/test/unit/pack_test.rb (2857 => 2858)
--- branches/datasets/test/unit/pack_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/pack_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PackTest < Test::Unit::TestCase
+class PackTest < ActiveSupport::TestCase
fixtures :packs
# Replace this with your real tests.
Modified: branches/datasets/test/unit/pending_invitation_test.rb (2857 => 2858)
--- branches/datasets/test/unit/pending_invitation_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/pending_invitation_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PendingInvitationTest < Test::Unit::TestCase
+class PendingInvitationTest < ActiveSupport::TestCase
fixtures :pending_invitations
# Replace this with your real tests.
Modified: branches/datasets/test/unit/permission_test.rb (2857 => 2858)
--- branches/datasets/test/unit/permission_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/permission_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PermissionTest < Test::Unit::TestCase
+class PermissionTest < ActiveSupport::TestCase
fixtures :permissions
# Replace this with your real tests.
Modified: branches/datasets/test/unit/picture_selection_test.rb (2857 => 2858)
--- branches/datasets/test/unit/picture_selection_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/picture_selection_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PictureSelectionTest < Test::Unit::TestCase
+class PictureSelectionTest < ActiveSupport::TestCase
fixtures :picture_selections
# Replace this with your real tests.
Modified: branches/datasets/test/unit/picture_test.rb (2857 => 2858)
--- branches/datasets/test/unit/picture_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/picture_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PictureTest < Test::Unit::TestCase
+class PictureTest < ActiveSupport::TestCase
fixtures :pictures
# Replace this with your real tests.
Modified: branches/datasets/test/unit/policy_test.rb (2857 => 2858)
--- branches/datasets/test/unit/policy_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/policy_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class PolicyTest < Test::Unit::TestCase
+class PolicyTest < ActiveSupport::TestCase
fixtures :policies
# Replace this with your real tests.
Modified: branches/datasets/test/unit/profile_test.rb (2857 => 2858)
--- branches/datasets/test/unit/profile_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/profile_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ProfileTest < Test::Unit::TestCase
+class ProfileTest < ActiveSupport::TestCase
fixtures :profiles
# Replace this with your real tests.
Modified: branches/datasets/test/unit/remote_workflow_test.rb (2857 => 2858)
--- branches/datasets/test/unit/remote_workflow_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/remote_workflow_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class RemoteWorkflowTest < Test::Unit::TestCase
+class RemoteWorkflowTest < ActiveSupport::TestCase
fixtures :remote_workflows
# Replace this with your real tests.
Modified: branches/datasets/test/unit/review_test.rb (2857 => 2858)
--- branches/datasets/test/unit/review_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/review_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ReviewTest < Test::Unit::TestCase
+class ReviewTest < ActiveSupport::TestCase
fixtures :reviews
# Replace this with your real tests.
Modified: branches/datasets/test/unit/taverna_enactor_test.rb (2857 => 2858)
--- branches/datasets/test/unit/taverna_enactor_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/taverna_enactor_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class TavernaEnactorTest < Test::Unit::TestCase
+class TavernaEnactorTest < ActiveSupport::TestCase
fixtures :taverna_enactors
# Replace this with your real tests.
Modified: branches/datasets/test/unit/user_test.rb (2857 => 2858)
--- branches/datasets/test/unit/user_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/user_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class UserTest < Test::Unit::TestCase
+class UserTest < ActiveSupport::TestCase
fixtures :users
# Replace this with your real tests.
Modified: branches/datasets/test/unit/viewing_test.rb (2857 => 2858)
--- branches/datasets/test/unit/viewing_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/viewing_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class ViewingTest < Test::Unit::TestCase
+class ViewingTest < ActiveSupport::TestCase
fixtures :viewings
# Replace this with your real tests.
Modified: branches/datasets/test/unit/workflow_test.rb (2857 => 2858)
--- branches/datasets/test/unit/workflow_test.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/test/unit/workflow_test.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../test_helper'
-class WorkflowTest < Test::Unit::TestCase
+class WorkflowTest < ActiveSupport::TestCase
fixtures :workflows
# Replace this with your real tests.
Deleted: branches/datasets/vendor/plugins/acts_as_bookmarkable/tasks/acts_as_bookmarkable_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/acts_as_bookmarkable/tasks/acts_as_bookmarkable_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/acts_as_bookmarkable/tasks/acts_as_bookmarkable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :acts_as_bookmarkable do
-# # Task goes here
-# end
\ No newline at end of file
Deleted: branches/datasets/vendor/plugins/acts_as_commentable/tasks/acts_as_commentable_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/acts_as_commentable/tasks/acts_as_commentable_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/acts_as_commentable/tasks/acts_as_commentable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :acts_as_commentable do
-# # Task goes here
-# end
\ No newline at end of file
Deleted: branches/datasets/vendor/plugins/acts_as_rateable/tasks/acts_as_rateable_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/acts_as_rateable/tasks/acts_as_rateable_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/acts_as_rateable/tasks/acts_as_rateable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :acts_as_rateable do
-# # Task goes here
-# end
\ No newline at end of file
Deleted: branches/datasets/vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,19 +0,0 @@
-namespace :acts_as_taggable do
- require 'rails_generator'
- require 'rails_generator/scripts/generate'
-
- namespace :db do
- desc "Creates tag tables for use with acts_as_taggable"
- task :create => :environment do
- raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
- Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_tables", "add_acts_as_taggable_tables" ])
- end
- end
-
- namespace :stylesheet do
- desc "Create tag stylesheet for use with acts_as_taggable"
- task :create do
- Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_stylesheet" ])
- end
- end
-end
\ No newline at end of file
Modified: branches/datasets/vendor/plugins/fckeditor/app/controllers/fckeditor_controller.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/fckeditor/app/controllers/fckeditor_controller.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/fckeditor/app/controllers/fckeditor_controller.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -17,7 +17,7 @@
xml.instruct!
#=> <?xml version="1.0" encoding="utf-8" ?>
xml.Connector("command" => params[:Command], "resourceType" => 'File') do
- xml.CurrentFolder("url" => @url, "path" => params[:CurrentFolder])
+ xml.CurrentFolder("url" => @uurl, "path" => params[:CurrentFolder])
xml.Folders do
@folders.each do |folder|
xml.Folder("name" => folder)
@@ -49,7 +49,7 @@
@folders = Array.new
@files = {}
begin
- @url = ""
+ @uurl = upload_directory_path
@current_folder = current_directory_path
Dir.entries(@current_folder).each do |entry|
next if entry =~ /^\./
@@ -64,9 +64,9 @@
def create_folder
begin
- @url = ""
- path = @url + params[:NewFolderName]
- if !(File.stat(@url).writable?)
+ @uurl = current_directory_path
+ path = @uurl + params[:NewFolderName]
+ if !(File.stat(@uurl).writable?)
@errorNumber = 103
elsif params[:NewFolderName] !~ /[\w\d\s]+/
@errorNumber = 102
@@ -84,7 +84,7 @@
def upload_file
begin
@new_file = check_file(params[:NewFile])
- @url = ""
+ @uurl = upload_directory_path
ftype = @new_file.content_type.strip
if ! MIME_TYPES.include?(ftype)
@errorNumber = 202
@@ -133,7 +133,7 @@
end
def upload_directory_path
- uploaded = request.relative_url_root.to_s+"#{UPLOADED}/#{params[:Type]}"
+ uploaded = ActionController::Base.relative_url_root.to_s+"#{UPLOADED}/#{params[:Type]}"
"#{uploaded}#{params[:CurrentFolder]}"
end
Modified: branches/datasets/vendor/plugins/fckeditor/init.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/fckeditor/init.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/fckeditor/init.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -6,7 +6,7 @@
FckeditorFileUtils.check_and_install
# make plugin controller available to app
-config.load_paths += %W(#{Fckeditor::PLUGIN_CONTROLLER_PATH} #{Fckeditor::PLUGIN_HELPER_PATH})
+config.autoload_paths += %W(#{Fckeditor::PLUGIN_CONTROLLER_PATH} #{Fckeditor::PLUGIN_HELPER_PATH})
Rails::Initializer.run(:set_load_path, config)
Modified: branches/datasets/vendor/plugins/fckeditor/lib/fckeditor.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/fckeditor/lib/fckeditor.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/fckeditor/lib/fckeditor.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -35,7 +35,7 @@
inputs = "<textarea id='#{id}' #{cols} #{rows} name='#{object}[#{field}]'>#{value}</textarea>\n"
end
- js_path = "#{request.relative_url_root}/_javascript_s"
+ js_path = "#{ActionController::Base.relative_url_root}/_javascript_s"
base_path = "#{js_path}/fckeditor/"
return inputs <<
_javascript__tag("var oFCKeditor = new FCKeditor('#{id}', '#{width}', '#{height}', '#{toolbarSet}');\n" <<
@@ -81,21 +81,21 @@
end
end
-include ActionView
-module ActionView::Helpers::AssetTagHelper
- alias_method :rails_javascript_include_tag, :_javascript__include_tag
-
- # <%= _javascript__include_tag :defaults, :fckeditor %>
- def _javascript__include_tag(*sources)
- main_sources, application_source = [], []
- if sources.include?(:fckeditor)
- sources.delete(:fckeditor)
- sources.push('fckeditor/fckeditor')
- end
- unless sources.empty?
- main_sources = rails_javascript_include_tag(*sources).split("\n")
- application_source = main_sources.pop if main_sources.last.include?('application.js')
- end
- [main_sources.join("\n"), application_source].join("\n")
- end
-end
+# include ActionView
+# module ActionView::Helpers::AssetTagHelper
+# alias_method :rails_javascript_include_tag, :_javascript__include_tag
+#
+# # <%= _javascript__include_tag :defaults, :fckeditor %>
+# def _javascript__include_tag(*sources)
+# main_sources, application_source = [], []
+# if sources.include?(:fckeditor)
+# sources.delete(:fckeditor)
+# sources.push('fckeditor/fckeditor')
+# end
+# unless sources.empty?
+# main_sources = rails_javascript_include_tag(*sources).split("\n")
+# application_source = main_sources.pop if main_sources.last.include?('application.js')
+# end
+# [main_sources.join("\n"), application_source].join("\n")
+# end
+# end
Deleted: branches/datasets/vendor/plugins/fckeditor/tasks/fckeditor_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/fckeditor/tasks/fckeditor_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/fckeditor/tasks/fckeditor_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,97 +0,0 @@
-# desc "Explaining what the task does"
-# task :fckeditor do
-# # Task goes here
-# end
-
-namespace :fckeditor do
- def setup
- require "config/environment"
- require 'fileutils'
-
- directory = File.join(RAILS_ROOT, '/vendor/plugins/fckeditor/')
- require "#{directory}lib/fckeditor"
- require "#{directory}lib/fckeditor_version"
- require "#{directory}lib/fckeditor_file_utils"
- end
-
- desc 'Install the FCKEditor components'
- task :install do
- setup
- puts "** Installing FCKEditor Plugin version #{FckeditorVersion.current}..."
-
- FckeditorFileUtils.destroy_and_install
-
- puts "** Successfully installed FCKEditor Plugin version #{FckeditorVersion.current}"
- end
-
- def fetch(path)
- response = Net::HTTP.get_response(URI.parse(path))
- case response
- when Net::HTTPSuccess then
- response
- when Net::HTTPRedirection then
- puts "** Redirected to #{response['location']}"
- fetch(response['location'])
- else
- response.error!
- end
- end
-
- desc "Update the FCKEditor code to the latest nightly build"
- task :download do
- require 'net/http'
- require 'zip/zipfilesystem'
-
- setup
- version = ENV['VERSION'] || "Nightly"
- installed_version = "2.4.2"
-
- puts "** Current FCKEditor version: #{installed_version}..."
- puts "** Downloading #{version} (1.2mb - please be patient)..."
-
- rails_tmp_path = File.join(RAILS_ROOT, "/tmp/")
- tmp_zip_path = File.join(rails_tmp_path, "fckeditor_#{version}.zip")
-
- # Creating tmp dir if it doesn't exist
- Dir.mkdir(rails_tmp_path) unless File.exists? rails_tmp_path
-
- # Download nightly build (http://www.fckeditor.net/nightly/FCKeditor_N.zip)
- # Releases (http://downloads.sourgefourge.net/fckeditor/FCKEditor_[2.4.3, 2.5b, 2.4.2].zip)
- nightly = version=='Nightly' ? true : false
- domain = nightly ? "http://www.fckeditor.net" : "http://downloads.sourceforge.net"
- path = nightly ? "/nightly/FCKeditor_N.zip" : "/fckeditor/FCKeditor_#{version}.zip"
-
- puts "** Download from #{domain}#{path}"
- #Net::HTTP.start(domain) { |http|
- response = fetch("#{domain}#{path}")
-
- open(tmp_zip_path, "wb") { |file|
- file.write(response.body)
- }
- #}
- puts "** Download successful"
-
- puts "** Extracting FCKeditor"
- Zip::ZipFile.open(tmp_zip_path) do |zipfile|
- zipfile.each do |entry|
- filename = File.join(rails_tmp_path, entry.name)
- FileUtils.rm_f(filename)
- FileUtils.mkdir_p(File.dirname(filename))
- entry.extract(filename)
- end
- end
-
- puts "** Backing up existing FCKEditor install to /public/_javascript_s/fckeditor_bck"
- FckeditorFileUtils.backup_existing
-
- puts "** Shifting files to /public/_javascript_s/fckeditor"
- FileUtils.cp_r File.join(RAILS_ROOT, "/tmp/fckeditor/"), File.join(RAILS_ROOT, "/public/_javascript_s/")
-
- puts "** Clean up"
- FileUtils.remove_file(tmp_zip_path, true)
- FileUtils.remove_entry(File.join(rails_tmp_path, "fckeditor/"), true)
-
- puts "** Successfully updated to FCKEditor version: #{version}..."
- end
-end
-
Deleted: branches/datasets/vendor/plugins/oauth_plugin/tasks/oauth_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/oauth_plugin/tasks/oauth_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/oauth_plugin/tasks/oauth_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :oauth do
-# # Task goes here
-# end
Deleted: branches/datasets/vendor/plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,16 +0,0 @@
-namespace :open_id_authentication do
- namespace :db do
- desc "Creates authentication tables for use with OpenIdAuthentication"
- task :create => :environment do
- raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
- require 'rails_generator'
- require 'rails_generator/scripts/generate'
- Rails::Generator::Scripts::Generate.new.run([ "open_id_authentication_tables", "add_open_id_authentication_tables" ])
- end
-
- desc "Clear the authentication tables"
- task :clear => :environment do
- OpenIdAuthentication::DbStore.gc
- end
- end
-end
\ No newline at end of file
Deleted: branches/datasets/vendor/plugins/qrcode/tasks/qrcode_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/qrcode/tasks/qrcode_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/qrcode/tasks/qrcode_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :qrcode do
-# # Task goes here
-# end
\ No newline at end of file
Deleted: branches/datasets/vendor/plugins/recaptcha/tasks/recaptcha_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/recaptcha/tasks/recaptcha_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/recaptcha/tasks/recaptcha_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :recaptcha do
-# # Task goes here
-# end
\ No newline at end of file
Deleted: branches/datasets/vendor/plugins/structured_data/tasks/structured_data_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/structured_data/tasks/structured_data_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/structured_data/tasks/structured_data_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :structured_data do
-# # Task goes here
-# end
Deleted: branches/datasets/vendor/plugins/validates_captcha/tasks/validates_captcha_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/validates_captcha/tasks/validates_captcha_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/validates_captcha/tasks/validates_captcha_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :validates_captcha do
-# # Task goes here
-# end
\ No newline at end of file
Modified: branches/datasets/vendor/plugins/validates_email_veracity_of/test/rails_root/config/environment.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/validates_email_veracity_of/test/rails_root/config/environment.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/validates_email_veracity_of/test/rails_root/config/environment.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -5,7 +5,7 @@
config.cache_classes = false
config.whiny_nils = true
config.breakpoint_server = true
- config.load_paths << "#{File.dirname(__FILE__)}/../../../lib/"
+ autoload_paths << "#{File.dirname(__FILE__)}/../../../lib/"
end
Dependencies.log_activity = true
Modified: branches/datasets/vendor/plugins/white_list/lib/white_list_helper.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/white_list/lib/white_list_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/white_list/lib/white_list_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -56,34 +56,37 @@
attrs = Set.new(options[:attributes]).merge(white_listed_attributes)
tags = Set.new(options[:tags] ).merge(white_listed_tags)
block ||= lambda { |node, bad| white_listed_bad_tags.include?(bad) ? nil : node.to_s.gsub(/</, '<') }
- returning [] do |new_text|
- tokenizer = HTML::Tokenizer.new(html)
- bad = nil
- while token = tokenizer.next
- node = HTML::Node.parse(nil, 0, 0, token, false)
- new_text << case node
- when HTML::Tag
- node.attributes.keys.each do |attr_name|
- value = node.attributes[attr_name].to_s
- if !attrs.include?(attr_name) || (protocol_attributes.include?(attr_name) && contains_bad_protocols?(value))
- node.attributes.delete(attr_name)
- else
- node.attributes[attr_name] = value
- end
- end if node.attributes
- node.attributes['rel'] = 'nofollow' if node.name == 'a' and node.attributes != nil
- if tags.include?(node.name)
- bad = nil
- node
+
+ new_text = []
+
+ tokenizer = HTML::Tokenizer.new(html)
+ bad = nil
+ while token = tokenizer.next
+ node = HTML::Node.parse(nil, 0, 0, token, false)
+ new_text << case node
+ when HTML::Tag
+ node.attributes.keys.each do |attr_name|
+ value = node.attributes[attr_name].to_s
+ if !attrs.include?(attr_name) || (protocol_attributes.include?(attr_name) && contains_bad_protocols?(value))
+ node.attributes.delete(attr_name)
else
- bad = node.name
- block.call node, bad
+ node.attributes[attr_name] = value
end
+ end if node.attributes
+ node.attributes['rel'] = 'nofollow' if node.name == 'a' and node.attributes != nil
+ if tags.include?(node.name)
+ bad = nil
+ node
else
+ bad = node.name
block.call node, bad
- end
+ end
+ else
+ block.call node, bad
end
- end.join
+ end
+
+ new_text.join
end
protected
Modified: branches/datasets/vendor/plugins/widgets/lib/widgets/navigation_helper.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/widgets/lib/widgets/navigation_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/widgets/lib/widgets/navigation_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -51,7 +51,7 @@
out '</ul>'
end
- def out(string); concat string, @_binding; end
+ def out(string); concat string; end
end
end
Modified: branches/datasets/vendor/plugins/widgets/lib/widgets/showhide_helper.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/widgets/lib/widgets/showhide_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/widgets/lib/widgets/showhide_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -17,7 +17,7 @@
# Crea un div di dettagli per un record
def detail_for record, &block
- concat(render_default_css, block.binding) unless @_showhide_css_done
+ concat(render_default_css) unless @_showhide_css_done
div_for(record, 'detail_for', :style => 'display: none;', :class => 'detail', &block)
@_showhide_css_done = true # prevents to print the CSS multiple times
nil
Modified: branches/datasets/vendor/plugins/widgets/lib/widgets/table_helper.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/widgets/lib/widgets/table_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/widgets/lib/widgets/table_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -59,7 +59,7 @@
_out << content_tag('td', ' ', :class => 'blank')
end unless remaining == 0
_out << '</tr>' << '</tbody>' << '</table>'
- concat(_out, block.binding)
+ concat(_out)
nil # avoid duplication if called with <%= %>
end
@@ -71,4 +71,4 @@
end
end
-end
\ No newline at end of file
+end
Modified: branches/datasets/vendor/plugins/widgets/lib/widgets/tabnav_helper.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/widgets/lib/widgets/tabnav_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/widgets/lib/widgets/tabnav_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -23,7 +23,7 @@
html << tag('div', options, true)
html << capture(&block)
html << '</div>'
- concat( html, block.binding)
+ concat(html)
nil # avoid duplication if called with <%= %>
else
return html
@@ -110,7 +110,7 @@
out '</ul>'
end
- def out(string); concat string, @_binding; end
+ def out(string); concat string; end
# generate _javascript_ function to use
# while loading remote tabs
Modified: branches/datasets/vendor/plugins/widgets/lib/widgets/tooltip_helper.rb (2857 => 2858)
--- branches/datasets/vendor/plugins/widgets/lib/widgets/tooltip_helper.rb 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/widgets/lib/widgets/tooltip_helper.rb 2011-12-01 14:16:25 UTC (rev 2858)
@@ -18,7 +18,7 @@
result << render_tooltip(name, tooltip_content(opts,&proc), opts)
if block_given?
- concat result, proc.binding;
+ concat result;
return nil
else
return result
Deleted: branches/datasets/vendor/plugins/widgets/tasks/widgets_tasks.rake (2857 => 2858)
--- branches/datasets/vendor/plugins/widgets/tasks/widgets_tasks.rake 2011-12-01 13:48:30 UTC (rev 2857)
+++ branches/datasets/vendor/plugins/widgets/tasks/widgets_tasks.rake 2011-12-01 14:16:25 UTC (rev 2858)
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :widgets do
-# # Task goes here
-# end
\ No newline at end of file