From cd6d95204f735a5ad8eb9b9ca01ddfed0b0ac405 Mon Sep 17 00:00:00 2001 From: Christophe Vilayphiou Date: Fri, 27 Jul 2012 19:12:39 +0800 Subject: [PATCH] Move Impressionist to Gemfile --- Gemfile | 4 +- Gemfile.lock | 5 +- vendor/impressionist/.gitignore | 10 - vendor/impressionist/.rspec | 1 - vendor/impressionist/.travis.yml | 11 - vendor/impressionist/CHANGELOG.rdoc | 19 - vendor/impressionist/LICENSE.txt | 20 - vendor/impressionist/README.md | 198 - vendor/impressionist/Rakefile | 21 - .../controllers/impressionist_controller.rb | 103 - vendor/impressionist/app/models/impression.rb | 3 - .../app/models/impressionist/bots.rb | 1468 ---- vendor/impressionist/impressionist.gemspec | 27 - .../active_record/impressionist_generator.rb | 21 - .../templates/create_impressions_table.rb | 30 - .../mongo_mapper/impressionist_generator.rb | 8 - .../mongoid/impressionist_generator.rb | 8 - vendor/impressionist/lib/impressionist.rb | 12 - .../impressionist/lib/impressionist/bots.rb | 18 - .../models/active_record/impression.rb | 18 - .../impressionist/impressionable.rb | 12 - .../models/mongo_mapper/impression.rb | 16 - .../impressionist/impressionable.rb | 12 - .../lib/impressionist/version.rb | 3 - vendor/impressionist/logo.png | Bin 63294 -> 0 bytes vendor/impressionist/test_app/.gitignore | 17 - vendor/impressionist/test_app/.rspec | 1 - vendor/impressionist/test_app/Gemfile | 59 - vendor/impressionist/test_app/README | 256 - vendor/impressionist/test_app/README.rdoc | 261 - vendor/impressionist/test_app/Rakefile | 7 - .../test_app/app/assets/images/rails.png | Bin 6646 -> 0 bytes .../app/assets/javascripts/application.js | 15 - .../app/assets/stylesheets/application.css | 13 - .../app/controllers/application_controller.rb | 8 - .../app/controllers/articles_controller.rb | 18 - .../app/controllers/dummy_controller.rb | 6 - .../app/controllers/posts_controller.rb | 23 - .../app/controllers/widgets_controller.rb | 12 - .../app/helpers/application_helper.rb | 2 - .../test_app/app/mailers/.gitkeep | 0 .../test_app/app/models/.gitkeep | 0 .../test_app/app/models/article.rb | 3 - .../test_app/app/models/dummy.rb | 7 - .../impressionist/test_app/app/models/post.rb | 3 - .../impressionist/test_app/app/models/user.rb | 3 - .../test_app/app/models/widget.rb | 3 - .../app/views/articles/index.html.erb | 1 - .../test_app/app/views/articles/show.html.erb | 1 - .../app/views/layouts/application.html.erb | 14 - .../test_app/app/views/posts/edit.html.erb | 0 .../test_app/app/views/posts/index.html.erb | 0 .../test_app/app/views/posts/show.html.erb | 0 .../test_app/app/views/widgets/index.html.erb | 0 .../test_app/app/views/widgets/new.html.erb | 0 .../test_app/app/views/widgets/show.html.erb | 0 vendor/impressionist/test_app/config.ru | 4 - .../test_app/config/application.rb | 59 - vendor/impressionist/test_app/config/boot.rb | 6 - .../test_app/config/cucumber.yml | 8 - .../test_app/config/database.yml | 30 - .../test_app/config/environment.rb | 5 - .../config/environments/development.rb | 37 - .../test_app/config/environments/pg_test.rb | 35 - .../config/environments/production.rb | 67 - .../test_app/config/environments/test.rb | 37 - .../initializers/backtrace_silencers.rb | 7 - .../config/initializers/impression.rb | 5 - .../config/initializers/inflections.rb | 15 - .../config/initializers/mime_types.rb | 5 - .../config/initializers/secret_token.rb | 7 - .../config/initializers/session_store.rb | 8 - .../config/initializers/wrap_parameters.rb | 14 - .../test_app/config/locales/en.yml | 5 - .../impressionist/test_app/config/routes.rb | 3 - .../migrate/20110201153144_create_articles.rb | 13 - .../db/migrate/20110210205028_create_posts.rb | 13 - .../migrate/20111127184039_create_widgets.rb | 15 - vendor/impressionist/test_app/db/seeds.rb | 7 - .../test_app/lib/assets/.gitkeep | 0 .../impressionist/test_app/lib/tasks/.gitkeep | 0 .../test_app/lib/tasks/cucumber.rake | 53 - vendor/impressionist/test_app/log/.gitkeep | 0 vendor/impressionist/test_app/public/404.html | 26 - vendor/impressionist/test_app/public/422.html | 26 - vendor/impressionist/test_app/public/500.html | 25 - .../impressionist/test_app/public/favicon.ico | 0 .../test_app/public/images/rails.png | Bin 6646 -> 0 bytes .../impressionist/test_app/public/index.html | 241 - .../public/javascripts/application.js | 2 - .../test_app/public/javascripts/controls.js | 965 --- .../test_app/public/javascripts/dragdrop.js | 974 --- .../test_app/public/javascripts/effects.js | 1123 --- .../test_app/public/javascripts/prototype.js | 6001 ----------------- .../test_app/public/javascripts/rails.js | 175 - .../impressionist/test_app/public/robots.txt | 5 - .../test_app/public/stylesheets/.gitkeep | 0 vendor/impressionist/test_app/script/cucumber | 10 - vendor/impressionist/test_app/script/rails | 6 - .../spec/controllers/controller_spec.rb | 125 - .../impressionist_uniqueness_spec.rb | 310 - .../test_app/spec/fixtures/articles.yml | 3 - .../test_app/spec/fixtures/impressions.yml | 43 - .../test_app/spec/fixtures/posts.yml | 3 - .../test_app/spec/fixtures/widgets.yml | 4 - .../spec/initializers/initializers_spec.rb | 18 - .../test_app/spec/models/bots_spec.rb | 27 - .../test_app/spec/models/model_spec.rb | 94 - .../rails_generators/rails_generators_spec.rb | 23 - .../test_app/spec/spec_helper.rb | 36 - .../upgrade_migrations/version_0_3_0.rb | 27 - .../upgrade_migrations/version_0_4_0.rb | 9 - .../upgrade_migrations/version_1_1_2.rb | 9 - 113 files changed, 6 insertions(+), 13543 deletions(-) delete mode 100644 vendor/impressionist/.gitignore delete mode 100644 vendor/impressionist/.rspec delete mode 100644 vendor/impressionist/.travis.yml delete mode 100644 vendor/impressionist/CHANGELOG.rdoc delete mode 100644 vendor/impressionist/LICENSE.txt delete mode 100644 vendor/impressionist/README.md delete mode 100644 vendor/impressionist/Rakefile delete mode 100644 vendor/impressionist/app/controllers/impressionist_controller.rb delete mode 100644 vendor/impressionist/app/models/impression.rb delete mode 100644 vendor/impressionist/app/models/impressionist/bots.rb delete mode 100644 vendor/impressionist/impressionist.gemspec delete mode 100644 vendor/impressionist/lib/generators/active_record/impressionist_generator.rb delete mode 100644 vendor/impressionist/lib/generators/active_record/templates/create_impressions_table.rb delete mode 100644 vendor/impressionist/lib/generators/mongo_mapper/impressionist_generator.rb delete mode 100644 vendor/impressionist/lib/generators/mongoid/impressionist_generator.rb delete mode 100644 vendor/impressionist/lib/impressionist.rb delete mode 100644 vendor/impressionist/lib/impressionist/bots.rb delete mode 100644 vendor/impressionist/lib/impressionist/models/active_record/impression.rb delete mode 100644 vendor/impressionist/lib/impressionist/models/active_record/impressionist/impressionable.rb delete mode 100644 vendor/impressionist/lib/impressionist/models/mongo_mapper/impression.rb delete mode 100644 vendor/impressionist/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb delete mode 100644 vendor/impressionist/lib/impressionist/version.rb delete mode 100644 vendor/impressionist/logo.png delete mode 100644 vendor/impressionist/test_app/.gitignore delete mode 100644 vendor/impressionist/test_app/.rspec delete mode 100644 vendor/impressionist/test_app/Gemfile delete mode 100644 vendor/impressionist/test_app/README delete mode 100644 vendor/impressionist/test_app/README.rdoc delete mode 100644 vendor/impressionist/test_app/Rakefile delete mode 100644 vendor/impressionist/test_app/app/assets/images/rails.png delete mode 100644 vendor/impressionist/test_app/app/assets/javascripts/application.js delete mode 100644 vendor/impressionist/test_app/app/assets/stylesheets/application.css delete mode 100644 vendor/impressionist/test_app/app/controllers/application_controller.rb delete mode 100644 vendor/impressionist/test_app/app/controllers/articles_controller.rb delete mode 100644 vendor/impressionist/test_app/app/controllers/dummy_controller.rb delete mode 100644 vendor/impressionist/test_app/app/controllers/posts_controller.rb delete mode 100644 vendor/impressionist/test_app/app/controllers/widgets_controller.rb delete mode 100644 vendor/impressionist/test_app/app/helpers/application_helper.rb delete mode 100644 vendor/impressionist/test_app/app/mailers/.gitkeep delete mode 100644 vendor/impressionist/test_app/app/models/.gitkeep delete mode 100644 vendor/impressionist/test_app/app/models/article.rb delete mode 100644 vendor/impressionist/test_app/app/models/dummy.rb delete mode 100644 vendor/impressionist/test_app/app/models/post.rb delete mode 100644 vendor/impressionist/test_app/app/models/user.rb delete mode 100644 vendor/impressionist/test_app/app/models/widget.rb delete mode 100644 vendor/impressionist/test_app/app/views/articles/index.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/articles/show.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/layouts/application.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/posts/edit.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/posts/index.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/posts/show.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/widgets/index.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/widgets/new.html.erb delete mode 100644 vendor/impressionist/test_app/app/views/widgets/show.html.erb delete mode 100644 vendor/impressionist/test_app/config.ru delete mode 100644 vendor/impressionist/test_app/config/application.rb delete mode 100644 vendor/impressionist/test_app/config/boot.rb delete mode 100644 vendor/impressionist/test_app/config/cucumber.yml delete mode 100644 vendor/impressionist/test_app/config/database.yml delete mode 100644 vendor/impressionist/test_app/config/environment.rb delete mode 100644 vendor/impressionist/test_app/config/environments/development.rb delete mode 100644 vendor/impressionist/test_app/config/environments/pg_test.rb delete mode 100644 vendor/impressionist/test_app/config/environments/production.rb delete mode 100644 vendor/impressionist/test_app/config/environments/test.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/backtrace_silencers.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/impression.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/inflections.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/mime_types.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/secret_token.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/session_store.rb delete mode 100644 vendor/impressionist/test_app/config/initializers/wrap_parameters.rb delete mode 100644 vendor/impressionist/test_app/config/locales/en.yml delete mode 100644 vendor/impressionist/test_app/config/routes.rb delete mode 100644 vendor/impressionist/test_app/db/migrate/20110201153144_create_articles.rb delete mode 100644 vendor/impressionist/test_app/db/migrate/20110210205028_create_posts.rb delete mode 100644 vendor/impressionist/test_app/db/migrate/20111127184039_create_widgets.rb delete mode 100644 vendor/impressionist/test_app/db/seeds.rb delete mode 100644 vendor/impressionist/test_app/lib/assets/.gitkeep delete mode 100644 vendor/impressionist/test_app/lib/tasks/.gitkeep delete mode 100644 vendor/impressionist/test_app/lib/tasks/cucumber.rake delete mode 100644 vendor/impressionist/test_app/log/.gitkeep delete mode 100644 vendor/impressionist/test_app/public/404.html delete mode 100644 vendor/impressionist/test_app/public/422.html delete mode 100644 vendor/impressionist/test_app/public/500.html delete mode 100644 vendor/impressionist/test_app/public/favicon.ico delete mode 100644 vendor/impressionist/test_app/public/images/rails.png delete mode 100644 vendor/impressionist/test_app/public/index.html delete mode 100644 vendor/impressionist/test_app/public/javascripts/application.js delete mode 100644 vendor/impressionist/test_app/public/javascripts/controls.js delete mode 100644 vendor/impressionist/test_app/public/javascripts/dragdrop.js delete mode 100644 vendor/impressionist/test_app/public/javascripts/effects.js delete mode 100644 vendor/impressionist/test_app/public/javascripts/prototype.js delete mode 100644 vendor/impressionist/test_app/public/javascripts/rails.js delete mode 100644 vendor/impressionist/test_app/public/robots.txt delete mode 100644 vendor/impressionist/test_app/public/stylesheets/.gitkeep delete mode 100755 vendor/impressionist/test_app/script/cucumber delete mode 100755 vendor/impressionist/test_app/script/rails delete mode 100644 vendor/impressionist/test_app/spec/controllers/controller_spec.rb delete mode 100644 vendor/impressionist/test_app/spec/controllers/impressionist_uniqueness_spec.rb delete mode 100644 vendor/impressionist/test_app/spec/fixtures/articles.yml delete mode 100644 vendor/impressionist/test_app/spec/fixtures/impressions.yml delete mode 100644 vendor/impressionist/test_app/spec/fixtures/posts.yml delete mode 100644 vendor/impressionist/test_app/spec/fixtures/widgets.yml delete mode 100644 vendor/impressionist/test_app/spec/initializers/initializers_spec.rb delete mode 100644 vendor/impressionist/test_app/spec/models/bots_spec.rb delete mode 100644 vendor/impressionist/test_app/spec/models/model_spec.rb delete mode 100644 vendor/impressionist/test_app/spec/rails_generators/rails_generators_spec.rb delete mode 100644 vendor/impressionist/test_app/spec/spec_helper.rb delete mode 100644 vendor/impressionist/upgrade_migrations/version_0_3_0.rb delete mode 100644 vendor/impressionist/upgrade_migrations/version_0_4_0.rb delete mode 100644 vendor/impressionist/upgrade_migrations/version_1_1_2.rb diff --git a/Gemfile b/Gemfile index 9dfdce1c..9fb4c3cd 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,9 @@ gem 'therubyracer' if RUBY_PLATFORM.downcase.include?("linux") gem 'rb-readline' if RUBY_PLATFORM.downcase.include?("linux") -gem "impressionist", :require => "impressionist", :path => "vendor/impressionist" +#gem "impressionist", :require => "impressionist", :path => "vendor/impressionist" +gem "impressionist", :git => 'git://github.com/charlotte-ruby/impressionist.git' + diff --git a/Gemfile.lock b/Gemfile.lock index 99b4d9a7..c7dcecaa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,8 +7,9 @@ GIT activesupport (>= 3.0.0) railties (>= 3.0.0) -PATH - remote: vendor/impressionist +GIT + remote: git://github.com/charlotte-ruby/impressionist.git + revision: 7a93fff25568cd3edcc63c1a3c4b60dc6b81d2b7 specs: impressionist (1.1.1) httpclient (~> 2.2) diff --git a/vendor/impressionist/.gitignore b/vendor/impressionist/.gitignore deleted file mode 100644 index 685130c7..00000000 --- a/vendor/impressionist/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*~ -/coverage -/pkg -/rdoc -/test_app/db/schema.rb -/test_app/db/migrate/*_create_impressions_table.rb -/test_app/doc -/test_app/test -/test_app/vendor -Gemfile.lock diff --git a/vendor/impressionist/.rspec b/vendor/impressionist/.rspec deleted file mode 100644 index 4e1e0d2f..00000000 --- a/vendor/impressionist/.rspec +++ /dev/null @@ -1 +0,0 @@ ---color diff --git a/vendor/impressionist/.travis.yml b/vendor/impressionist/.travis.yml deleted file mode 100644 index b7ae9000..00000000 --- a/vendor/impressionist/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -before_install: gem install bundler -before_script: "cd test_app && bundle install && ./script/rails generate impressionist && bundle exec rake db:migrate && cd .." -language: ruby -rvm: - - rbx-18mode - - rbx-19mode - - jruby-18mode - - 1.8.7 - - 1.9.2 - - 1.9.3 - - ruby-head diff --git a/vendor/impressionist/CHANGELOG.rdoc b/vendor/impressionist/CHANGELOG.rdoc deleted file mode 100644 index c3378b22..00000000 --- a/vendor/impressionist/CHANGELOG.rdoc +++ /dev/null @@ -1,19 +0,0 @@ -== 0.4.0 (2011-06-03) -* Fix postgres bug -* New impression count method that accepts options for filter, start_date and end_date -* Add referrer to Impression model. YOU MUST RUN THE UPGRADE MIGRATION IF YOU ARE UPGRADING FROM 0.3.0 -* UPGRADE MIGRATION = impressionist/upgrade_migrations/version_0_4_0.rb -* NOTE IF YOU ARE UPGRADING FROM 0.2.5 OR BELOW, YOU MUST RUN BOTH UPGRADE MIGRATIONS - -== 0.3.0 (2011-03-06) -* added session_hash to impression model -* migration template updated to add session_hash -* new count instance method for impressionable model - unique_impression_count_session -* NOTE: if you are upgrading from 0.2.5, then run the migration in the 'upgrade_migrations' dir - -== 0.2.5 (2011-02-17) -* New model method - @widget.unique_impression_count_ip - This gives you unique impression account filtered by IP (and in turn request_hash since they have same IPs) -* @widget.unique_impression_count now uses request_hash. This was incorrectly stated in the README, since it was using ip_address. The README is correct as a result of the method change. - -== 0.2.4 (2011-02-17) -* Fix issue #1 - action_name and controller_name were not being logged for impressionist method inside action diff --git a/vendor/impressionist/LICENSE.txt b/vendor/impressionist/LICENSE.txt deleted file mode 100644 index 67e3f5c6..00000000 --- a/vendor/impressionist/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2011 cowboycoded - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/impressionist/README.md b/vendor/impressionist/README.md deleted file mode 100644 index 40774e74..00000000 --- a/vendor/impressionist/README.md +++ /dev/null @@ -1,198 +0,0 @@ -![Impressionist Logo](https://github.com/charlotte-ruby/impressionist/raw/master/logo.png) - -[![Build Status](https://secure.travis-ci.org/charlotte-ruby/impressionist.png?branch=master)](http://travis-ci.org/charlotte-ruby/impressionist) - -impressionist -============= - -A lightweight plugin that logs impressions per action or manually per model - --------------------------------------------------------------------------------- - -What does this thing do? ------------------------- -Logs an impression... and I use that term loosely. It can log page impressions -(technically action impressions), but it is not limited to that. You can log -impressions multiple times per request. And you can also attach it to a model. -The goal of this project is to provide customizable stats that are immediately -accessible in your application as opposed to using Google Analytics and pulling -data using their API. You can attach custom messages to impressions. No -reporting yet.. this thingy just creates the data. - -What about bots? ----------------- -They are ignored. 1200 known bots have been added to the ignore list as of -February 1, 2011. Impressionist uses this list: -http://www.user-agents.org/allagents.xml - -Installation ------------- -Add it to your Gemfile - - gem 'impressionist' - -Install with Bundler - - bundle install - -Generate the impressions table migration - - rails g impressionist - -Run the migration - - rake db:migrate - -The following fields are provided in the migration: - - t.string "impressionable_type" # model type: Widget - t.integer "impressionable_id" # model instance ID: @widget.id - t.integer "user_id" # automatically logs @current_user.id - t.string "controller_name" # logs the controller name - t.string "action_name" # logs the action_name - t.string "view_name" # TODO: log individual views (as well as partials and nested partials) - t.string "request_hash" # unique ID per request, in case you want to log multiple impressions and group them - t.string "session_hash" # logs the rails session - t.string "ip_address" # request.remote_ip - t.string "referrer" # request.referer - t.string "message" # custom message you can add - t.datetime "created_at" # I am not sure what this is.... Any clue? - t.datetime "updated_at" # never seen this one before either.... Your guess is as good as mine?? - -Usage ------ - -1. Log all actions in a controller - - WidgetsController < ApplicationController - impressionist - end - -2. Specify actions you want logged in a controller - - WidgetsController < ApplicationController - impressionist :actions=>[:show,:index] - end - -3. Make your models impressionable. This allows you to attach impressions to - an AR model instance. Impressionist will automatically log the Model name - (based on action_name) and the id (based on params[:id]), but in order to - get the count of impressions (example: @widget.impression_count), you will - need to make your model impressionalble - - class Widget < ActiveRecord::Base - is_impressionable - end - -4. Log an impression per model instance in your controller. Note that it is - not necessary to specify "impressionist" (usage #1) in the top of you - controller if you are using this method. If you add "impressionist" to the - top of your controller and also use this method in your action, it will - result in 2 impressions being logged (but associated with one request_hash) - - def show - @widget = Widget.find - impressionist(@widget,message:"wtf is a widget?") #message is optional - end - -5. Get unique impression count from a model. This groups impressions by - request_hash, so if you logged multiple impressions per request, it will - only count them one time. This unique impression count will not filter out - unique users, only unique requests - - @widget.impressionist_count - @widget.impressionist_count(:start_date=>"2011-01-01",:end_date=>"2011-01-05") - @widget.impressionist_count(:start_date=>"2011-01-01") #specify start date only, end date = now - -6. Get the unique impression count from a model filtered by IP address. This - in turn will give you impressions with unique request_hash, since rows with - the same request_hash will have the same IP address. - - @widget.impressionist_count(:filter=>:ip_address) - -7. Get the unique impression count from a model filtered by session hash. Same - as #6 regarding request hash. This may be more desirable than filtering by - IP address depending on your situation, since filtering by IP may ignore - visitors that use the same IP. The downside to this filtering is that a - user could clear session data in their browser and skew the results. - - @widget.impressionist_count(:filter=>:session_hash) - -8. Get total impression count. This may return more than 1 impression per http - request, depending on how you are logging impressions - - @widget.impressionist_count(:filter=>:all) - -Logging impressions for authenticated users happens automatically. If you have -a current_user helper or use @current_user in your before_filter to set your -authenticated user, current_user.id will be written to the user_id field in the -impressions table. - -Adding a counter cache ----------------------- -Impressionist makes it easy to add a `counter_cache` column to your model. The -most basic configuration looks like: - - is_impressionable :counter_cache => true - -This will automatically increment the `impressions_count` column in the -included model. Note: You'll need to add that column to your model. If you'd -like specific a different column name, you can: - - is_impressionable :counter_cache => { :column_name => :my_column } - -If you'd like to include only unique impressions in your count: - - is_impressionable :counter_cache => { :column_name => :my_column, :unique => true } - -What if I only want to record unique impressions? -------------------------------------------------- -Maybe you only care about unique impressions and would like to avoid -unnecessary database records. You can specify conditions for recording -impressions in your controller: - - # only record impression if the request has a unique combination of type, id, and session - impressionist :unique => [:impressionable_type, :impressionable_id, :session_hash] - - # only record impression if the request has a unique combination of controller, action, and session - impressionist :unique => [:controller_name, :action_name, :session_hash] - - # only record impression if session is unique - impressionist :unique => [:session_hash] - -Or you can use the `impressionist` method directly: - - impressionist(impressionable, "some message", :unique => [:session_hash]) - -Development Roadmap -------------------- -* Automatic impression logging in views. For example, log initial view, and - any partials called from initial view -* Customizable black list for user-agents or IP addresses. Impressions will be - ignored. Web admin as part of the Engine. -* Reporting engine -* AB testing integration - -Contributing to impressionist ------------------------------ -* Check out the latest master to make sure the feature hasn't been implemented - or the bug hasn't been fixed yet -* Check out the issue tracker to make sure someone already hasn't requested it - and/or contributed it -* Fork the project -* Start a feature/bugfix branch -* Commit and push until you are happy with your contribution -* Make sure to add rpsec tests for it. Patches or features without tests will - be ignored. Also, try to write better tests than I do ;-) -* If adding engine controller or view functionality, use HAML and Inherited - Resources. -* All testing is done inside a small Rails app (test_app). You will find specs - within this app. - -Contributors ------------- -* [johnmcaliley](https://github.com/johnmcaliley) -* [coryschires](https://github.com/coryschires) -* [georgmittendorfer](https://github.com/georgmittendorfer) - -Copyright (c) 2011 John McAliley. See LICENSE.txt for further details. diff --git a/vendor/impressionist/Rakefile b/vendor/impressionist/Rakefile deleted file mode 100644 index d808f163..00000000 --- a/vendor/impressionist/Rakefile +++ /dev/null @@ -1,21 +0,0 @@ -require 'bundler/setup' -require 'rspec/core/rake_task' - -Bundler::GemHelper.install_tasks - -RSpec::Core::RakeTask.new do |task| - task.rspec_opts = "-I ./test_app/spec" - task.pattern = "./test_app/spec/**/*_spec.rb" -end - -task :test => :spec -task :default => :spec - -namespace :impressionist do - require File.dirname(__FILE__) + "/lib/impressionist/bots" - - desc "output the list of bots from http://www.user-agents.org/" - task :bots do - p Impressionist::Bots.consume - end -end diff --git a/vendor/impressionist/app/controllers/impressionist_controller.rb b/vendor/impressionist/app/controllers/impressionist_controller.rb deleted file mode 100644 index 05a39768..00000000 --- a/vendor/impressionist/app/controllers/impressionist_controller.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'digest/sha2' - -module ImpressionistController - module ClassMethods - def impressionist(opts={}) - before_filter { |c| c.impressionist_subapp_filter(opts[:actions], opts[:unique])} - end - end - - module InstanceMethods - def self.included(base) - base.before_filter :impressionist_app_filter - end - - def impressionist(obj,message=nil,opts={}) - unless bypass - if obj.respond_to?("impressionable?") - if unique_instance?(obj, opts[:unique]) - obj.impressions.create(associative_create_statement({:message => message})) - end - else - # we could create an impression anyway. for classes, too. why not? - raise "#{obj.class.to_s} is not impressionable!" - end - end - end - - def impressionist_app_filter - @impressionist_hash = Digest::SHA2.hexdigest(Time.now.to_f.to_s+rand(10000).to_s) - end - - def impressionist_subapp_filter(actions=nil,unique_opts=nil) - unless bypass - actions.collect!{|a|a.to_s} unless actions.blank? - if (actions.blank? || actions.include?(action_name)) && unique?(unique_opts) - Impression.create(direct_create_statement) - end - end - end - - private - - def bypass - Impressionist::Bots.bot?(request.user_agent) - end - - def unique_instance?(impressionable, unique_opts) - return unique_opts.blank? || !impressionable.impressions.where(unique_query(unique_opts)).exists? - end - - def unique?(unique_opts) - return unique_opts.blank? || !Impression.where(unique_query(unique_opts)).exists? - end - - # creates the query to check for uniqueness - def unique_query(unique_opts) - full_statement = direct_create_statement - # reduce the full statement to the params we need for the specified unique options - unique_opts.reduce({}) do |query, param| - query[param] = full_statement[param] - query - end - end - - # creates a statment hash that contains default values for creating an impression via an AR relation. - def associative_create_statement(query_params={}) - query_params.reverse_merge!( - :controller_name => controller_name, - :action_name => action_name, - :user_id => user_id, - :request_hash => @impressionist_hash, - :session_hash => session_hash, - :ip_address => request.remote_ip, - :referrer => request.referer - ) - end - - # creates a statment hash that contains default values for creating an impression. - def direct_create_statement(query_params={}) - query_params.reverse_merge!( - :impressionable_type => controller_name.singularize.camelize, - :impressionable_id=> params[:id] - ) - associative_create_statement(query_params) - end - - def session_hash - # # careful: request.session_options[:id] encoding in rspec test was ASCII-8BIT - # # that broke the database query for uniqueness. not sure if this is a testing only issue. - # str = request.session_options[:id] - # logger.debug "Encoding: #{str.encoding.inspect}" - # # request.session_options[:id].encode("ISO-8859-1") - request.session_options[:id] - end - - #use both @current_user and current_user helper - def user_id - user_id = @current_user ? @current_user.id : nil rescue nil - user_id = current_user ? current_user.id : nil rescue nil if user_id.blank? - user_id - end - end -end diff --git a/vendor/impressionist/app/models/impression.rb b/vendor/impressionist/app/models/impression.rb deleted file mode 100644 index b4d81ecb..00000000 --- a/vendor/impressionist/app/models/impression.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Impression - belongs_to :impressionable, :polymorphic=>true -end diff --git a/vendor/impressionist/app/models/impressionist/bots.rb b/vendor/impressionist/app/models/impressionist/bots.rb deleted file mode 100644 index aee7cf9c..00000000 --- a/vendor/impressionist/app/models/impressionist/bots.rb +++ /dev/null @@ -1,1468 +0,0 @@ -module Impressionist - module Bots - - def self.bot?(user_agent = nil) - return false if user_agent.nil? - WILD_CARDS.any? { |wc| user_agent.downcase.include?(wc) } || LIST.include?(user_agent) - end - - WILD_CARDS = ["bot","yahoo","slurp","google","msn","crawler"] - - LIST = [" UnChaos From Chaos To Order Hybrid Web Search Engine.(vadim_gonchar@unchaos.com)", - " UnChaos Bot Hybrid Web Search Engine. (vadim_gonchar@unchaos.com)", - " UnChaosBot From Chaos To Order UnChaos Hybrid Web Search Engine at www.unchaos.com (info@unchaos.com)", - " http://www.sygol.com", - "*/Nutch-0.9-dev", - "+SitiDi.net/SitiDiBot/1.0 (+Have Good Day)", - "-DIE-KRAEHE- META-SEARCH-ENGINE/1.1 http://www.die-kraehe.de", - "192.comAgent", - "4anything.com LinkChecker v2.0", - "8484 Boston Project v 1.0", - ":robot/1.0 (linux) ( admin e-mail: undefined http://www.neofonie.de/loesungen/search/robot.html )", - "A-Online Search", - "A1 Sitemap Generator/1.0 (+http://www.micro-sys.dk/products/sitemap-generator/) miggibot/2006.01.24", - "aardvark-crawler", - "AbachoBOT", - "AbachoBOT (Mozilla compatible)", - "ABCdatos BotLink/5.xx.xxx#BBL", - "Aberja Checkomat", - "abot/0.1 (abot; http://www.abot.com; abot@abot.com)", - "About/0.1libwww-perl/5.47", - "Accelatech RSSCrawler/0.4", - "accoona", - "Accoona-AI-Agent/1.1.1 (crawler at accoona dot com)", - "Accoona-AI-Agent/1.1.2 (aicrawler at accoonabot dot com)", - "Ack (http://www.ackerm.com/)", - "AcoiRobot", - "Acoon Robot v1.50.001", - "Acoon Robot v1.52 (http://www.acoon.de)", - "Acoon-Robot 4.0.x.[xx] (http://www.acoon.de)", - "Acoon-Robot v3.xx (http://www.acoon.de and http://www.acoon.com)", - "Acorn/Nutch-0.9 (Non-Profit Search Engine; acorn.isara.org; acorn at isara dot org)", - "AESOP_com_SpiderMan", - "agadine/1.x.x (+http://www.agada.de)", - "Agent-SharewarePlazaFileCheckBot/2.0+(+http://www.SharewarePlaza.com)", - "AgentName/0.1 libwww-perl/5.48", - "AIBOT/2.1 By +(www.21seek.com A Real artificial intelligence search engine China)", - "aipbot/1.0 (aipbot; http://www.aipbot.com; aipbot@aipbot.com)", - "aipbot/2-beta (aipbot dev; http://aipbot.com; aipbot@aipbot.com)", - "Aladin/3.324", - "Aleksika Spider/1.0 (+http://www.aleksika.com/)", - "AlkalineBOT/1.3", - "AlkalineBOT/1.4 (1.4.0326.0 RTM)", - "Allesklar/0.1 libwww-perl/5.46", - "Allrati/1.1 (+)", - "AltaVista Intranet V2.0 AVS EVAL search@freeit.com", - "AltaVista Intranet V2.0 Compaq Altavista Eval sveand@altavista.net", - "AltaVista Intranet V2.0 evreka.com crawler@evreka.com", - "AltaVista V2.0B crawler@evreka.com", - "AmfibiBOT", - "Amfibibot/0.06 (Amfibi Web Search; http://www.amfibi.com; agent@amfibi.com)", - "Amfibibot/0.07 (Amfibi Robot; http://www.amfibi.com; agent@amfibi.com)", - "amibot", - "AnnoMille spider 0.1 alpha - http://www.annomille.it", - "AnswerBus (http://www.answerbus.com/)", - "antibot-V1.1.5/i586-linux-2.2", - "AnzwersCrawl/2.0 (anzwerscrawl@anzwers.com.au;Engine)", - "Apexoo Spider 1.x", - "Aport", - "appie 1.1 (www.walhello.com)", - "ArabyBot (compatible; Mozilla/5.0; GoogleBot; FAST Crawler 6.4; http://www.araby.com;)", - "ArachBot", - "Arachnoidea (arachnoidea@euroseek.com)", - "ArchitextSpider", - "archive.org_bot", - "Arikus_Spider", - "Arquivo-web-crawler (compatible; heritrix/1.12.1 +http://arquivo-web.fccn.pt)", - "ASAHA Search Engine Turkey V.001 (http://www.asaha.com/)", - "Asahina-Antenna/1.x", - "Asahina-Antenna/1.x (libhina.pl/x.x ; libtime.pl/x.x)", - "ask.24x.info", - "AskAboutOil/0.06-rcp (Nutch; http://www.nutch.org/docs/en/bot.html; nutch-agent@askaboutoil.com)", - "asked/Nutch-0.8 (web crawler; http://asked.jp; epicurus at gmail dot com)", - "ASPSeek/1.2.5", - "ASPseek/1.2.9d", - "ASPSeek/1.2.x", - "ASPSeek/1.2.xa", - "ASPseek/1.2.xx", - "ASPSeek/1.2.xxpre", - "ASSORT/0.10", - "asterias/2.0", - "AtlocalBot/1.1 +(http://www.atlocal.com/local-web-site-owner.html)", - "Atomic_Email_Hunter/4.0", - "Atomz/1.0", - "atSpider/1.0", - "Attentio/Nutch-0.9-dev (Attentio's beta blog crawler; www.attentio.com; info@attentio.com)", - "augurfind", - "augurnfind V-1.x", - "autoemailspider", - "autowebdir 1.1 (www.autowebdir.com)", - "AV Fetch 1.0", - "AVSearch-1.0(peter.turney@nrc.ca)", - "AVSearch-3.0(AltaVista/AVC)", - "axadine/ (Axadine Crawler; http://www.axada.de/; )", - "AxmoRobot - Crawling your site for better indexing on www.axmo.com search engine.", - "BabalooSpider/1.3 (BabalooSpider; http://www.babaloo.si; spider@babaloo.si)", - "BaboomBot/1.x.x (+http://www.baboom.us)", - "BaiduImagespider+(+http://www.baidu.jp/search/s308.html)", - "BaiDuSpider", - "Baiduspider+(+http://help.baidu.jp/system/05.html)", - "Baiduspider+(+http://www.baidu.com/search/spider.htm)", - "Baiduspider+(+http://www.baidu.com/search/spider_jp.html)", - "Balihoo/Nutch-1.0-dev (Crawler for Balihoo.com search engine - obeys robots.txt and robots meta tags ; http://balihoo.com/index.aspx; robot at balihoo dot com)", - "BarraHomeCrawler (albertof@barrahome.org)", - "bdcindexer_2.6.2 (research@bdc)", - "BDFetch", - "BDNcentral Crawler v2.3 [en] (http://www.bdncentral.com/robot.html) (X11; I; Linux 2.0.44 i686)", - "beautybot/1.0 (+http://www.uchoose.de/crawler/beautybot/)", - "BebopBot/2.5.1 ( crawler http://www.apassion4jazz.net/bebopbot.html )", - "BigCliqueBOT/1.03-dev (bigclicbot; http://www.bigclique.com; bot@bigclique.com)", - "BIGLOTRON (Beta 2;GNU/Linux)", - "Bigsearch.ca/Nutch-x.x-dev (Bigsearch.ca Internet Spider; http://www.bigsearch.ca/; info@enhancededge.com)", - "BilgiBetaBot/0.8-dev (bilgi.com (Beta) ; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)", - "BilgiBot/1.0(beta) (http://www.bilgi.com/; bilgi at bilgi dot com)", - "Bitacle bot/1.1", - "Bitacle Robot (V:1.0;) (http://www.bitacle.com)", - "BlackWidow", - "Blaiz-Bee/1.0 (+http://www.blaiz.net)", - "Blaiz-Bee/2.00.8222 (BE Internet Search Engine http://www.rawgrunt.com)", - "Blaiz-Bee/2.00.xxxx (+http://www.blaiz.net)", - "BlitzBOT@tricus.net", - "BlitzBOT@tricus.net (Mozilla compatible)", - "BlogBot/1.x", - "Bloglines Title Fetch/1.0 (http://www.bloglines.com)", - "Bloglines-Images/0.1 (http://www.bloglines.com)", - "Bloglines/3.1 (http://www.bloglines.com)", - "Blogpulse (info@blogpulse.com)", - "BlogPulseLive (support@blogpulse.com)", - "BlogSearch/1.x +http://www.icerocket.com/", - "blogsearchbot-pumpkin-3", - "BlogsNowBot, V 2.01 (+http://www.blogsnow.com/)", - "BlogVibeBot-v1.1 (spider@blogvibe.nl)", - "blogWatcher_Spider/0.1 (http://www.lr.pi.titech.ac.jp/blogWatcher/)", - "BlogzIce/1.0 (+http://icerocket.com; rhodes@icerocket.com)", - "BlogzIce/1.0 +http://www.icerocket.com/", - "BloobyBot", - "Bloodhound/Nutch-0.9 (Testing Crawler for Research - obeys robots.txt and robots meta tags ; http://balihoo.com/index.aspx; robot at balihoo dot com)", - "boitho.com-dc/0.xx (http://www.boitho.com/dcbot.html)", - "boitho.com-robot/1.x", - "boitho.com-robot/1.x (http://www.boitho.com/bot.html)", - "BPImageWalker/2.0 (www.bdbrandprotect.com)", - "BravoBrian SpiderEngine MarcoPolo", - "BruinBot (+http://webarchive.cs.ucla.edu/bruinbot.html) ", - "BSDSeek/1.0", - "BTbot/0.x (+http://www.btbot.com/btbot.html)", - "BuildCMS crawler (http://www.buildcms.com/crawler)", - "BullsEye", - "bumblebee@relevare.com", - "BurstFindCrawler/1.1 (crawler.burstfind.com; http://crawler.burstfind.com; crawler@burstfind.com)", - "Buscaplus Robi/1.0 (http://www.buscaplus.com/robi/)", - "bwh3_user_agent", - "Cabot/Nutch-0.9 (Amfibi's web-crawling robot; http://www.amfibi.com/cabot/; agent@amfibi.com)", - "Cabot/Nutch-1.0-dev (Amfibi's web-crawling robot; http://www.amfibi.com/cabot/; agent@amfibi.com)", - "carleson/1.0", - "Carnegie_Mellon_University_Research_WebBOT-->PLEASE READ-->http://www.andrew.cmu.edu/~brgordon/webbot/index.html http://www.andrew.cmu.edu/~brgordon/webbot/index.html", - "Carnegie_Mellon_University_WebCrawler http://www.andrew.cmu.edu/~brgordon/webbot/index.html", - "Catall Spider", - "CazoodleBot/CazoodleBot-0.1 (CazoodleBot Crawler; http://www.cazoodle.com/cazoodlebot; cazoodlebot@cazoodle.com)", - "CCBot/1.0 (+http://www.commoncrawl.org/bot.html)", - "ccubee/x.x", - "Ceramic Tile Installation Guide (http://www.floorstransformed.com)", - "cfetch/1.0", - "China Local Browse 2.6", - "ChristCRAWLER 2.0", - "CipinetBot (http://www.cipinet.com/bot.html)", - "ClariaBot/1.0", - "Claymont.com", - "CloakDetect/0.9 (+http://fulltext.seznam.cz/)", - "Clushbot/2.x (+http://www.clush.com/bot.html)", - "Clushbot/3.x-BinaryFury (+http://www.clush.com/bot.html)", - "Clushbot/3.xx-Ajax (+http://www.clush.com/bot.html)", - "Clushbot/3.xx-Hector (+http://www.clush.com/bot.html)", - "Clushbot/3.xx-Peleus (+http://www.clush.com/bot.html)", - "Cogentbot/1.X (+http://www.cogentsoftwaresolutions.com/bot.html)", - "combine/0.0", - "Combine/2.0 http://combine.it.lth.se/", - "Combine/3 http://combine.it.lth.se/", - "Combine/x.0", - "cometrics-bot, http://www.cometrics.de", - "Computer_and_Automation_Research_Institute_Crawler crawler@ilab.sztaki.hu", - "Comrite/0.7.1 (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)", - "ContactBot/0.2", - "ContentSmartz", - "Convera Internet Spider V6.x", - "ConveraCrawler/0.2", - "ConveraCrawler/0.9d (+http://www.authoritativeweb.com/crawl)", - "ConveraMultiMediaCrawler/0.1 (+http://www.authoritativeweb.com/crawl)", - "CoolBot", - "cosmos/0.8_(robot@xyleme.com)", - "cosmos/0.9_(robot@xyleme.com)", - "CougarSearch/0.x (+http://www.cougarsearch.com/faq.shtml)", - "Covac TexAs Arachbot", - "Cowbot-0.1 (NHN Corp. / +82-2-3011-1954 / nhnbot@naver.com)", - "Cowbot-0.1.x (NHN Corp. / +82-2-3011-1954 / nhnbot@naver.com)", - "CrawlConvera0.1 (CrawlConvera@yahoo.com)", - "Crawler (cometsearch@cometsystems.com)", - "Crawler admin@crawler.de", - "Crawler V 0.2.x admin@crawler.de", - "crawler@alexa.com", - "CrawlerBoy Pinpoint.com", - "Crawllybot/0.1 (Crawllybot; +http://www.crawlly.com; crawler@crawlly.com)", - "CreativeCommons/0.06-dev (Nutch; http://www.nutch.org/docs/en/bot.html; nutch-agent@lists.sourceforge.net)", - "CrocCrawler vx.3 [en] (http://www.croccrawler.com) (X11; I; Linux 2.0.44 i686)", - "csci_b659/0.13", - "Cuasarbot/0.9b http://www.cuasar.com/spider_beta/ ", - "CurryGuide SiteScan 1.1", - "Custom Spider www.bisnisseek.com /1.0", - "CyberPatrol SiteCat Webbot (http://www.cyberpatrol.com/cyberpatrolcrawler.asp)", - "CydralSpider/1.x (Cydral Web Image Search; http://www.cydral.com)", - "CydralSpider/3.0 (Cydral Image Search; http://www.cydral.com)", - "DataCha0s/2.0", - "DataCha0s/2.0", - "DataFountains/DMOZ Downloader", - "DataFountains/Dmoz Downloader (http://ivia.ucr.edu/useragents.shtml)", - "DataFountains/DMOZ Feature Vector Corpus Creator (http://ivia.ucr.edu/useragents.shtml)", - "DataparkSearch/4.47 (+http://dataparksearch.org/bot)", - "DataparkSearch/4.xx (http://www.dataparksearch.org/)", - "DataSpear/1.0 (Spider; http://www.dataspear.com/spider.html; spider@dataspear.com)", - "DataSpearSpiderBot/0.2 (DataSpear Spider Bot; http://dssb.dataspear.com/bot.html; dssb@dataspear.com)", - "DatenBot( http://www.sicher-durchs-netz.de/bot.html)", - "DaviesBot/1.7 (www.wholeweb.net)", - "daypopbot/0.x", - "dbDig(http://www.prairielandconsulting.com)", - "DBrowse 1.4b", - "DBrowse 1.4d", - "dCSbot/1.1", - "de.searchengine.comBot 1.2 (http://de.searchengine.com/spider)", - "deepak-USC/ISI", - "DeepIndex", - "DeepIndex ( http://www.zetbot.com )", - "DeepIndex (www.en.deepindex.com)", - "DeepIndexer.ca", - "Demo Bot DOT 16b", - "Demo Bot Z 16b", - "Denmex websearch (http://search.denmex.com)", - "dev-spider2.searchpsider.com/1.3b", - "DiaGem/1.1 (http://www.skyrocket.gr.jp/diagem.html)", - "Diamond/x.0", - "DiamondBot", - "Digger/1.0 JDK/1.3.0rc3", - "DigOut4U", - "DIIbot/1.2", - "disco/Nutch-0.9 (experimental crawler; www.discoveryengine.com; disco-crawl@discoveryengine.com)", - "disco/Nutch-1.0-dev (experimental crawler; www.discoveryengine.com; disco-crawl@discoveryengine.com)", - "DittoSpyder", - "dloader(NaverRobot)/1.0", - "DoCoMo/1.0/Nxxxi/c10", - "DoCoMo/1.0/Nxxxi/c10/TB", - "DoCoMo/2.0 P900iV(c100;TB;W24H11) ", - "DoCoMo/2.0 SH902i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)", - "DoCoMo/2.0/SO502i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)", - "dodgebot/experimental", - "Download-Tipp Linkcheck (http://download-tipp.de/)", - "Drecombot/1.0 (http://career.drecom.jp/bot.html)", - "DSurf15a 01", - "DSurf15a 71", - "DSurf15a 81", - "DSurf15a VA", - "dtSearchSpider", - "DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)", - "Dumbot(version 0.1 beta - dumbfind.com)", - "Dumbot(version 0.1 beta - http://www.dumbfind.com/dumbot.html)", - "Dumbot(version 0.1 beta)", - "e-sense 1.0 ea(www.vigiltech.com/esensedisclaim.html)", - "e-SocietyRobot(http://www.yama.info.waseda.ac.jp/~yamana/es/)", - "eApolloBot/2.0 (compatible; heritrix/2.0.0-SNAPSHOT-20071024.170148 +http://www.eapollo-opto.com)", - "EARTHCOM.info/1.x [www.earthcom.info]", - "EARTHCOM.info/1.xbeta [www.earthcom.info]", - "EasyDL/3.xx", - "EasyDL/3.xx http://keywen.com/Encyclopedia/Bot", - "EBrowse 1.4b", - "EchO!/2.0", - "Educate Search VxB", - "egothor/3.0a (+http://www.xdefine.org/robot.html)", - "EgotoBot/4.8 (+http://www.egoto.com/about.htm)", - "ejupiter.com", - "elfbot/1.0 (+http://www.uchoose.de/crawler/elfbot/)", - "ELI/20070402:2.0 (DAUM RSS Robot, Daum Communications Corp.; +http://ws.daum.net/aboutkr.html)", - "EmailSiphon", - "EmailSpider", - "EmailWolf 1.00", - "EMPAS_ROBOT", - "EnaBot/1.x (http://www.enaball.com/crawler.html)", - "Enfish Tracker", - "Enterprise_Search/1.0", - "Enterprise_Search/1.0.xxx", - "Enterprise_Search/1.00.xxx;MSSQL (http://www.innerprise.net/es-spider.asp)", - "envolk/1.7 (+http://www.envolk.com/envolkspiderinfo.php)", - "envolk[ITS]spider/1.6(+http://www.envolk.com/envolkspider.html)", - "EroCrawler", - "ES.NET_Crawler/2.0 (http://search.innerprise.net/)", - "eseek-larbin_2.6.2 (crawler@exactseek.com)", - "ESISmartSpider", - "eStyleSearch 4 (compatible; MSIE 6.0; Windows NT 5.0)", - "ESurf15a 15", - "EuripBot/0.x (+http://www.eurip.com) GetFile", - "EuripBot/0.x (+http://www.eurip.com) GetRobots", - "EuripBot/0.x (+http://www.eurip.com) PreCheck", - "Eurobot/1.0 (http://www.ayell.eu)", - "EvaalSE - bot@evaal.com", - "eventax/1.3 (eventax; http://www.eventax.de/; info@eventax.de)", - "Everest-Vulcan Inc./0.1 (R&D project; host=e-1-24; http://everest.vulcan.com/crawlerhelp)", - "Everest-Vulcan Inc./0.1 (R&D project; http://everest.vulcan.com/crawlerhelp)", - "Exabot-Images/1.0", - "Exabot-Test/1.0", - "Exabot/2.0", - "Exabot/3.0", - "ExactSeek Crawler/0.1", - "exactseek-crawler-2.63 (crawler@exactseek.com)", - "exactseek-pagereaper-2.63 (crawler@exactseek.com)", - "exactseek.com", - "Exalead NG/MimeLive Client (convert/http/0.120)", - "Excalibur Internet Spider V6.5.4", - "Execrawl/1.0 (Execrawl; http://www.execrawl.com/; bot@execrawl.com)", - "exooba crawler/exooba crawler (crawler for exooba.com; http://www.exooba.com/; info at exooba dot com)", - "exooba/exooba crawler (exooba; exooba)", - "ExperimentalHenrytheMiragoRobot", - "ExtractorPro", - "EyeCatcher (Download-tipp.de)/1.0", - "Factbot 1.09 (see http://www.factbites.com/webmasters.php)", - "factbot : http://www.factbites.com/robots", - "Fast Crawler Gold Edition", - "FAST Enterprise Crawler 6 (Experimental)", - "FAST Enterprise Crawler 6 / Scirus scirus-crawler@fast.no; http://www.scirus.com/srsapp/contactus/", - "FAST Enterprise Crawler 6 used by Cobra Development (admin@fastsearch.com)", - "FAST Enterprise Crawler 6 used by Comperio AS (sts@comperio.no)", - "FAST Enterprise Crawler 6 used by FAST (FAST)", - "FAST Enterprise Crawler 6 used by Pages Jaunes (pvincent@pagesjaunes.fr)", - "FAST Enterprise Crawler 6 used by Sensis.com.au Web Crawler (search_comments\\at\\sensis\\dot\\com\\dot\\au)", - "FAST Enterprise Crawler 6 used by Singapore Press Holdings (crawler@sphsearch.sg)", - "FAST Enterprise Crawler/6 (www.fastsearch.com)", - "FAST Enterprise Crawler/6.4 (helpdesk at fast.no)", - "FAST FirstPage retriever (compatible; MSIE 5.5; Mozilla/4.0)", - "FAST MetaWeb Crawler (helpdesk at fastsearch dot com)", - "Fast PartnerSite Crawler", - "FAST-WebCrawler/2.2.10 (Multimedia Search) (crawler@fast.no; http://www.fast.no/faq/faqfastwebsearch/faqfastwebcrawler.html)", - "FAST-WebCrawler/2.2.6 (crawler@fast.no; http://www.fast.no/faq/faqfastwebsearch/faqfastwebcrawler.html)", - "FAST-WebCrawler/2.2.7 (crawler@fast.no; http://www.fast.no/faq/faqfastwebsearch/faqfastwebcrawler.html)http://www.fast.no", - "FAST-WebCrawler/2.2.8 (crawler@fast.no; http://www.fast.no/faq/faqfastwebsearch/faqfastwebcrawler.html)http://www.fast.no", - "FAST-WebCrawler/3.2 test", - "FAST-WebCrawler/3.3 (crawler@fast.no; http://fast.no/support.php?c=faqs/crawler)", - "FAST-WebCrawler/3.4/Nirvana (crawler@fast.no; http://fast.no/support.php?c=faqs/crawler)", - "FAST-WebCrawler/3.4/PartnerSite (crawler@fast.no; http://fast.no/support.php?c=faqs/crawler)", - "FAST-WebCrawler/3.5 (atw-crawler at fast dot no; http://fast.no/support.php?c=faqs/crawler)", - "FAST-WebCrawler/3.6 (atw-crawler at fast dot no; http://fast.no/support/crawler.asp)", - "FAST-WebCrawler/3.6/FirstPage (crawler@fast.no; http://fast.no/support.php?c=faqs/crawler)", - "FAST-WebCrawler/3.7 (atw-crawler at fast dot no; http://fast.no/support/crawler.asp)", - "FAST-WebCrawler/3.7/FirstPage (atw-crawler at fast dot no;http://fast.no/support/crawler.asp)", - "FAST-WebCrawler/3.8 (atw-crawler at fast dot no; http://fast.no/support/crawler.asp)", - "FAST-WebCrawler/3.8/Fresh (atw-crawler at fast dot no; http://fast.no/support/crawler.asp)", - "FAST-WebCrawler/3.x Multimedia", - "FAST-WebCrawler/3.x Multimedia (mm dash crawler at fast dot no)", - "fastbot crawler beta 2.0 (+http://www.fastbot.de)", - "FastBug http://www.ay-up.com", - "FastCrawler 3.0.1 (crawler@1klik.dk)", - "FastSearch Web Crawler for Verizon SuperPages (kevin.watters@fastsearch.com)", - "Favcollector/2.0 (info@favcollector.com http://www.favcollector.com/)", - "favo.eu crawler/0.6 (http://www.favo.eu)", - "Faxobot/1.0", - "Feed Seeker Bot (RSS Feed Seeker http://www.MyNewFavoriteThing.com/fsb.php)", - "Feed24.com", - "FeedChecker/0.01", - "Feedfetcher-Google; (+http://www.google.com/feedfetcher.html)", - "FeedHub FeedDiscovery/1.0 (http://www.feedhub.com)", - "FeedHub MetaDataFetcher/1.0 (http://www.feedhub.com)", - "Feedjit Favicon Crawler 1.0", - "Feedster Crawler/3.0; Feedster, Inc.", - "Felix - Mixcat Crawler (+http://mixcat.com)", - "FFC Trap Door Spider", - "Filtrbox/1.0", - "Findexa Crawler (http://www.findexa.no/gulesider/article26548.ece)", - "findlinks/x.xxx (+http://wortschatz.uni-leipzig.de/findlinks/) ", - "FineBot", - "Firefly/1.0", - "Firefly/1.0 (compatible; Mozilla 4.0; MSIE 5.5)", - "Firefox (kastaneta03@hotmail.com)", - "Firefox_1.0.6 (kasparek@naparek.cz)", - "FirstGov.gov Search - POC:firstgov.webmasters@gsa.gov", - "firstsbot", - "Flapbot/0.7.2 (Flaptor Crawler; http://www.flaptor.com; crawler at flaptor period com)", - "Flexum spider", - "Flexum/2.0", - "FlickBot 2.0 RPT-HTTPClient/0.3-3", - "flunky", - "FnooleBot/2.5.2 (+http://www.fnoole.com/addurl.html)", - "FocusedSampler/1.0", - "Folkd.com Spider/0.1 beta 1 (www.folkd.com)", - "Fooky.com/ScorpionBot/ScoutOut; http://www.fooky.com/scorpionbots", - "Francis/1.0 (francis@neomo.de http://www.neomo.de/)", - "Franklin Locator 1.8", - "FreeFind.com-SiteSearchEngine/1.0 (http://freefind.com; spiderinfo@freefind.com)", - "FreshNotes crawler< report problems to crawler-at-freshnotes-dot-com", - "FSurf15a 01", - "FTB-Bot http://www.findthebest.co.uk/", - "Full Web Bot 0416B", - "Full Web Bot 0516B", - "Full Web Bot 2816B", - "FuseBulb.Com", - "FyberSpider (+http://www.fybersearch.com/fyberspider.php)", - "GAIS Robot/1.0B2", - "Gaisbot/3.0 (indexer@gais.cs.ccu.edu.tw; http://gais.cs.ccu.edu.tw/robot.php)", - "Gaisbot/3.0+(robot06@gais.cs.ccu.edu.tw;+http://gais.cs.ccu.edu.tw/robot.php)", - "GalaxyBot/1.0 (http://www.galaxy.com/galaxybot.html)", - "Gallent Search Spider v1.4 Robot 2 (http://robot.GallentSearch.com)", - "gamekitbot/1.0 (+http://www.uchoose.de/crawler/gamekitbot/)", - "GammaSpider/1.0", - "gazz/x.x (gazz@nttrd.com)", - "generic_crawler/01.0217/", - "genieBot (http://64.5.245.11/faq/faq.html)", - "geniebot wgao@genieknows.com", - "GeonaBot 1.x; http://www.geona.com/", - "gigabaz/3.1x (baz@gigabaz.com; http://gigabaz.com/gigabaz/)", - "Gigabot/2.0 (gigablast.com)", - "Gigabot/2.0/gigablast.com/spider.html", - "Gigabot/2.0; http://www.gigablast.com/spider.html", - "Gigabot/2.0att", - "Gigabot/3.0 (http://www.gigablast.com/spider.html)", - "Gigabot/x.0", - "GigabotSiteSearch/2.0 (sitesearch.gigablast.com)", - "GNODSPIDER (www.gnod.net)", - "Goblin/0.9 (http://www.goguides.org/)", - "Goblin/0.9.x (http://www.goguides.org/goblin-info.html)", - "GoForIt.com", - "GOFORITBOT ( http://www.goforit.com/about/ )", - "gonzo1[P] +http://www.suchen.de/popups/faq.jsp", - "gonzo2[P] +http://www.suchen.de/faq.html", - "Goofer/0.2", - "Googlebot-Image/1.0", - "Googlebot-Image/1.0 ( http://www.googlebot.com/bot.html)", - "Googlebot/2.1 ( http://www.google.com/bot.html)", - "Googlebot/2.1 ( http://www.googlebot.com/bot.html)", - "Googlebot/Test ( http://www.googlebot.com/bot.html)", - "GrapeFX/0.3 libwww/5.4.0", - "great-plains-web-spider/flatlandbot (Flatland Industries Web Spider; http://www.flatlandindustries.com/flatlandbot.php; jason@flatlandindustries.com)", - "GrigorBot 0.8 (http://www.grigor.biz/bot.html)", - "Gromit/1.0", - "grub crawler(http://www.grub.org)", - "grub-client", - "gsa-crawler (Enterprise; GID-01422; jplastiras@google.com)", - "gsa-crawler (Enterprise; GID-01742;gsatesting@rediffmail.com)", - "gsa-crawler (Enterprise; GIX-02057; dm@enhesa.com)", - "gsa-crawler (Enterprise; GIX-03519; cknuetter@stubhub.com)", - "gsa-crawler (Enterprise; GIX-0xxxx; enterprise-training@google.com)", - "Guestbook Auto Submitter", - "Gulliver/1.3", - "Gulper Web Bot 0.2.4 (www.ecsl.cs.sunysb.edu/~maxim/cgi-bin/Link/GulperBot)", - "Gungho/0.08004 (http://code.google.com/p/gungho-crawler/wiki/Index)", - "GurujiBot/1.0 (+http://www.guruji.com/WebmasterFAQ.html)", - "GurujiImageBot/1.0 (+http://www.guruji.com/en/WebmasterFAQ.html)", - "HappyFunBot/1.1", - "Harvest-NG/1.0.2", - "Hatena Antenna/0.4 (http://a.hatena.ne.jp/help#robot)", - "Hatena Pagetitle Agent/1.0", - "Hatena RSS/0.3 (http://r.hatena.ne.jp)", - "hbtronix.spider.2 -- http://hbtronix.de/spider.php", - "HeinrichderMiragoRobot", - "HeinrichderMiragoRobot (http://www.miragorobot.com/scripts/deinfo.asp)", - "Helix/1.x ( http://www.sitesearch.ca/helix/)", - "HenriLeRobotMirago (http://www.miragorobot.com/scripts/frinfo.asp)", - "HenrytheMiragoRobot", - "HenryTheMiragoRobot (http://www.miragorobot.com/scripts/mrinfo.asp)", - "Hi! I'm CsCrawler my homepage: http://www.kde.cs.uni-kassel.de/lehre/ss2005/googlespam/crawler.html RPT-HTTPClient/0.3-3", - "Hippias/0.9 Beta", - "HitList", - "Hitwise Spider v1.0 http://www.hitwise.com", - "holmes/3.11 (http://morfeo.centrum.cz/bot)", - "holmes/3.9 (onet.pl)", - "holmes/3.xx (OnetSzukaj/5.0; +http://szukaj.onet.pl)", - "holmes/x.x", - "HolmesBot (http://holmes.ge)", - "HomePageSearch(hpsearch.uni-trier.de)", - "Homerbot: www.homerweb.com", - "Honda-Search/0.7.2 (Nutch; http://lucene.apache.org/nutch/bot.html; search@honda-search.com)", - "HooWWWer/2.1.3 (debugging run) (+http://cosco.hiit.fi/search/hoowwwer/ | mailto:crawler-infohiit.fi)", - "HooWWWer/2.1.x ( http://cosco.hiit.fi/search/hoowwwer/ | mailto:crawler-infohiit.fi)", - "HPL/Nutch-0.9 -", - "htdig/3.1.6 (http://computerorgs.com)", - "htdig/3.1.6 (unconfigured@htdig.searchengine.maintainer)", - "htdig/3.1.x (root@localhost)", - "http://Ask.24x.Info/ (http://narres.it/)", - "http://hilfe.acont.de/bot.html ACONTBOT", - "http://www.almaden.ibm.com/cs/crawler", - "http://www.almaden.ibm.com/cs/crawler [rc1.wf.ibm.com]", - "http://www.almaden.ibm.com/cs/crawler [wf216]", - "http://www.istarthere.com_spider@istarthere.com", - "http://www.monogol.de", - "http://www.trendtech.dk/spider.asp)", - "i1searchbot/2.0 (i1search web crawler; http://www.i1search.com; crawler@i1search.com)", - "IAArchiver-1.0", - "iaskspider2 (iask@staff.sina.com.cn)", - "ia_archiver", - "ia_archiver-web.archive.org", - "ia_archiver/1.6", - "ICC-Crawler(Mozilla-compatible; http://kc.nict.go.jp/icc/crawl.html; icc-crawl(at)ml(dot)nict(dot)go(dot)jp)", - "ICC-Crawler(Mozilla-compatible;http://kc.nict.go.jp/icc/crawl.html;icc-crawl-contact(at)ml(dot)nict(dot)go(dot)jp)", - "iCCrawler (http://www.iccenter.net)", - "ICCrawler - ICjobs (http://www.icjobs.de/bot.htm)", - "ichiro/x.0 (http://help.goo.ne.jp/door/crawler.html)", - "ichiro/x.0 (ichiro@nttr.co.jp)", - "IconSurf/2.0 favicon finder (see http://iconsurf.com/robot.html)", - "IconSurf/2.0 favicon monitor (see http://iconsurf.com/robot.html)", - "ICRA_label_spider/x.0", - "icsbot-0.1", - "ideare - SignSite/1.x", - "iFeed.jp/2.0 (www.psychedelix.com/agents/agents.rss; 0 subscribers)", - "igdeSpyder (compatible; igde.ru; +http://igde.ru/doc/tech.html)", - "IIITBOT/1.1 (Indian Language Web Search Engine; http://webkhoj.iiit.net; pvvpr at iiit dot ac dot in)", - "ilial/Nutch-0.9 (Ilial, Inc. is a Los Angeles based Internet startup company. For more information please visit http://www.ilial.com/crawler; http://www.ilial.com/crawler; crawl@ilial.com)", - "ilial/Nutch-0.9-dev", - "IlseBot/1.x", - "IlTrovatore-Setaccio ( http://www.iltrovatore.it)", - "Iltrovatore-Setaccio/0.3-dev (Indexing; http://www.iltrovatore.it/bot.html; info@iltrovatore.it)", - "IlTrovatore-Setaccio/1.2 ( http://www.iltrovatore.it/aiuto/faq.html)", - "Iltrovatore-Setaccio/1.2 (It-bot; http://www.iltrovatore.it/bot.html; info@iltrovatore.it)", - "iltrovatore-setaccio/1.2-dev (spidering; http://www.iltrovatore.it/aiuto/.....)", - "IlTrovatore/1.2 (IlTrovatore; http://www.iltrovatore.it/bot.html; bot@iltrovatore.it)", - "ImageWalker/2.0 (www.bdbrandprotect.com)", - "IncyWincy data gatherer(webmaster@loopimprovements.com", - "IncyWincy page crawler(webmaster@loopimprovements.com", - "IncyWincy(http://www.look.com)", - "IncyWincy(http://www.loopimprovements.com/robot.html)", - "IncyWincy/2.1(loopimprovements.com/robot.html)", - "IndexTheWeb.com Crawler7", - "Industry Program 1.0.x", - "Inet library", - "info@pubblisito.com- (http://www.pubblisito.com) il Sud dei Motori di Ricerca", - "InfoFly/1.0 (http://www.versions-project.org/)", - "INFOMINE/8.0 Adders", - "INFOMINE/8.0 RemoteServices", - "INFOMINE/8.0 VLCrawler (http://infomine.ucr.edu/useragents)", - "InfoNaviRobot(F107)", - "InfoSeek Sidewinder/0.9", - "InfoSeek Sidewinder/1.0A", - "InfoSeek Sidewinder/1.1A", - "Infoseek SideWinder/1.45 (Compatible; MSIE 10.0; UNIX)", - "Infoseek SideWinder/2.0B (Linux 2.4 i686)", - "INGRID/3.0 MT (webcrawler@NOSPAMexperimental.net; http://webmaster.ilse.nl/jsp/webmaster.jsp)", - "Inktomi Search", - "InnerpriseBot/1.0 (http://www.innerprise.com/)", - "Insitor.com search and find world wide!", - "Insitornaut", - "Internet Ninja x.0", - "InternetArchive/0.8-dev(Nutch;http://lucene.apache.org/nutch/bot.html;nutch-agent@lucene.apache", - "InternetSeer.com", - "IOI/2.0 (ISC Open Index crawler; http://index.isc.org/; bot@index.isc.org)", - "IPiumBot laurion(dot)com", - "IpselonBot/0.xx-beta (Ipselon; http://www.ipselon.com; ipselonbot@ipselon.com)", - "IRLbot/1.0 ( http://irl.cs.tamu.edu/crawler)", - "IRLbot/3.0 (compatible; MSIE 6.0; http://irl.cs.tamu.edu/crawler/)", - "ISC Systems iRc Search 2.1", - "IUPUI Research Bot v 1.9a", - "IWAgent/ 1.0 - www.brandprotect.com", - "Jabot/6.x (http://odin.ingrid.org/)", - "Jabot/7.x.x (http://odin.ingrid.org/)", - "Jack", - "Jambot/0.1.x (Jambot; http://www.jambot.com/blog; crawler@jambot.com)", - "Jambot/0.2.1 (Jambot; http://www.jambot.com/blog/static.php?page=webmaster-robot; crawler@jambot.com)", - "Jayde Crawler. http://www.jayde.com", - "Jetbot/1.0", - "JobSpider_BA/1.1", - "Jyxobot/x", - "k2spider", - "KAIST AITrc Crawler", - "KakleBot - www.kakle.com/0.1 (KakleBot - www.kakle.com; http:// www.kakle.com/bot.html; support@kakle.com)", - "kalooga/kalooga-4.0-dev-datahouse (Kalooga; http://www.kalooga.com; info@kalooga.com)", - "kalooga/KaloogaBot (Kalooga; http://www.kalooga.com/info.html?page=crawler; crawler@kalooga.com)", - "Kenjin Spider", - "Kevin http://dznet.com/kevin/", - "Kevin http://websitealert.net/kevin/", - "KE_1.0/2.0 libwww/5.2.8", - "KFSW-Bot (Version: 1.01 powered by KFSW www.kfsw.de)", - "kinja-imagebot (http://www.kinja.com/)", - "kinjabot (http://www.kinja.com)", - "KIT-Fireball/2.0", - "KIT-Fireball/2.0 (compatible; Mozilla 4.0; MSIE 5.5)", - "KnowItAll(knowitall@cs.washington.edu)", - "Knowledge.com/0.x", - "Krugle/Krugle,Nutch/0.8+ (Krugle web crawler; http://www.krugle.com/crawler/info.html; webcrawler@krugle.com)", - "KSbot/1.0 (KnowledgeStorm crawler; http://www.knowledgestorm.com/resources/content/crawler/index.html; crawleradmin@knowledgestorm.com)", - "kuloko-bot/0.x", - "kulokobot www.kuloko.com kuloko@backweave.com", - "kulturarw3/0.1", - "LapozzBot/1.4 ( http://robot.lapozz.com)", - "LapozzBot/1.5 (+http://robot.lapozz.hu)", - "larbin (samualt9@bigfoot.com)", - "LARBIN-EXPERIMENTAL (efp@gmx.net)", - "larbin_2.1.1 larbin2.1.1@somewhere.com", - "larbin_2.2.0 (crawl@compete.com)", - "larbin_2.2.1_de_Viennot (Laurent.Viennot@inria.fr)", - "larbin_2.2.2 (sugayama@lab7.kuis.kyoto-u.ac.jp)", - "larbin_2.2.2_guillaume (guillaume@liafa.jussieu.fr)", - "larbin_2.6.0 (larbin2.6.0@unspecified.mail)", - "larbin_2.6.1 (larbin2.6.1@unspecified.mail)", - "larbin_2.6.2 (hamasaki@grad.nii.ac.jp)", - "larbin_2.6.2 (larbin2.6.2@unspecified.mail)", - "larbin_2.6.2 (listonATccDOTgatechDOTedu)", - "larbin_2.6.2 (pimenas@systems.tuc.gr)", - "larbin_2.6.2 (tom@lemurconsulting.com)", - "larbin_2.6.2 (vitalbox1@hotmail.com)", - "larbin_2.6.3 (ltaa_web_crawler@groupes.epfl.ch)", - "larbin_2.6.3 (wgao@genieknows.com)", - "larbin_2.6.3_for_(http://cosco.hiit.fi/search/) tsilande@hiit.fi", - "larbin_2.6_basileocaml (basile.starynkevitch@cea.fr)", - "larbin_devel (http://pauillac.inria.fr/~ailleret/prog/larbin/)", - "lawinfo-crawler/Nutch-0.9-dev (Crawler for lawinfo.com pages; http://www.lawinfo.com; webmaster@lawinfo.com)", - "LECodeChecker/3.0 libgetdoc/1.0", - "LEIA/2.90", - "LEIA/3.01pr (LEIAcrawler; [SNIP])", - "LetsCrawl.com/1.0 +http://letscrawl.com/", - "LexiBot/1.00", - "Libby_1.1/libwww-perl/5.47", - "LibertyW (+http://www.lw01.com)", - "libWeb/clsHTTP -- hiongun@kt.co.kr", - "libwww-perl/5.41", - "libwww-perl/5.45", - "libwww-perl/5.48", - "libwww-perl/5.52 FP/2.1", - "libwww-perl/5.52 FP/4.0", - "libwww-perl/5.65", - "libwww-perl/5.800", - "libwww/5.3.2", - "LijitSpider/Nutch-0.9 (Reports crawler; http://www.lijit.com/; info(a)lijit(d)com)", - "Lincoln State Web Browser", - "linkbot", - "linknzbot", - "Links 2.0 (http://gossamer-threads.com/scripts/links/)", - "Links SQL (http://gossamer-threads.com/scripts/links-sql/)", - "LinkScan/11.0beta2 UnixShareware robot from Elsop.com (used by Indiafocus/Indiainfo)", - "LinkScan/9.0g Unix", - "LinkScan/x.x Unix", - "LiveTrans/Nutch-0.9 (maintainer: cobain at iis dot sinica dot edu dot tw; http://wkd.iis.sinica.edu.tw/LiveTrans/)", - "Llaut/1.0 (http://mnm.uib.es/~gallir/llaut/bot.html)", - "LMQueueBot/0.2", - "lmspider (lmspider@scansoft.com)", - "LNSpiderguy", - "LocalBot/1.0 ( http://www.localbot.co.uk/)", - "LocalcomBot/1.2.x ( http://www.local.com/bot.htm)", - "Lockstep Spider/1.0", - "Look.com", - "Lovel as 1.0 ( +http://www.everatom.com)", - "LTI/LemurProject Nutch Spider/Nutch-1.0-dev (lti crawler for CMU; http://www.lti.cs.cmu.edu; changkuk at cmu dot edu)", - "LTI/LemurProject Nutch Spider/Nutch-1.0-dev (Research spider using Nutch; http://www.lemurproject.org; mhoy@cs.cmu.edu)", - "lwp-trivial/1.32", - "lwp-trivial/1.34", - "lwp-trivial/1.34", - "LWP::Simple/5.22", - "LWP::Simple/5.36", - "LWP::Simple/5.48", - "LWP::Simple/5.50", - "LWP::Simple/5.51", - "LWP::Simple/5.53", - "LWP::Simple/5.63", - "LWP::Simple/5.803", - "Lycos_Spider_(modspider)", - "Lycos_Spider_(T-Rex)", - "Lynx/2.8.4rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.6c (human-guided@lerly.net)", - "Mac Finder 1.0.xx", - "Mackster( http://www.ukwizz.com )", - "Mahiti.Com/Mahiti Crawler-1.0 (Mahiti.Com; http://mahiti.com ; mahiti.com)", - "Mail.Ru/1.0", - "mailto:webcraft@bea.com", - "mammoth/1.0 ( http://www.sli-systems.com/)", - "MantraAgent", - "MapoftheInternet.com ( http://MapoftheInternet.com)", - "Mariner/5.1b [de] (Win95; I ;Kolibri gncwebbot)", - "Marketwave Hit List", - "Martini", - "MARTINI", - "Marvin v0.3", - "MaSagool/1.0 (MaSagool; http://sagool.jp/; info@sagool.jp)", - "MasterSeek", - "Mata Hari/2.00 ", - "Matrix S.p.A. - FAST Enterprise Crawler 6 (Unknown admin e-mail address)", - "maxomobot/dev-20051201 (maxomo; http://67.102.134.34:4047/MAXOMO/MAXOMObot.html; maxomobot@maxomo.com)", - "MDbot/1.0 (+http://www.megadownload.net/bot.html)", - "MediaCrawler-1.0 (Experimental)", - "Mediapartners-Google/2.1 ( http://www.googlebot.com/bot.html)", - "MediaSearch/0.1", - "MegaSheep v1.0 (www.searchuk.com internet sheep)", - "Megite2.0 (http://www.megite.com)", - "Mercator-1.x", - "Mercator-2.0", - "Mercator-Scrub-1.1", - "Metaeuro Web Crawler/0.2 (MetaEuro Web Search Clustering Engine; http://www.metaeuro.com; crawler at metaeuro dot com)", - "MetaGer-LinkChecker", - "MetagerBot/0.8-dev (MetagerBot; http://metager.de; )", - "MetaGer_PreChecker0.1", - "Metaspinner/0.01 (Metaspinner; http://www.meta-spinner.de/; support@meta-spinner.de/)", - "metatagsdir/0.7 (+http://metatagsdir.com/directory/)", - "MFC Foundation Class Library 4.0", - "MicroBaz", - "Microsoft Small Business Indexer", - "Microsoft URL Control - 6.00.8xxx", - "MicrosoftPrototypeCrawler (How's my crawling? mailto:newbiecrawler@hotmail.com)", - "Missauga Locate 1.0.0", - "Missigua Locator 1.9", - "Missouri College Browse", - "Misterbot-Nutch/0.7.1 (Misterbot-Nutch; http://www.misterbot.fr; admin@misterbot.fr)", - "Miva (AlgoFeedback@miva.com)", - "Mizzu Labs 2.2", - "MJ12bot/vx.x.x (http://majestic12.co.uk/bot.php?+)", - "MJ12bot/vx.x.x (http://www.majestic12.co.uk/projects/dsearch/mj12bot.php)", - "MJBot (SEO assessment)", - "MLBot (www.metadatalabs.com)", - "MnogoSearch/3.2.xx", - "Mo College 1.9", - "moget/x.x (moget@goo.ne.jp)", - "mogimogi/1.0", - "MojeekBot/0.x (archi; http://www.mojeek.com/bot.html)", - "Morris - Mixcat Crawler ( http://mixcat.com)", - "Mouse-House/7.4 (spider_monkey spider info at www.mobrien.com/sm.shtml)", - "mozDex/0.xx-dev (mozDex; http://www.mozdex.com/en/bot.html; spider@mozdex.com)", - "Mozilla (Mozilla@somewhere.com)", - "Mozilla 4.0(compatible; BotSeer/1.0; +http://botseer.ist.psu.edu)", - "Mozilla/2.0 (compatible; Ask Jeeves)", - "Mozilla/2.0 (compatible; Ask Jeeves/Teoma)", - "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; http://about.ask.com/en/docs/about/webmasters.shtml) ", - "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; http://sp.ask.com/docs/about/tech_crawling.html)", - "Mozilla/2.0 (compatible; EZResult -- Internet Search Engine)", - "Mozilla/2.0 (compatible; NEWT ActiveX; Win32)", - "Mozilla/2.0 (compatible; T-H-U-N-D-E-R-S-T-O-N-E)", - "Mozilla/3.0 (compatible; Fluffy the spider; http://www.searchhippo.com/; info@searchhippo.com)", - "Mozilla/3.0 (compatible; Indy Library)", - "Mozilla/3.0 (compatible; MuscatFerret/1.5.4; claude@euroferret.com)", - "Mozilla/3.0 (compatible; MuscatFerret/1.5; olly@muscat.co.uk)", - "Mozilla/3.0 (compatible; MuscatFerret/1.6.x; claude@euroferret.com)", - "Mozilla/3.0 (compatible; scan4mail (advanced version) http://www.peterspages.net/?scan4mail)", - "Mozilla/3.0 (compatible; ScollSpider; http://www.webwobot.com)", - "Mozilla/3.0 (compatible; Webinator-DEV01.home.iprospect.com/2.56)", - "Mozilla/3.0 (compatible; Webinator-indexer.cyberalert.com/2.56)", - "Mozilla/3.0 (INGRID/3.0 MT; webcrawler@NOSPAMexperimental.net; http://aanmelden.ilse.nl/?aanmeld_mode=webhints)", - "Mozilla/3.0 (Slurp.so/Goo; slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Mozilla/3.0 (Slurp/cat; slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Mozilla/3.0 (Slurp/si; slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Mozilla/3.0 (Vagabondo/1.1 MT; webcrawler@NOSPAMwise-guys.nl; http://webagent.wise-guys.nl/)", - "Mozilla/3.0 (Vagabondo/1.x MT; webagent@wise-guys.nl; http://webagent.wise-guys.nl/)", - "Mozilla/3.0 (Vagabondo/2.0 MT; webcrawler@NOSPAMexperimental.net; http://aanmelden.ilse.nl/?aanmeld_mode=webhints)", - "Mozilla/3.0 (Vagabondo/2.0 MT; webcrawler@NOSPAMwise-guys.nl; http://webagent.wise-guys.nl/)", - "Mozilla/3.01 (Compatible; Links2Go Similarity Engine)", - "Mozilla/4.0", - "Mozilla/4.0 (agadine3.0) www.agada.de", - "Mozilla/4.0 (compatible: AstraSpider V.2.1 : astrafind.com)", - "Mozilla/4.0 (compatible; Vagabondo/2.2; webcrawler at wise-guys dot nl; http://webagent.wise-guys.nl/)", - "Mozilla/4.0 (compatible; Vagabondo/4.0Beta; webcrawler at wise-guys dot nl; http://webagent.wise-guys.nl/)", - "Mozilla/4.0 (compatible; Advanced Email Extractor v2.xx)", - "Mozilla/4.0 (compatible; B_L_I_T_Z_B_O_T)", - "Mozilla/4.0 (compatible; ChristCrawler.com ChristCrawler@ChristCENTRAL.com)", - "Mozilla/4.0 (compatible; crawlx, crawler@trd.overture.com)", - "Mozilla/4.0 (compatible; DAUMOA-video; +http://ws.daum.net/aboutkr.html)", - "Mozilla/4.0 (compatible; FastCrawler3 support-fastcrawler3@fast.no)", - "Mozilla/4.0 (compatible; FDSE robot)", - "Mozilla/4.0 (compatible; GPU p2p crawler http://gpu.sourceforge.net/search_engine.php)", - "Mozilla/4.0 (compatible; grub-client-0.2.x; Crawl your stuff with http://grub.org)", - "Mozilla/4.0 (compatible; grub-client-0.3.x; Crawl your own stuff with http://grub.org)", - "Mozilla/4.0 (compatible; grub-client-2.x)", - "Mozilla/4.0 (compatible; Iplexx Spider/1.0 http://www.iplexx.at)", - "Mozilla/4.0 (compatible; MSIE 4.01; Vonna.com b o t)", - "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; SPV M700; OpVer 19.123.2.733) OrangeBot-Mobile 2008.0 (mobilesearch.support@orange-ftgroup.com)", - "Mozilla/4.0 (compatible; MSIE 4.0; Windows NT; Site Server 3.0 Robot) Indonesia Interactive", - "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) (samualt9@bigfoot.com)", - "Mozilla/4.0 (compatible; MSIE 5.0; NetNose-Crawler 2.0; A New Search Experience: http://www.netnose.com)", - "Mozilla/4.0 (compatible; MSIE 5.0; Windows 95) TrueRobot; 1.5", - "Mozilla/4.0 (compatible; MSIE 5.0; Windows 95) VoilaBot BETA 1.2 (http://www.voila.com/)", - "Mozilla/4.0 (compatible; MSIE 5.0; Windows 95) VoilaBot; 1.6", - "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt; DTS Agent", - "Mozilla/4.0 (compatible; MSIE 5.0; www.galaxy.com; www.psychedelix.com)", - "Mozilla/4.0 (compatible; MSIE 5.0; www.galaxy.com; www.psychedelix.com/; http://www.galaxy.com/info/crawler.html)", - "Mozilla/4.0 (compatible; MSIE 5.0; YANDEX)", - "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; obot)", - "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; QXW03018)", - "Mozilla/4.0 (compatible; MSIE 6.0 compatible; Asterias Crawler v4; +http://www.singingfish.com/help/spider.html; webmaster@singingfish.com); SpiderThread Revision: 3.10", - "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Skampy/0.9.x [en]", - "Mozilla/4.0 (compatible; MSIE 6.0; TargetSeek/1.0; +http://www.targetgroups.net/TargetSeek.html)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; ODP entries t_st; http://tuezilla.de/t_st-odp-entries-agent.html)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; ODP links test; http://tuezilla.de/test-odp-links-agent.html)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; ZoomSpider.net bot; .NET CLR 1.1.4322)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; heritrix/1.3.0 http://www.cs.washington.edu/research/networking/websys/)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; QihooBot 1.0 qihoobot@qihoo.net)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)", - "Mozilla/4.0 (compatible; MSIE enviable; DAUMOA 2.0; DAUM Web Robot; Daum Communications Corp., Korea; +http://ws.daum.net/aboutkr.html)", - "Mozilla/4.0 (compatible; MSIE is not me; DAUMOA/1.0.1; DAUM Web Robot; Daum Communications Corp., Korea)", - "Mozilla/4.0 (compatible; NaverBot/1.0; http://help.naver.com/delete_main.asp)", - "Mozilla/4.0 (compatible; SpeedySpider; www.entireweb.com)", - "Mozilla/4.0 (compatible; www.galaxy.com)", - "Mozilla/4.0 (compatible; Y!J; for robot study; keyoshid)", - "Mozilla/4.0 (compatible; Yahoo Japan; for robot study; kasugiya)", - "Mozilla/4.0 (JemmaTheTourist;http://www.activtourist.com)", - "Mozilla/4.0 (MobilePhone SCP-5500/US/1.0) NetFront/3.0 MMP/2.0 (compatible; Googlebot/2.1; http://www.google.com/bot.html)", - "Mozilla/4.0 (MobilePhone SCP-5500/US/1.0) NetFront/3.0 MMP/2.0 FAKE (compatible; Googlebot/2.1; http://www.google.com/bot.html)", - "Mozilla/4.0 (Mozilla; http://www.mozilla.org/docs/en/bot.html; master@mozilla.com)", - "Mozilla/4.0 (Sleek Spider/1.2)", - "Mozilla/4.0 compatible FurlBot/Furl Search 2.0 (FurlBot; http://www.furl.net; wn.furlbot@looksmart.net)", - "Mozilla/4.0 compatible ZyBorg/1.0 (wn.zyborg@looksmart.net; http://www.WISEnutbot.com)", - "Mozilla/4.0 compatible ZyBorg/1.0 (ZyBorg@WISEnutbot.com; http://www.WISEnutbot.com)", - "Mozilla/4.0 compatible ZyBorg/1.0 Dead Link Checker (wn.zyborg@looksmart.net; http://www.WISEnutbot.com)", - "Mozilla/4.0 compatible ZyBorg/1.0 for Homepage (ZyBorg@WISEnutbot.com; http://www.WISEnutbot.com)", - "Mozilla/4.0 efp@gmx.net", - "Mozilla/4.0 [en] (Ask Jeeves Corporate Spider)", - "Mozilla/4.0(compatible; Zealbot 1.0)", - "Mozilla/4.04 (compatible; Dulance bot; +http://www.dulance.com/bot.jsp)", - "Mozilla/4.0_(compatible;_MSIE_5.0;_Windows_95)_TrueRobot/1.4 libwww/5.2.8", - "Mozilla/4.0_(compatible;_MSIE_5.0;_Windows_95)_VoilaBot/1.6 libwww/5.3.2", - "Mozilla/4.6 [en] (http://www.cnet.com/)", - "Mozilla/4.7", - "Mozilla/4.7 (compatible; http://eidetica.com/spider)", - "Mozilla/4.7 (compatible; Intelliseek; http://www.intelliseek.com)", - "Mozilla/4.7 (compatible; Whizbang)", - "Mozilla/4.7 (compatible; WhizBang; http://www.whizbang.com/crawler)", - "Mozilla/4.7 [en](BecomeBot@exava.com)", - "Mozilla/4.7 [en](Exabot@exava.com)", - "Mozilla/4.72 [en] (BACS http://www.ba.be)", - "Mozilla/5.0", - "Mozilla/5.0 (+http://www.eurekster.com/mammoth) Mammoth/0.1", - "Mozilla/5.0 (+http://www.sli-systems.com/) Mammoth/0.1", - "Mozilla/5.0 (Clustered-Search-Bot/1.0; support@clush.com; http://www.clush.com/)", - "Mozilla/5.0 (compatible; +http://www.evri.com/evrinid)", - "Mozilla/5.0 (compatible; 008/0.83; http://www.80legs.com/spider.html;) Gecko/2008032620", - "Mozilla/5.0 (compatible; Abonti/0.8 - http://www.abonti.com)", - "Mozilla/5.0 (compatible; aiHitBot/1.0; +http://www.aihit.com/)", - "Mozilla/5.0 (compatible; AnsearchBot/1.x; +http://www.ansearch.com.au/)", - "Mozilla/5.0 (compatible; archive.org_bot/1.10.0 +http://www.loc.gov/minerva/crawl.html)", - "Mozilla/5.0 (compatible; archive.org_bot/1.13.1x http://crawler.archive.org)", - "Mozilla/5.0 (compatible; archive.org_bot/1.5.0-200506132127 http://crawler.archive.org) Hurricane Katrina", - "Mozilla/5.0 (compatible; Ask Jeeves/Teoma; http://about.ask.com/en/docs/about/webmasters.shtml)", - "Mozilla/5.0 (compatible; BecomeBot/1.23; http://www.become.com/webmasters.html)", - "Mozilla/5.0 (compatible; BecomeBot/1.xx; MSIE 6.0 compatible; http://www.become.com/webmasters.html)", - "Mozilla/5.0 (compatible; BecomeBot/2.0beta; http://www.become.com/webmasters.html)", - "Mozilla/5.0 (compatible; BecomeBot/2.x; MSIE 6.0 compatible; http://www.become.com/site_owners.html)", - "Mozilla/5.0 (compatible; BecomeJPBot/2.3; MSIE 6.0 compatible; +http://www.become.co.jp/site_owners.html)", - "Mozilla/5.0 (compatible; BlogRefsBot/0.1; http://www.blogrefs.com/about/bloggers)", - "Mozilla/5.0 (compatible; Bot; +http://pressemitteilung.ws/spamfilter", - "Mozilla/5.0 (compatible; BuzzRankingBot/1.0; +http://www.buzzrankingbot.com/)", - "Mozilla/5.0 (compatible; Charlotte/1.0b; charlotte@betaspider.com)", - "Mozilla/5.0 (compatible; Charlotte/1.0b; http://www.searchme.com/support/)", - "Mozilla/5.0 (compatible; Crawling jpeg; http://www.yama.info.waseda.ac.jp)", - "Mozilla/5.0 (compatible; de/1.13.2 +http://www.de.com)", - "Mozilla/5.0 (compatible; Diffbot/0.1; +http://www.diffbot.com)", - "Mozilla/5.0 (compatible; DNS-Digger-Explorer/1.0; +http://www.dnsdigger.com)", - "Mozilla/5.0 (compatible; DNS-Digger/1.0; +http://www.dnsdigger.com)", - "Mozilla/5.0 (compatible; EARTHCOM.info/2.01; http://www.earthcom.info)", - "Mozilla/5.0 (compatible; EARTHCOM/2.2; +http://enter4u.eu)", - "Mozilla/5.0 (compatible; Exabot Test/3.0; +http://www.exabot.com/go/robot)", - "Mozilla/5.0 (compatible; FatBot 2.0; http://www.thefind.com/main/CrawlerFAQs.fhtml)", - "Mozilla/5.0 (compatible; Galbot/1.0; +http://www.galbot.com/bot.html)", - "mozilla/5.0 (compatible; genevabot http://www.healthdash.com)", - "Mozilla/5.0 (compatible; Googlebot/2.1; http://www.google.com/bot.html)", - "mozilla/5.0 (compatible; heritrix/1.0.4 http://innovationblog.com)", - "Mozilla/5.0 (compatible; heritrix/1.10.2 +http://i.stanford.edu/)", - "Mozilla/5.0 (compatible; heritrix/1.12.1 +http://newstin.com/)", - "Mozilla/5.0 (compatible; heritrix/1.12.1 +http://www.page-store.com)", - "Mozilla/5.0 (compatible; heritrix/1.12.1 +http://www.page-store.com) [email:paul@page-store.com]", - "mozilla/5.0 (compatible; heritrix/1.3.0 http://archive.crawler.org)", - "Mozilla/5.0 (compatible; heritrix/1.4.0 +http://www.chepi.net)", - "Mozilla/5.0 (compatible; heritrix/1.4t http://www.truveo.com/)", - "Mozilla/5.0 (compatible; heritrix/1.5.0 http://www.l3s.de/~kohlschuetter/projects/crawling/)", - "Mozilla/5.0 (compatible; heritrix/1.5.0-200506231921 http://pandora.nla.gov.au/crawl.html)", - "Mozilla/5.0 (compatible; heritrix/1.6.0 http://www.worio.com/)", - "Mozilla/5.0 (compatible; heritrix/1.7.0 +http://www.greaterera.com/)", - "Mozilla/5.0 (compatible; heritrix/1.x.x +http://www.accelobot.com)", - "Mozilla/5.0 (compatible; heritrix/2.0.0-RC1 +http://www.aol.com)", - "Mozilla/5.0 (compatible; Hermit Search. Com; +http://www.hermitsearch.com)", - "Mozilla/5.0 (compatible; HyperixScoop/1.3; +http://www.hyperix.com)", - "Mozilla/5.0 (compatible; IDBot/1.0; +http://www.id-search.org/bot.html)", - "Mozilla/5.0 (compatible; InterseekWeb/3.x)", - "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Exabot-Thumbnails)", - "Mozilla/5.0 (compatible; LemSpider 0.1)", - "Mozilla/5.0 (compatible; MojeekBot/2.0; http://www.mojeek.com/bot.html)", - "Mozilla/5.0 (compatible; MSIE 6.0; Podtech Network; crawler_admin@podtech.net)", - "Mozilla/5.0 (compatible; OnetSzukaj/5.0; http://szukaj.onet.pl)", - "Mozilla/5.0 (compatible; PalmeraBot; http://www.links24h.com/help/palmera) Version 0.001", - "Mozilla/5.0 (compatible; pogodak.ba/3.x)", - "Mozilla/5.0 (compatible; Pogodak.hr/3.1)", - "Mozilla/5.0 (compatible; PWeBot/3.1; http://www.programacionweb.net/robot.php)", - "Mozilla/5.0 (compatible; Quantcastbot/1.0; www.quantcast.com)", - "Mozilla/5.0 (compatible; ScoutJet; +http://www.scoutjet.com/)", - "Mozilla/5.0 (compatible; Scrubby/2.2; http://www.scrubtheweb.com/)", - "Mozilla/5.0 (compatible; ShunixBot/1.x.x +http://www.shunix.com/robot.htm)", - "Mozilla/5.0 (compatible; ShunixBot/1.x; http://www.shunix.com/bot.htm)", - "Mozilla/5.0 (compatible; SkreemRBot +http://skreemr.com)", - "Mozilla/5.0 (compatible; SummizeBot +http://www.summize.com)", - "Mozilla/5.0 (compatible; Synoobot/0.9; http://www.synoo.com/search/bot.html)", - "Mozilla/5.0 (compatible; Theophrastus/x.x; http://users.cs.cf.ac.uk/N.A.Smith/theophrastus.php)", - "Mozilla/5.0 (compatible; TridentSpider/3.1)", - "Mozilla/5.0 (compatible; Vagabondo/2.1; webcrawler at wise-guys dot nl; http://webagent.wise-guys.nl/)", - "Mozilla/5.0 (compatible; Webduniabot/1.0; +http://search.webdunia.com/bot.aspx)", - "Mozilla/5.0 (compatible; worio bot heritrix/1.10.0 +http://worio.com)", - "Mozilla/5.0 (compatible; WoW Lemmings Kathune/2.0;http://www.wowlemmings.com/kathune.html)", - "Mozilla/5.0 (compatible; Yahoo! DE Slurp; http://help.yahoo.com/help/us/ysearch/slurp)", - "Mozilla/5.0 (compatible; Yahoo! Slurp China; http://misc.yahoo.com.cn/help.html)", - "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)", - "Mozilla/5.0 (compatible; Yoono; http://www.yoono.com/)", - "Mozilla/5.0 (compatible; YoudaoBot/1.0; http://www.youdao.com/help/webmaster/spider/; )", - "Mozilla/5.0 (compatible; Zenbot/1.3; +http://zen.co.za/webmasters/)", - "Mozilla/5.0 (compatible; zermelo +http://www.powerset.com) [email:paul@page-store.com,crawl@powerset.com]", - "Mozilla/5.0 (compatible;archive.org_bot/1.7.1; collectionId=316; Archive-It; +http://www.archive-it.org)", - "Mozilla/5.0 (compatible;archive.org_bot/heritrix-1.9.0-200608171144 +http://pandora.nla.gov.au/crawl.html)", - "Mozilla/5.0 (compatible;MAINSEEK_BOT)", - "Mozilla/5.0 (Slurp/cat; slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Mozilla/5.0 (Slurp/si; slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Mozilla/5.0 (Twiceler-0.9 http://www.cuill.com/twiceler/robot.html)", - "Mozilla/5.0 (Version: xxxx Type:xx)", - "Mozilla/5.0 (wgao@genieknows.com)", - "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.7) NimbleCrawler 1.11 obeys UserAgent NimbleCrawler For problems contact: crawler_at_dataalchemy.com", - "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) VoilaBot BETA 1.2 (support.voilabot@orange-ftgroup.com)", - "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) VoilaBot BETA 1.2 (support.voilabot@orange-ftgroup.com)", - "Mozilla/5.0 (Windows;) NimbleCrawler 1.12 obeys UserAgent NimbleCrawler For problems contact: crawler@health", - "Mozilla/5.0 (Windows;) NimbleCrawler 1.12 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com", - "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1; aggregator:Spinn3r (Spinn3r 3.1); http://spinn3r.com/robot) Gecko/20021130", - "Mozilla/5.0 URL-Spider", - "Mozilla/5.0 usww.com-Spider-for-w8.net", - "Mozilla/5.0 wgao@genieknows.com", - "Mozilla/5.0 [en] (compatible; Gulper Web Bot 0.2.4 www.ecsl.cs.sunysb.edu/~maxim/cgi-bin/Link/GulperBot)", - "MQbot metaquerier.cs.uiuc.edu/crawler", - "MQBOT/Nutch-0.9-dev (MQBOT Nutch Crawler; http://falcon.cs.uiuc.edu; mqbot@cs.uiuc.edu)", - "msnbot-media/1.0 (+http://search.msn.com/msnbot.htm)", - "msnbot-Products/1.0 (+http://search.msn.com/msnbot.htm)", - "MSNBOT/0.xx (http://search.msn.com/msnbot.htm)", - "msnbot/x.xx ( http://search.msn.com/msnbot.htm)", - "MSNBOT_Mobile MSMOBOT Mozilla/2.0 (compatible; MSIE 4.02; Windows CE; Default)", - "MSNPTC/1.0", - "MSRBOT (http://research.microsoft.com/research/sv/msrbot)", - "multicrawler ( http://sw.deri.org/2006/04/multicrawler/robots.html)", - "MultiText/0.1", - "MusicWalker2.0 ( http://www.somusical.com)", - "MVAClient", - "Mylinea.com Crawler 2.0", - "Naamah 1.0.1/Blogbot (http://blogbot.de/)", - "Naamah 1.0a/Blogbot (http://blogbot.de/)", - "NABOT/5.0", - "nabot_1.0", - "NameOfAgent (CMS Spider)", - "NASA Search 1.0", - "NationalDirectory-WebSpider/1.3", - "NationalDirectoryAddURL/1.0", - "NaverBot-1.0 (NHN Corp. / +82-2-3011-1954 / nhnbot@naver.com)", - "NaverBot_dloader/1.5", - "NavissoBot", - "NavissoBot/1.7 (+http://navisso.com/)", - "NCSA Beta 1 (http://vias.ncsa.uiuc.edu/viasarchivinginformation.html)", - "Nebullabot/2.2 (http://bot.nebulla.info)", - "NEC Research Agent -- compuman at research.nj.nec.com", - "Net-Seekr Bot/Net-Seekr Bot V1 (http://www.net-seekr.com)", - "NetinfoBot/1.0 (http://netinfo.bg/netinfobot.html)", - "NetLookout/2.24", - "Netluchs/0.8-dev ( ; http://www.netluchs.de/; ___don't___spam_me_@netluchs.de)", - "NetNoseCrawler/v1.0", - "Netprospector JavaCrawler", - "NetResearchServer(http://www.look.com)", - "NetResearchServer/x.x(loopimprovements.com/robot.html)", - "NetSeer/Nutch-0.9 (NetSeer Crawler; http://www.netseer.com; crawler@netseer.com)", - "NetSprint -- 2.0", - "NetWhatCrawler/0.06-dev (NetWhatCrawler from NetWhat.com; http://www.netwhat.com; support@netwhat.com)", - "NetZippy", - "NextGenSearchBot 1 (for information visit http://www.eliyon.com/NextGenSearchBot)", - "NextopiaBOT (+http://www.nextopia.com) distributed crawler client beta v0.x", - "NG-Search/0.90 (NG-SearchBot; http://www.ng-search.com; )", - "NG/1.0", - "NG/4.0.1229", - "NITLE Blog Spider/0.01", - "Noago Spider", - "Nokia-WAPToolkit/1.2 googlebot(at)googlebot.com", - "Nokia6610/1.0 (3.09) Profile/MIDP-1.0 Configuration/CLDC-1.0 (compatible;YahooSeeker/M1A1-R2D2; http://help.yahoo.com/help/us/ysearch/crawling/crawling-01.html)", - "NokodoBot/1.x (+http://nokodo.com/bot.htm)", - "Norbert the Spider(Burf.com)", - "noxtrumbot/1.0 (crawler@noxtrum.com)", - "noyona_0_1", - "NP/0.1 (NP; http://www.nameprotect.com; npbot@nameprotect.com)", - "NPBot (http://www.nameprotect.com/botinfo.html)", - "NPBot-1/2.0", - "Nsauditor/1.x", - "nsyght.com/Nutch-1.0-dev (nsyght.com; Nsyght.com)", - "nsyght.com/Nutch-x.x (nsyght.com; search.nsyght.com)", - "nttdirectory_robot/0.9 (super-robot@super.navi.ocn.ne.jp)", - "nuSearch Spider www.nusearch.com (compatible; MSIE 4.01)", - "NuSearch Spider (compatible; MSIE 6.0)", - "NuSearch Spider www.nusearch.com", - "Nutch", - "Nutch crawler/Nutch-0.9 (picapage.com; admin@picapage.com)", - "Nutch/Nutch-0.9 (Eurobot; http://www.ayell.eu )", - "NutchCVS/0.0x-dev (Nutch; http://www.nutch.org/docs/bot.html; nutch-agent@lists.sourceforge.net)", - "NutchCVS/0.7.1 (Nutch running at UW; http://www.nutch.org/docs/en/bot.html; sycrawl@cs.washington.edu)", - "NutchEC2Test/Nutch-0.9-dev (Testing Nutch on Amazon EC2.; http://lucene.apache.org/nutch/bot.html; ec2test at lucene.com)", - "NutchOrg/0.0x-dev (Nutch; http://www.nutch.org/docs/bot.html; nutch-agent@lists.sourceforge.net)", - "nutchsearch/Nutch-0.9 (Nutch Search 1.0; herceg_novi at yahoo dot com)", - "NutchVinegarCrawl/Nutch-0.8.1 (Vinegar; http://www.cs.washington.edu; eytanadar at gmail dot com)", - "obidos-bot (just looking for books.)", - "ObjectsSearch/0.01-dev (ObjectsSearch;http://www.ObjectsSearch.com/bot.html; support@thesoftwareobjects.com)", - "ObjectsSearch/0.0x (ObjectsSearch; http://www.ObjectsSearch.com/bot.html; support@thesoftwareobjects.com)", - "oBot ((compatible;Win32))", - "Ocelli/1.x (http://www.globalspec.com/Ocelli)", - "Octora Beta - www.octora.com", - "Octora Beta Bot - www.octora.com", - "OmniExplorer_Bot/1.0x (+http://www.omni-explorer.com) Internet CategorizerOmniExplorer http://www.omni-explorer.com/ car & shopping search (64.62.175.xxx)", - "OmniExplorer_Bot/1.0x (+http://www.omni-explorer.com) Job Crawler", - "OmniExplorer_Bot/1.1x (+http://www.omni-explorer.com) Torrent Crawler", - "OmniExplorer_Bot/x.xx (+http://www.omni-explorer.com) WorldIndexer", - "Onet.pl SA- http://szukaj.onet.pl", - "OntoSpider/1.0 libwww-perl/5.65", - "OOZBOT/0.20 ( http://www.setooz.com/oozbot.html ; agentname at setooz dot_com )", - "OpenAcoon v4.0.x (www.openacoon.de)", - "Openbot/3.0+(robot-response@openfind.com.tw;+http://www.openfind.com.tw/robot.html)", - "Openfind data gatherer- Openbot/3.0+(robot-response@openfind.com.tw;+http://www.openfind.com.tw/robot.html)", - "Openfind Robot/1.1A2", - "OpenISearch/1.x (www.openisearch.com)", - "OpenTaggerBot (http://www.opentagger.com/opentaggerbot.htm)", - "OpenTextSiteCrawler/2.9.2", - "OpenWebSpider/0.x.x (http://www.openwebspider.org)", - "OpenWebSpider/x", - "OpidooBOT (larbin2.6.3@unspecified.mail)", - "Oracle Ultra Search", - "OrangeSpider", - "Orbiter/T-2.0 (+http://www.dailyorbit.com/bot.htm)", - "Overture-WebCrawler/3.8/Fresh (atw-crawler at fast dot no; http://fast.no/support/crawler.asp)", - "ozelot/2.7.3 (Search engine indexer; www.flying-cat.de/ozelot; ozelot@flying-cat.de)", - "PADLibrary Spider", - "PageBitesHyperBot/600 (http://www.pagebites.com/)", - "Pagebull http://www.pagebull.com/", - "page_verifier (http://www.securecomputing.com/goto/pv)", - "parallelContextFocusCrawler1.1parallelContextFocusCrawler1.1", - "ParaSite/1.0b (http://www.ianett.com/parasite/)", - "Patwebbot (http://www.herz-power.de/technik.html)", - "PBrowse 1.4b", - "pd02_1.0.0 pd02_1.0.0@dzimi@post.sk", - "PEERbot www.peerbot.com", - "PEval 1.4b", - "PicoSearch/1.0", - "Piffany_Web_Scraper_v0.x", - "Piffany_Web_Spider_v0.x", - "pipeLiner/0.3a (PipeLine Spider;http://www.pipeline-search.com/webmaster.html; webmaster'at'pipeline-search.com)", - "pipeLiner/0.xx (PipeLine Spider; http://www.pipeline-search.com/webmaster.html)", - "Pita", - "PJspider/3.0 (pjspider@portaljuice.com; http://www.portaljuice.com)", - "PlagiarBot/1.0", - "PluckFeedCrawler/2.0 (compatible; Mozilla 4.0; MSIE 5.5; http://www.pluck.com; 1 subscribers)", - "Pluggd/Nutch-0.9 (automated crawler http://www.pluggd.com;support at pluggd dot com)", - "Poirot", - "polybot 1.0 (http://cis.poly.edu/polybot/)", - "Pompos/1.x http://dir.com/pompos.html", - "Pompos/1.x pompos@iliad.fr", - "Popdexter/1.0", - "Port Huron Labs", - "PortalBSpider/2.0 (spider@portalb.com)", - "potbot 1.0", - "PRCrawler/Nutch-0.9 (data mining development project; crawler@projectrialto.com)", - "PrivacyFinder Cache Bot v1.0", - "PrivacyFinder/1.1", - "Production Bot 0116B", - "Production Bot 2016B", - "Production Bot DOT 3016B", - "Program Shareware 1.0.2", - "Project XP5 [2.03.07-111203]", - "PROve AnswerBot 4.0", - "ProWebGuide Link Checker (http://www.prowebguide.com)", - "psbot/0.1 (+http://www.picsearch.com/bot.html)", - "PSurf15a 11", - "PSurf15a 51", - "PSurf15a VA", - "psycheclone", - "PubCrawl (pubcrawl.stanford.edu)", - "pulseBot (pulse Web Miner)", - "PWeBot/1.2 Inspector (http://www.programacionweb.net/robot.php)", - "PycURL", - "Python-urllib/1.1x", - "Python-urllib/2.0a1", - "Qango.com Web Directory (http://www.qango.com/)", - "QEAVis Agent/Nutch-0.9 (Quantitative Evaluation of Academic Websites Visibility; http://nlp.uned.es/qeavis", - "QPCreep Test Rig ( We are not indexing- just testing )", - "QuepasaCreep ( crawler@quepasacorp.com )", - "QuepasaCreep v0.9.1x", - "QueryN Metasearch", - "QweeryBot/3.01 ( http://qweerybot.qweery.nl)", - "Qweery_robot.txt_CheckBot/3.01 (http://qweerybot.qweery.com)", - "R6_CommentReader_(www.radian6.com/crawler)", - "R6_FeedFetcher_(www.radian6.com/crawler)", - "rabaz (rabaz at gigabaz dot com)", - "RaBot/1.0 Agent-admin/phortse@hanmail.net", - "ramBot xtreme x.x", - "RAMPyBot - www.giveRAMP.com/0.1 (RAMPyBot - www.giveRAMP.com; http://www.giveramp.com/bot.html; support@giveRAMP.com)", - "RAMPyBot/0.8-dev (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)", - "Rankivabot/3.2 (www.rankiva.com; 3.2; vzmxikn)", - "Rational SiteCheck (Windows NT)", - "Reaper [2.03.10-031204] (http://www.sitesearch.ca/reaper/)", - "Reaper/2.0x (+http://www.sitesearch.ca/reaper)", - "RedCarpet/1.2 (http://www.redcarpet-inc.com/robots.html)", - "RedCell/0.1 (InfoSec Search Bot (Coming Soon); http://www.telegenetic.net/bot.html; lhall@telegenetic.net)", - "RedCell/0.1 (RedCell; telegenetic.net/bot.html; lhall_at_telegenetic.net)", - "RedKernel WWW-Spider 2/0 (+http://www-spider.redkernel-softwares.com/)", - "rico/0.1", - "RixBot (http://babelserver.org/rix)", - "RoboCrawl (http://www.canadiancontent.net)", - "RoboCrawl (www.canadiancontent.net)", - "RoboPal (http://www.findpal.com/)", - "Robot/www.pj-search.com", - "Robot: NutchCrawler- Owner: wdavies@acm.org", - "Robot@SuperSnooper.Com", - "Robozilla/1.0", - "Rotondo/3.1 libwww/5.3.1", - "RRC (crawler_admin@bigfoot.com)", - "RSSMicro.com RSS/Atom Feed Robot", - "RSurf15a 41", - "RSurf15a 51", - "RSurf15a 81", - "RufusBot (Rufus Web Miner; http://64.124.122.252/feedback.html)", - "RufusBot (Rufus Web Miner; http://www.webaroo.com/rooSiteOwners.html)", - "sait/Nutch-0.9 (SAIT Research; http://www.samsung.com)", - "SandCrawler - Compatibility Testing", - "SapphireWebCrawler/1.0 (Sapphire Web Crawler using Nutch; http://boston.lti.cs.cmu.edu/crawler/; mhoy@cs.cmu.edu)", - "SapphireWebCrawler/Nutch-1.0-dev (Sapphire Web Crawler using Nutch; http://boston.lti.cs.cmu.edu/crawler/; mhoy@cs.cmu.edu)", - "savvybot/0.2", - "SBIder/0.7 (SBIder; http://www.sitesell.com/sbider.html; http://support.sitesell.com/contact-support.html)", - "SBIder/0.8-dev (SBIder; http://www.sitesell.com/sbider.html; http://support.sitesell.com/contact-support.html)", - "ScanWeb", - "ScholarUniverse/0.8 (Nutch;+http://scholaruniverse.com/bot.jsp; fetch-agent@scholaruniverse.com)", - "schwarzmann.biz-Spider_for_paddel.org+(http://www.innerprise.net/usp-spider.asp)", - "ScollSpider/2.0 (+http://www.webwobot.com/ScollSpider.php)", - "Scooter-3.0.EU", - "Scooter-3.0.FS", - "Scooter-3.0.HD", - "Scooter-3.0.VNS", - "Scooter-3.0QI", - "Scooter-3.2", - "Scooter-3.2.BT", - "Scooter-3.2.DIL", - "Scooter-3.2.EX", - "Scooter-3.2.JT", - "Scooter-3.2.NIV", - "Scooter-3.2.SF0", - "Scooter-3.2.snippet", - "Scooter-3.3dev", - "Scooter-ARS-1.1", - "Scooter-ARS-1.1-ih", - "scooter-venus-3.0.vns", - "Scooter-W3-1.0", - "Scooter-W3.1.2", - "Scooter/1.0", - "Scooter/1.0 scooter@pa.dec.com", - "Scooter/1.1 (custom)", - "Scooter/2.0 G.R.A.B. V1.1.0", - "Scooter/2.0 G.R.A.B. X2.0", - "Scooter/3.3", - "Scooter/3.3.QA.pczukor", - "Scooter/3.3.vscooter", - "Scooter/3.3_SF", - "Scooter2_Mercator_x-x.0", - "Scooter_bh0-3.0.3", - "Scooter_trk3-3.0.3", - "ScoutAbout", - "ScoutAnt/0.1; +http://www.ant.com/what_is_ant.com/", - "scoutmaster", - "Scrubby/2.x (http://www.scrubtheweb.com/)", - "Scrubby/3.0 (+http://www.scrubtheweb.com/help/technology.html)", - "Search+", - "Search-Engine-Studio", - "search.ch V1.4", - "search.ch V1.4.2 (spiderman@search.ch; http://www.search.ch)", - "Search/1.0 (http://www.innerprise.net/es-spider.asp)", - "searchbot admin@google.com", - "SearchByUsa/2 (SearchByUsa; http://www.SearchByUsa.com/bot.html; info@SearchByUsa.com)", - "SearchdayBot", - "SearchExpress Spider0.99", - "SearchGuild/DMOZ/Experiment (searchguild@gmail.com)", - "SearchGuild_DMOZ_Experiment (chris@searchguild.com)", - "Searchit-Now Robot/2.2 (+http://www.searchit-now.co.uk)", - "Searchmee! Spider v0.98a", - "SearchSight/2.0 (http://SearchSight.com/)", - "SearchSpider.com/1.1", - "Searchspider/1.2 (SearchSpider; http://www.searchspider.com; webmaster@searchspider.com)", - "SearchTone2.0 - IDEARE", - "Seekbot/1.0 (http://www.seekbot.net/bot.html) HTTPFetcher/0.3", - "Seekbot/1.0 (http://www.seekbot.net/bot.html) RobotsTxtFetcher/1.0 (XDF)", - "Seekbot/1.0 (http://www.seekbot.net/bot.html) RobotsTxtFetcher/1.2", - "Seeker.lookseek.com", - "Semager/1.1 (http://www.semager.de/blog/semager-bots/)", - "Semager/1.x (http://www.semager.de)", - "Sensis Web Crawler (search_comments\\at\\sensis\\dot\\com\\dot\\au)", - "Sensis.com.au Web Crawler (search_comments\\at\\sensis\\dot\\com\\dot\\au)", - "SeznamBot/1.0", - "SeznamBot/1.0 (+http://fulltext.seznam.cz/)", - "SeznamBot/2.0-test (+http://fulltext.sblog.cz/)", - "ShablastBot 1.0", - "Shim Crawler", - "Shim-Crawler(Mozilla-compatible; http://www.logos.ic.i.u-tokyo.ac.jp/crawler/; crawl@logos.ic.i.u-tokyo.ac.jp)", - "ShopWiki/1.0 ( +http://www.shopwiki.com/)", - "ShopWiki/1.0 ( +http://www.shopwiki.com/wiki/Help:Bot)", - "Shoula.com Crawler 2.0", - "SietsCrawler/1.1 (+http://www.siets.biz)", - "Sigram/Nutch-1.0-dev (Test agent for Nutch development; http://www.sigram.com/bot.html; bot at sigram dot com)", - "Siigle Orumcex v.001 Turkey (http://www.siigle.com)", - "silk/1.0", - "silk/1.0 (+http://www.slider.com/silk.htm)/3.7", - "Sirketcebot/v.01 (http://www.sirketce.com/bot.html)", - "SiteSpider +(http://www.SiteSpider.com/)", - "SiteTruth.com site rating system", - "SiteXpert", - "Skampy/0.9.x (http://www.skaffe.com/skampy-info.html)", - "Skimpy/0.x (http://www.skaffe.com/skampy-info.html)", - "Skywalker/0.1 (Skywalker; anonymous; anonymous)", - "Slarp/0.1", - "Slider_Search_v1-de", - "Slurp/2.0 (slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Slurp/2.0-KiteWeekly (slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Slurp/si (slurp@inktomi.com; http://www.inktomi.com/slurp.html)", - "Slurpy Verifier/1.0", - "SlySearch (slysearch@slysearch.com)", - "SlySearch/1.0 http://www.plagiarism.org/crawler/robotinfo.html", - "SlySearch/1.x http://www.slysearch.com", - "smartwit.com", - "SmiffyDCMetaSpider/1.0", - "snap.com beta crawler v0", - "Snapbot/1.0", - "Snapbot/1.0 (Snap Shots, +http://www.snap.com)", - "SnykeBot/0.6 (http://www.snyke.com)", - "SocSciBot ()", - "SoftHypermarketFileCheckBot/1.0+(+http://www.softhypermaket.com)", - "sogou develop spider", - "Sogou Orion spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", - "sogou spider", - "Sogou web spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", - "sohu agent", - "sohu-search", - "Sosospider+(+http://help.soso.com/webspider.htm)", - "speedfind ramBot xtreme 8.1", - "Speedy Spider (Beta/x.x; speedy@entireweb.com)", - "Speedy Spider (Entireweb; Beta/1.0; http://www.entireweb.com/about/search_tech/speedyspider/)", - "Speedy_Spider (http://www.entireweb.com)", - "Sphere Scout&v4.0 - scout at sphere dot com", - "Sphider", - "Spida/0.1", - "Spider-Sleek/2.0 (+http://search-info.com/linktous.html)", - "spider.batsch.com", - "spider.yellopet.com - www.yellopet.com", - "Spider/maxbot.com admin@maxbot.com", - "SpiderKU/0.x", - "SpiderMan", - "SpiderMonkey/7.0x (SpiderMonkey.ca info at http://spidermonkey.ca/sm.shtml)", - "Spinne/2.0", - "Spinne/2.0 med", - "Spinne/2.0 med_AH", - "Spock Crawler (http://www.spock.com/crawler)", - "sportsuchmaschine.de-Robot (Version: 1.02- powered by www.sportsuchmaschine.de)", - "sproose/0.1-alpha (sproose crawler; http://www.sproose.com/bot.html; crawler@sproose.com)", - "Sqworm/2.9.81-BETA (beta_release; 20011102-760; i686-pc-linux-gnu)", - "Sqworm/2.9.85-BETA (beta_release; 20011115-775; i686-pc-linux-gnu)", - "SSurf15a 11 ", - "StackRambler/x.x ", - "stat statcrawler@gmail.com", - "Steeler/1.x (http://www.tkl.iis.u-tokyo.ac.jp/~crawler/)", - "Steeler/3.3 (http://www.tkl.iis.u-tokyo.ac.jp/~crawler/)", - "Strategic Board Bot (+http://www.strategicboard.com)", - "Strategic Board Bot (+http://www.strategicboard.com)", - "Submission Spider at surfsafely.com", - "suchbaer.de", - "suchbaer.de (CrawlerAgent v0.103)", - "suchbot", - "Suchknecht.at-Robot", - "suchpadbot/1.0 (+http://www.suchpad.de)", - "SurferF3 1/0", - "suzuran", - "Swooglebot/2.0. (+http://swoogle.umbc.edu/swooglebot.htm)", - "SWSBot-Images/1.2 http://www.smartwaresoft.com/swsbot12.html", - "SygolBot http://www.sygol.net", - "SynoBot", - "Syntryx ANT Scout Chassis Pheromone; Mozilla/4.0 compatible crawler", - "Szukacz/1.x", - "Szukacz/1.x (robot; www.szukacz.pl/jakdzialarobot.html; szukacz@proszynski.pl)", - "tags2dir.com/0.8 (+http://tags2dir.com/directory/)", - "Tagword (http://tagword.com/dmoz_survey.php)", - "Talkro Web-Shot/1.0 (E-mail: webshot@daumsoft.com- Home: http://222.122.15.190/webshot)", - "TCDBOT/Nutch-0.8 (PhD student research;http://www.tcd.ie; mcgettrs at t c d dot IE)", - "TECOMAC-Crawler/0.x", - "Tecomi Bot (http://www.tecomi.com/bot.htm)", - "Teemer (NetSeer, Inc. is a Los Angeles based Internet startup company.; http://www.netseer.com/crawler.html; crawler@netseer.com)", - "Teoma MP", - "teomaagent crawler-admin@teoma.com", - "teomaagent1 [crawler-admin@teoma.com]", - "teoma_agent1", - "Teradex Mapper; mapper@teradex.com; http://www.teradex.com", - "terraminds-bot/1.0 (support@terraminds.de)", - "TerrawizBot/1.0 (+http://www.terrawiz.com/bot.html)", - "Test spider", - "TestCrawler/Nutch-0.9 (Testing Crawler for Research ; http://balihoo.com/index.aspx; tgautier at balihoo dot com)", - "TheRarestParser/0.2a (http://therarestwords.com/)", - "TheSuBot/0.1 (www.thesubot.de)", - "thumbshots-de-Bot (Version: 1.02- powered by www.thumbshots.de)", - "timboBot/0.9 http://www.breakingblogs.com/timbo_bot.html", - "TinEye/1.1 (http://tineye.com/crawler.html)", - "tivraSpider/1.0 (crawler@tivra.com)", - "TJG/Spider", - "Tkensaku/x.x(http://www.tkensaku.com/q.html)", - "Topodia/1.2-dev (Topodia - Crawler for HTTP content indexing; http://www.topodia.com/; support@topodia.com)", - "Toutatis x-xx.x (hoppa.com)", - "Toutatis x.x (hoppa.com)", - "Toutatis x.x-x", - "traazibot/testengine (+http://www.traazi.de)", - "Trampelpfad-Spider", - "Trampelpfad-Spider-v0.1", - "TSurf15a 11", - "Tumblr/1.0 RSS syndication (+http://www.tumblr.com/) (support@tumblr.com)", - "TurnitinBot/x.x (http://www.turnitin.com/robot/crawlerinfo.html)", - "Turnpike Emporium LinkChecker/0.1", - "TutorGig/1.5 (+http://www.tutorgig.com/crawler)", - "Tutorial Crawler 1.4 (http://www.tutorgig.com/crawler)", - "Twiceler www.cuill.com/robots.html", - "Twiceler-0.9 http://www.cuill.com/twiceler/robot.html", - "Tycoon Agent/Nutch-1.0-dev", - "TygoBot", - "TygoProwler", - "UIowaCrawler/1.0", - "UKWizz/Nutch-0.8.1 (UKWizz Nutch crawler; http://www.ukwizz.com/)", - "Ultraseek", - "Under the Rainbow 2.2", - "UofTDB_experiment (leehyun@cs.toronto.edu)", - "updated/0.1-alpha (updated crawler; http://www.updated.com; crawler@updated.com)", - "updated/0.1beta (updated.com; http://www.updated.com; crawler@updated.om)", - "Uptimebot", - "UptimeBot(www.uptimebot.com)", - "URL Spider Pro/x.xx (innerprise.net)", - "urlfan-bot/1.0; +http://www.urlfan.com/site/bot/350.html", - "URL_Spider_Pro/x.x", - "URL_Spider_Pro/x.x+(http://www.innerprise.net/usp-spider.asp)", - "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", - "User-Agent: Mozilla/4.0 (SKIZZLE! Distributed Internet Spider v1.0 - www.SKIZZLE.com)", - "USyd-NLP-Spider (http://www.it.usyd.edu.au/~vinci/bot.html)", - "VadixBot", - "Vagabondo-WAP/2.0 (webcrawler at wise-guys dot nl; http://webagent.wise-guys.nl/)/1.0 Profile", - "Vagabondo/1.x MT (webagent@wise-guys.nl)", - "Vagabondo/2.0 MT", - "Vagabondo/2.0 MT (webagent at wise-guys dot nl)", - "Vagabondo/2.0 MT (webagent@NOSPAMwise-guys.nl)", - "Vagabondo/3.0 (webagent at wise-guys dot nl)", - "Vakes/0.01 (Vakes; http://www.vakes.com/; search@vakes.com)", - "versus 0.2 (+http://versus.integis.ch)", - "versus crawler eda.baykan@epfl.ch", - "VeryGoodSearch.com.DaddyLongLegs", - "verzamelgids.nl - Networking4all Bot/x.x", - "Verzamelgids/2.2 (http://www.verzamelgids.nl)", - "Vespa Crawler", - "VisBot/2.0 (Visvo.com Crawler; http://www.visvo.com/bot.html; bot@visvo.com)", - "Vision Research Lab image spider at vision.ece.ucsb.edu", - "VMBot/0.x.x (VMBot; http://www.VerticalMatch.com/; vmbot@tradedot.com)", - "Vortex/2.2 (+http://marty.anstey.ca/robots/vortex/)", - "voyager-hc/1.0", - "voyager/1.0", - "voyager/2.0 (http://www.kosmix.com/html/crawler.html)", - "VSE/1.0 (testcrawler@hotmail.com)", - "VSE/1.0 (testcrawler@vivisimo.com)", - "vspider", - "vspider/3.x", - "VWBOT/Nutch-0.9-dev (VWBOT Nutch Crawler; http://vwbot.cs.uiuc.edu;+vwbot@cs.uiuc.edu", - "W3SiteSearch Crawler_v1.1 http://www.w3sitesearch.de", - "wadaino.jp-crawler 0.2 (http://wadaino.jp/)", - "Wavefire/0.8-dev (Wavefire; http://www.wavefire.com; info@wavefire.com)", - "Waypath development crawler - info at waypath dot com", - "Waypath Scout v2.x - info at waypath dot com", - "Web Snooper", - "web2express.org/Nutch-0.9-dev (leveled playing field; http://web2express.org/; info at web2express.org)", - "WebAlta Crawler/1.2.1 (http://www.webalta.ru/bot.html)", - "WebarooBot (Webaroo Bot; http://64.124.122.252/feedback.html)", - "WebarooBot (Webaroo Bot; http://www.webaroo.com/rooSiteOwners.html)", - "webbandit/4.xx.0", - "Webclipping.com", - "WebCompass 2.0", - "WebCorp/1.0", - "webcrawl.net", - "WebFindBot(http://www.web-find.com)", - "Webglimpse 2.xx.x (http://webglimpse.net)", - "Weblog Attitude Diffusion 1.0", - "webmeasurement-bot, http://rvs.informatik.uni-leipzig.de", - "WebRankSpider/1.37 (+http://ulm191.server4you.de/crawler/)", - "WebSearch.COM.AU/3.0.1 (The Australian Search Engine; http://WebSearch.COM.AU; Search@WebSearch.COM.AU)", - "WebSearchBench WebCrawler v0.1(Experimental)", - "WebsiteWorth v1.0", - "Webspinne/1.0 webmaster@webspinne.de", - "Websquash.com (Add url robot)", - "WebStat/1.0 (Unix; beta; 20040314)", - "Webster v0.3 ( http://webster.healeys.net/ )", - "WebVac (webmaster@pita.stanford.edu)", - "Webverzeichnis.de - Telefon: 01908 / 26005", - "WebVulnCrawl.unknown/1.0 libwww-perl/5.803", - "Wells Search II", - "WEP Search 00", - "WFARC", - "whatUseek_winona/3.0", - "WhizBang! Lab", - "Willow Internet Crawler by Twotrees V2.1", - "WinHTTP Example/1.0", - "WinkBot/0.06 (Wink.com search engine web crawler; http://www.wink.com/Wink:WinkBot; winkbot@wink.com)", - "WIRE/0.11 (Linux; i686; Bot,Robot,Spider,Crawler,aromano@cli.di.unipi.it)", - "WIRE/0.x (Linux; i686; Bot,Robot,Spider,Crawler)", - "WISEbot/1.0 (WISEbot@koreawisenut.com; http://wisebot.koreawisenut.com)", - "worio heritrix bot (+http://worio.com/)", - "woriobot ( http://www.worio.com/)", - "WorldLight", - "Wotbox/alpha0.6 (bot@wotbox.com; http://www.wotbox.com)", - "Wotbox/alpha0.x.x (bot@wotbox.com; http://www.wotbox.com) Java/1.4.1_02", - "WSB WebCrawler V1.0 (Beta)- cl@cs.uni-dortmund.de", - "WSB, http://websearchbench.cs.uni-dortmund.de", - "wume_crawler/1.1 (http://wume.cse.lehigh.edu/~xiq204/crawler/)", - "Wwlib/Linux", - "www.arianna.it", - "WWWeasel Robot v1.00 (http://wwweasel.de)", - "wwwster/1.x (Beta- mailto:gue@cis.uni-muenchen.de)", - "X-Crawler ", - "xirq/0.1-beta (xirq; http://www.xirq.com; xirq@xirq.com)", - "xyro_(xcrawler@cosmos.inria.fr)", - "Y!J-BSC/1.0 (http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html)", - "Y!J-SRD/1.0", - "Y!J/1.0 (http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html)", - "yacy (www.yacy.net; v20040602; i386 Linux 2.4.26-gentoo-r13; java 1.4.2_06; MET/en)", - "yacybot (x86 Windows XP 5.1; java 1.5.0_06; Europe/de) yacy.net", - "Yahoo Pipes 1.0", - "Yahoo! Mindset", - "Yahoo-Blogs/v3.9 (compatible; Mozilla 4.0; MSIE 5.5; http://help.yahoo.com/help/us/ysearch/crawling/crawling-02.html )", - "Yahoo-MMAudVid/1.0 (mms dash mmaudvidcrawler dash support at yahoo dash inc dot com)", - "Yahoo-MMAudVid/2.0(mms dash mm aud vid crawler dash support at yahoo dash inc.com ;Mozilla 4.0 compatible; MSIE 7.0;Windows NT 5.0; .NET CLR 2.0)", - "Yahoo-MMCrawler/3.x (mm dash crawler at trd dot overture dot com)", - "Yahoo-Test/4.0", - "Yahoo-VerticalCrawler-FormerWebCrawler/3.9 crawler at trd dot overture dot com; http://www.alltheweb.com/help/webmaster/crawler", - "YahooFeedSeeker/2.0 (compatible; Mozilla 4.0; MSIE 5.5; http://publisher.yahoo.com/rssguide)", - "YahooSeeker-Testing/v3.9 (compatible; Mozilla 4.0; MSIE 5.5; http://search.yahoo.com/)", - "YahooSeeker/1.0 (compatible; Mozilla 4.0; MSIE 5.5; http://help.yahoo.com/help/us/shop/merchant/)", - "YahooSeeker/1.0 (compatible; Mozilla 4.0; MSIE 5.5; http://search.yahoo.com/yahooseeker.html)", - "YahooSeeker/1.1 (compatible; Mozilla 4.0; MSIE 5.5; http://help.yahoo.com/help/us/shop/merchant/)", - "YahooSeeker/bsv3.9 (compatible; Mozilla 4.0; MSIE 5.5; http://help.yahoo.com/help/us/ysearch/crawling/crawling-02.html )", - "YahooSeeker/CafeKelsa-dev (compatible; Konqueror/3.2; FreeBSD ;cafekelsa-dev-webmaster@yahoo-inc.com )", - "Yandex/1.01.001 (compatible; Win16; I)", - "Yanga WorldSearch Bot v1.1/beta (http://www.yanga.co.uk/)", - "yarienavoir.net/0.2", - "Yeti", - "Yeti/0.01 (nhn/1noon, yetibot@naver.com, check robots.txt daily and follows it)", - "Yeti/1.0 (NHN Corp.; http://help.naver.com/robots/)", - "yggdrasil/Nutch-0.9 (yggdrasil biorelated search engine; www dot biotec dot tu minus dresden do de slash schroeder; heiko dot dietze at biotec dot tu minus dresden dot de)", - "YodaoBot/1.0 (http://www.yodao.com/help/webmaster/spider/; )", - "yoofind/yoofind-0.1-dev (yoono webcrawler; http://www.yoono.com ; MyEmail)", - "yoogliFetchAgent/0.1", - "yoono/1.0 web-crawler/1.0", - "YottaCars_Bot/4.12 (+http://www.yottacars.com) Car Search Engine ", - "YottaShopping_Bot/4.12 (+http://www.yottashopping.com) Shopping Search Engine", - "Zao-Crawler", - "Zao-Crawler 0.2b", - "Zao/0.1 (http://www.kototoi.org/zao/)", - "ZBot/1.00 (icaulfield@zeus.com)", - "Zearchit", - "ZeBot_lseek.net (bot@ze.bz)", - "ZeBot_www.ze.bz (ze.bz@hotmail.com)", - "zedzo.digest/0.1 (http://www.zedzo.com/)", - "zermelo Mozilla/5.0 compatible; heritrix/1.12.1 (+http://www.powerset.com) [email:crawl@powerset.com,email:paul@page-store.com]", - "zerxbot/Version 0.6 libwww-perl/5.79", - "Zeus ThemeSite Viewer Webster Pro V2.9 Win32", - "Zeus xxxxx Webster Pro V2.9 Win32", - "Zeusbot/0.07 (Ulysseek's web-crawling robot; http://www.zeusbot.com; agent@zeusbot.com)", - "ZipppBot/0.xx (ZipppBot; http://www.zippp.net; webmaster@zippp.net)", - "ZIPPPCVS/0.xx (ZipppBot/.xx;http://www.zippp.net; webmaster@zippp.net)", - "Zippy v2.0 - Zippyfinder.com", - "ZoomSpider - wrensoft.com", - "zspider/0.9-dev http://feedback.redkolibri.com/", - "ZyBorg/1.0 (ZyBorg@WISEnut.com; http://www.WISEnut.com)"] - end -end diff --git a/vendor/impressionist/impressionist.gemspec b/vendor/impressionist/impressionist.gemspec deleted file mode 100644 index e462fe73..00000000 --- a/vendor/impressionist/impressionist.gemspec +++ /dev/null @@ -1,27 +0,0 @@ -# encoding: utf-8 -require File.expand_path('../lib/impressionist/version', __FILE__) - -Gem::Specification.new do |s| - s.add_dependency 'httpclient', '~> 2.2' - s.add_dependency 'nokogiri', '~> 1.5' - s.add_development_dependency 'capybara' - s.add_development_dependency 'rake', '>= 0.9' - s.add_development_dependency 'rails', '~>3.1' - s.add_development_dependency 'rdoc', '>= 2.4.2' - s.add_development_dependency 'rspec-rails' - s.add_development_dependency 'simplecov' - s.add_development_dependency 'sqlite3' - s.add_development_dependency 'systemu' - s.authors = ["johnmcaliley"] - s.description = "Log impressions from controller actions or from a model" - s.email = "john.mcaliley@gmail.com" - s.files = `git ls-files`.split("\n") - s.homepage = "https://github.com/charlotte-ruby/impressionist" - s.licenses = ["MIT"] - s.name = "impressionist" - s.require_paths = ["lib"] - s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version= - s.summary = "Easy way to log impressions" - s.test_files = `git ls-files -- test_app/*`.split("\n") - s.version = Impressionist::VERSION -end diff --git a/vendor/impressionist/lib/generators/active_record/impressionist_generator.rb b/vendor/impressionist/lib/generators/active_record/impressionist_generator.rb deleted file mode 100644 index 31f4c1a4..00000000 --- a/vendor/impressionist/lib/generators/active_record/impressionist_generator.rb +++ /dev/null @@ -1,21 +0,0 @@ -module ActiveRecord - module Generators - class ImpressionistGenerator < Rails::Generators::Base - include Rails::Generators::Migration - source_root File.join(File.dirname(__FILE__), 'templates') - - def self.next_migration_number(dirname) - sleep 1 - if ActiveRecord::Base.timestamped_migrations - Time.now.utc.strftime("%Y%m%d%H%M%S") - else - "%.3d" % (current_migration_number(dirname) + 1) - end - end - - def create_migration_file - migration_template 'create_impressions_table.rb', 'db/migrate/create_impressions_table.rb' - end - end - end -end diff --git a/vendor/impressionist/lib/generators/active_record/templates/create_impressions_table.rb b/vendor/impressionist/lib/generators/active_record/templates/create_impressions_table.rb deleted file mode 100644 index 5282380c..00000000 --- a/vendor/impressionist/lib/generators/active_record/templates/create_impressions_table.rb +++ /dev/null @@ -1,30 +0,0 @@ -class CreateImpressionsTable < ActiveRecord::Migration - def self.up - create_table :impressions, :force => true do |t| - t.string :impressionable_type - t.integer :impressionable_id - t.integer :user_id - t.string :controller_name - t.string :action_name - t.string :view_name - t.string :request_hash - t.string :ip_address - t.string :session_hash - t.text :message - t.text :referrer - t.timestamps - end - add_index :impressions, [:impressionable_type, :message, :impressionable_id], :name => "impressionable_type_message_index", :unique => false - add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false - add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false - add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false - add_index :impressions, :user_id - end - - def self.down - drop_table :impressions - end -end diff --git a/vendor/impressionist/lib/generators/mongo_mapper/impressionist_generator.rb b/vendor/impressionist/lib/generators/mongo_mapper/impressionist_generator.rb deleted file mode 100644 index eaa1b65c..00000000 --- a/vendor/impressionist/lib/generators/mongo_mapper/impressionist_generator.rb +++ /dev/null @@ -1,8 +0,0 @@ -module MongoMapper - module Generators - class ImpressionistGenerator < Rails::Generators::Base - # Empty for now, need it for generating the config file without - # triggering other ORM's generators. - end - end -end diff --git a/vendor/impressionist/lib/generators/mongoid/impressionist_generator.rb b/vendor/impressionist/lib/generators/mongoid/impressionist_generator.rb deleted file mode 100644 index e56bf904..00000000 --- a/vendor/impressionist/lib/generators/mongoid/impressionist_generator.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Mongoid - module Generators - class ImpressionistGenerator < Rails::Generators::Base - # Empty for now, need it for generating the config file without - # triggering other ORM's generators. - end - end -end diff --git a/vendor/impressionist/lib/impressionist.rb b/vendor/impressionist/lib/impressionist.rb deleted file mode 100644 index 7ead8fe9..00000000 --- a/vendor/impressionist/lib/impressionist.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "impressionist/engine.rb" - -module Impressionist - # Define ORM - mattr_accessor :orm - @@orm = :active_record - - # Load configuration from initializer - def self.setup - yield self - end -end diff --git a/vendor/impressionist/lib/impressionist/bots.rb b/vendor/impressionist/lib/impressionist/bots.rb deleted file mode 100644 index 10d3fd64..00000000 --- a/vendor/impressionist/lib/impressionist/bots.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'httpclient' -require 'nokogiri' - -module Impressionist - module Bots - LIST_URL = "http://www.user-agents.org/allagents.xml" - def self.consume - response = HTTPClient.new.get_content(LIST_URL) - doc = Nokogiri::XML(response) - list = [] - doc.xpath('//user-agent').each do |agent| - type = agent.xpath("Type").text - list << agent.xpath("String").text.gsub("<","<") if ["R","S"].include?(type) #gsub hack for badly formatted data - end - list - end - end -end diff --git a/vendor/impressionist/lib/impressionist/models/active_record/impression.rb b/vendor/impressionist/lib/impressionist/models/active_record/impression.rb deleted file mode 100644 index 94c2710c..00000000 --- a/vendor/impressionist/lib/impressionist/models/active_record/impression.rb +++ /dev/null @@ -1,18 +0,0 @@ -class Impression < ActiveRecord::Base - attr_accessible :impressionable_type, :impressionable_id, :user_id, - :controller_name, :action_name, :view_name, :request_hash, :ip_address, - :session_hash, :message, :referrer - - after_save :update_impressions_counter_cache - - private - - def update_impressions_counter_cache - impressionable_class = self.impressionable_type.constantize - - if impressionable_class.impressionist_counter_cache_options - resouce = impressionable_class.find(self.impressionable_id) - resouce.try(:update_impressionist_counter_cache) - end - end -end diff --git a/vendor/impressionist/lib/impressionist/models/active_record/impressionist/impressionable.rb b/vendor/impressionist/lib/impressionist/models/active_record/impressionist/impressionable.rb deleted file mode 100644 index 6100b886..00000000 --- a/vendor/impressionist/lib/impressionist/models/active_record/impressionist/impressionable.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Impressionist - module Impressionable - extend ActiveSupport::Concern - - module ClassMethods - def is_impressionable(options={}) - has_many :impressions, :as => :impressionable, :dependent => :destroy - @impressionist_cache_options = options[:counter_cache] - end - end - end -end diff --git a/vendor/impressionist/lib/impressionist/models/mongo_mapper/impression.rb b/vendor/impressionist/lib/impressionist/models/mongo_mapper/impression.rb deleted file mode 100644 index a7d5f64c..00000000 --- a/vendor/impressionist/lib/impressionist/models/mongo_mapper/impression.rb +++ /dev/null @@ -1,16 +0,0 @@ -class Impression - include MongoMapper::Document - - key :impressionable_type, String - key :impressionable_id, String - key :user_id, String - key :controller_name, String - key :action_name, String - key :view_name, String - key :request_hash, String - key :ip_address, String - key :session_hash, String - key :message, String - key :referrer, String - timestamps! -end diff --git a/vendor/impressionist/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb b/vendor/impressionist/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb deleted file mode 100644 index 9e0dd524..00000000 --- a/vendor/impressionist/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Impressionist - module Impressionable - extend ActiveSupport::Concern - - module ClassMethods - def is_impressionable(options={}) - many :impressions, :as => :impressionable, :dependent => :destroy - @cache_options = options[:counter_cache] - end - end - end -end diff --git a/vendor/impressionist/lib/impressionist/version.rb b/vendor/impressionist/lib/impressionist/version.rb deleted file mode 100644 index cc644dcd..00000000 --- a/vendor/impressionist/lib/impressionist/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Impressionist - VERSION = "1.1.1" -end diff --git a/vendor/impressionist/logo.png b/vendor/impressionist/logo.png deleted file mode 100644 index 9106036b03e6235342f75ed3e9a3d12ad0420bde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63294 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 z 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 diff --git a/vendor/impressionist/test_app/.gitignore b/vendor/impressionist/test_app/.gitignore deleted file mode 100644 index 351f6382..00000000 --- a/vendor/impressionist/test_app/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile ~/.gitignore_global - -# Ignore bundler config -/.bundle -/Gemfile.lock - -# Ignore the default SQLite database. -/db/*.sqlite3 - -# Ignore all logfiles and tempfiles. -/coverage -/log/*.log -/tmp diff --git a/vendor/impressionist/test_app/.rspec b/vendor/impressionist/test_app/.rspec deleted file mode 100644 index 4e1e0d2f..00000000 --- a/vendor/impressionist/test_app/.rspec +++ /dev/null @@ -1 +0,0 @@ ---color diff --git a/vendor/impressionist/test_app/Gemfile b/vendor/impressionist/test_app/Gemfile deleted file mode 100644 index 67f8bb24..00000000 --- a/vendor/impressionist/test_app/Gemfile +++ /dev/null @@ -1,59 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', '3.2.2' - -gem 'impressionist', :path => '../' - -platforms :jruby do - gem 'activerecord-jdbcsqlite3-adapter' - gem 'jdbc-sqlite3' - gem 'jruby-openssl' -end - -platforms :ruby, :mswin, :mingw do - gem 'pg' - gem 'sqlite3' -end - -gem 'json' - -# Gems used only for assets and not required -# in production environments by default. -group :assets do - gem 'sass-rails', '~> 3.2.3' - gem 'coffee-rails', '~> 3.2.1' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - # gem 'therubyracer' - - gem 'uglifier', '>= 1.0.3' -end - -group :development, :test do - gem 'autotest-notification' - gem 'rspec-rails' - gem 'spork' -end - -group :test do - gem 'capybara' - gem 'simplecov' - gem 'systemu' -end - -gem 'jquery-rails' - -# To use ActiveModel has_secure_password -# gem 'bcrypt-ruby', '~> 3.0.0' - -# To use Jbuilder templates for JSON -# gem 'jbuilder' - -# Use unicorn as the app server -# gem 'unicorn' - -# Deploy with Capistrano -# gem 'capistrano' - -# To use debugger -# gem 'ruby-debug' diff --git a/vendor/impressionist/test_app/README b/vendor/impressionist/test_app/README deleted file mode 100644 index fe7013d5..00000000 --- a/vendor/impressionist/test_app/README +++ /dev/null @@ -1,256 +0,0 @@ -== Welcome to Rails - -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 -methods. You can read more about Active Record in -link:files/vendor/rails/activerecord/README.html. - -The controller and view are handled by the Action Pack, which handles both -layers by its two parts: Action View and Action Controller. These two layers -are bundled in a single package due to their heavy interdependence. This is -unlike the relationship between the Active Record and Action Pack that is much -more separate. Each of these packages can be used independently outside of -Rails. You can read more about Action Pack in -link:files/vendor/rails/actionpack/README.html. - - -== Getting Started - -1. At the command prompt, create a new Rails application: - rails new myapp (where myapp is the application name) - -2. Change directory to myapp and start the web server: - cd myapp; rails server (run with --help for options) - -3. Go to http://localhost:3000/ and you'll see: - "Welcome aboard: You're riding Ruby on Rails!" - -4. Follow the guidelines to start developing your application. You can find -the following resources handy: - -* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html -* Ruby on Rails Tutorial Book: http://www.railstutorial.org/ - - -== Debugging Rails - -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. - -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: - - class WeblogController < ActionController::Base - def destroy - @weblog = Weblog.find(params[:id]) - @weblog.destroy - logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") - 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/. There are -several books available online as well: - -* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) -* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) - -These two 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 sudo gem install ruby-debug. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.find(:all) - debugger - end - end - -So the controller will accept the action, run the first line, then present you -with a IRB prompt in the server window. Here you can do things like: - - >> @posts.inspect - => "[#nil, "body"=>nil, "id"=>"1"}>, - #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" - >> @posts.first.title = "hello from a debugger" - => "hello from a debugger" - -...and even better, you can examine how your runtime objects actually work: - - >> f = @posts.first - => #nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - -Finally, when you're ready to resume execution, you can enter "cont". - - -== Console - -The console is a Ruby shell, which allows you to interact with your -application's domain model. Here you'll have all parts of the application -configured, just like it is when the application is running. You can inspect -domain models, change values, and save to the database. Starting the script -without arguments will launch it in the development environment. - -To start the console, run rails console from the application -directory. - -Options: - -* Passing the -s, --sandbox argument will rollback any modifications - made to the database. -* Passing an environment name as an argument will load the corresponding - environment. Example: rails console production. - -To reload your controllers and models after launching the console run -reload! - -More information about irb can be found at: -link:http://www.rubycentral.com/pickaxe/irb.html - - -== dbconsole - -You can go to the command line of your database directly through rails -dbconsole. 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 rails dbconsole production. Currently works for MySQL, -PostgreSQL and SQLite 3. - -== Description of Contents - -The default directory structure of a generated Ruby on Rails application: - - |-- app - | |-- controllers - | |-- helpers - | |-- mailers - | |-- models - | `-- views - | `-- layouts - |-- config - | |-- environments - | |-- initializers - | `-- locales - |-- db - |-- doc - |-- lib - | `-- tasks - |-- log - |-- public - | |-- images - | |-- javascripts - | `-- stylesheets - |-- script - |-- test - | |-- fixtures - | |-- functional - | |-- integration - | |-- performance - | `-- unit - |-- tmp - | |-- cache - | |-- pids - | |-- sessions - | `-- sockets - `-- vendor - `-- plugins - -app - Holds all the code that's specific to this particular application. - -app/controllers - Holds controllers that should be named like weblogs_controller.rb for - automated URL mapping. All controllers should descend from - ApplicationController which itself descends from ActionController::Base. - -app/models - Holds models that should be named like post.rb. Models descend from - ActiveRecord::Base by default. - -app/views - Holds the template files for the view that should be named like - weblogs/index.html.erb for the WeblogsController#index action. All views use - eRuby syntax by default. - -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 layout :default and create a file named default.html.erb. - Inside default.html.erb, call <% yield %> to render the view using this - layout. - -app/helpers - Holds view helpers that should be named like weblogs_helper.rb. These are - generated for you automatically when using generators for controllers. - Helpers can be used to wrap functionality for your views into methods. - -config - Configuration files for the Rails environment, the routing map, the database, - and other dependencies. - -db - Contains the database schema in schema.rb. db/migrate contains all the - sequence of Migrations for your schema. - -doc - This directory is where your application documentation will be stored when - generated using rake doc:app - -lib - Application specific libraries. Basically, any kind of custom code that - doesn't belong under controllers, models, or helpers. This directory is in - the load path. - -public - The directory available for the web server. Contains subdirectories for - images, stylesheets, and javascripts. Also contains the dispatchers and the - default HTML files. This should be set as the DOCUMENT_ROOT of your web - server. - -script - Helper scripts for automation and generation. - -test - Unit and functional tests along with fixtures. When using the rails generate - command, template test files will be generated for you and placed in this - directory. - -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. diff --git a/vendor/impressionist/test_app/README.rdoc b/vendor/impressionist/test_app/README.rdoc deleted file mode 100644 index 7c36f235..00000000 --- a/vendor/impressionist/test_app/README.rdoc +++ /dev/null @@ -1,261 +0,0 @@ -== Welcome to Rails - -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 -methods. You can read more about Active Record in -link:files/vendor/rails/activerecord/README.html. - -The controller and view are handled by the Action Pack, which handles both -layers by its two parts: Action View and Action Controller. These two layers -are bundled in a single package due to their heavy interdependence. This is -unlike the relationship between the Active Record and Action Pack that is much -more separate. Each of these packages can be used independently outside of -Rails. You can read more about Action Pack in -link:files/vendor/rails/actionpack/README.html. - - -== Getting Started - -1. At the command prompt, create a new Rails application: - rails new myapp (where myapp is the application name) - -2. Change directory to myapp and start the web server: - cd myapp; rails server (run with --help for options) - -3. Go to http://localhost:3000/ and you'll see: - "Welcome aboard: You're riding Ruby on Rails!" - -4. Follow the guidelines to start developing your application. You can find -the following resources handy: - -* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html -* Ruby on Rails Tutorial Book: http://www.railstutorial.org/ - - -== Debugging Rails - -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. - -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: - - class WeblogController < ActionController::Base - def destroy - @weblog = Weblog.find(params[:id]) - @weblog.destroy - logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") - 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/. There are -several books available online as well: - -* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) -* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) - -These two 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 sudo gem install ruby-debug. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.all - debugger - end - end - -So the controller will accept the action, run the first line, then present you -with a IRB prompt in the server window. Here you can do things like: - - >> @posts.inspect - => "[#nil, "body"=>nil, "id"=>"1"}>, - #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" - >> @posts.first.title = "hello from a debugger" - => "hello from a debugger" - -...and even better, you can examine how your runtime objects actually work: - - >> f = @posts.first - => #nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - -Finally, when you're ready to resume execution, you can enter "cont". - - -== Console - -The console is a Ruby shell, which allows you to interact with your -application's domain model. Here you'll have all parts of the application -configured, just like it is when the application is running. You can inspect -domain models, change values, and save to the database. Starting the script -without arguments will launch it in the development environment. - -To start the console, run rails console from the application -directory. - -Options: - -* Passing the -s, --sandbox argument will rollback any modifications - made to the database. -* Passing an environment name as an argument will load the corresponding - environment. Example: rails console production. - -To reload your controllers and models after launching the console run -reload! - -More information about irb can be found at: -link:http://www.rubycentral.org/pickaxe/irb.html - - -== dbconsole - -You can go to the command line of your database directly through rails -dbconsole. 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 rails dbconsole production. Currently works for MySQL, -PostgreSQL and SQLite 3. - -== Description of Contents - -The default directory structure of a generated Ruby on Rails application: - - |-- app - | |-- assets - | |-- images - | |-- javascripts - | `-- stylesheets - | |-- controllers - | |-- helpers - | |-- mailers - | |-- models - | `-- views - | `-- layouts - |-- config - | |-- environments - | |-- initializers - | `-- locales - |-- db - |-- doc - |-- lib - | `-- tasks - |-- log - |-- public - |-- script - |-- test - | |-- fixtures - | |-- functional - | |-- integration - | |-- performance - | `-- unit - |-- tmp - | |-- cache - | |-- pids - | |-- sessions - | `-- sockets - `-- vendor - |-- assets - `-- stylesheets - `-- plugins - -app - Holds all the code that's specific to this particular application. - -app/assets - Contains subdirectories for images, stylesheets, and JavaScript files. - -app/controllers - Holds controllers that should be named like weblogs_controller.rb for - automated URL mapping. All controllers should descend from - ApplicationController which itself descends from ActionController::Base. - -app/models - Holds models that should be named like post.rb. Models descend from - ActiveRecord::Base by default. - -app/views - Holds the template files for the view that should be named like - weblogs/index.html.erb for the WeblogsController#index action. All views use - eRuby syntax by default. - -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 layout :default and create a file named default.html.erb. - Inside default.html.erb, call <% yield %> to render the view using this - layout. - -app/helpers - Holds view helpers that should be named like weblogs_helper.rb. These are - generated for you automatically when using generators for controllers. - Helpers can be used to wrap functionality for your views into methods. - -config - Configuration files for the Rails environment, the routing map, the database, - and other dependencies. - -db - Contains the database schema in schema.rb. db/migrate contains all the - sequence of Migrations for your schema. - -doc - This directory is where your application documentation will be stored when - generated using rake doc:app - -lib - Application specific libraries. Basically, any kind of custom code that - doesn't belong under controllers, models, or helpers. This directory is in - the load path. - -public - The directory available for the web server. Also contains the dispatchers and the - default HTML files. This should be set as the DOCUMENT_ROOT of your web - server. - -script - Helper scripts for automation and generation. - -test - Unit and functional tests along with fixtures. When using the rails generate - command, template test files will be generated for you and placed in this - directory. - -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. diff --git a/vendor/impressionist/test_app/Rakefile b/vendor/impressionist/test_app/Rakefile deleted file mode 100644 index 9946cea6..00000000 --- a/vendor/impressionist/test_app/Rakefile +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env rake -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require File.expand_path('../config/application', __FILE__) - -TestApp::Application.load_tasks diff --git a/vendor/impressionist/test_app/app/assets/images/rails.png b/vendor/impressionist/test_app/app/assets/images/rails.png deleted file mode 100644 index d5edc04e65f555e3ba4dcdaad39dc352e75b575e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6646 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 AQ~&?~ diff --git a/vendor/impressionist/test_app/app/assets/javascripts/application.js b/vendor/impressionist/test_app/app/assets/javascripts/application.js deleted file mode 100644 index 9097d830..00000000 --- a/vendor/impressionist/test_app/app/assets/javascripts/application.js +++ /dev/null @@ -1,15 +0,0 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// the compiled file. -// -// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD -// GO AFTER THE REQUIRES BELOW. -// -//= require jquery -//= require jquery_ujs -//= require_tree . diff --git a/vendor/impressionist/test_app/app/assets/stylesheets/application.css b/vendor/impressionist/test_app/app/assets/stylesheets/application.css deleted file mode 100644 index 3b5cc664..00000000 --- a/vendor/impressionist/test_app/app/assets/stylesheets/application.css +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the top of the - * compiled file, but it's generally better to create a new file per style scope. - * - *= require_self - *= require_tree . -*/ diff --git a/vendor/impressionist/test_app/app/controllers/application_controller.rb b/vendor/impressionist/test_app/app/controllers/application_controller.rb deleted file mode 100644 index 1ce61fa1..00000000 --- a/vendor/impressionist/test_app/app/controllers/application_controller.rb +++ /dev/null @@ -1,8 +0,0 @@ -class ApplicationController < ActionController::Base - protect_from_forgery - before_filter :secondary_before_filter - - def secondary_before_filter - @test_secondary_before_filter = "this is a test" - end -end diff --git a/vendor/impressionist/test_app/app/controllers/articles_controller.rb b/vendor/impressionist/test_app/app/controllers/articles_controller.rb deleted file mode 100644 index 367b460f..00000000 --- a/vendor/impressionist/test_app/app/controllers/articles_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -class ArticlesController < ApplicationController - before_filter :test_current_user_var - - def test_current_user_var - if session[:user_id] - @current_user = User.new - @current_user.id = session[:user_id] - end - end - - def index - impressionist(Article.first,"this is a test article impression") - end - - def show - impressionist(Article.first) - end -end diff --git a/vendor/impressionist/test_app/app/controllers/dummy_controller.rb b/vendor/impressionist/test_app/app/controllers/dummy_controller.rb deleted file mode 100644 index 86664a67..00000000 --- a/vendor/impressionist/test_app/app/controllers/dummy_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This controller imports the impressionist module to make the modules methods available for testing -class DummyController < ActionController::Base - - impressionist - -end diff --git a/vendor/impressionist/test_app/app/controllers/posts_controller.rb b/vendor/impressionist/test_app/app/controllers/posts_controller.rb deleted file mode 100644 index 35262709..00000000 --- a/vendor/impressionist/test_app/app/controllers/posts_controller.rb +++ /dev/null @@ -1,23 +0,0 @@ -class PostsController < ApplicationController - helper_method :current_user - impressionist - def index - - end - - def show - - end - - def edit - - end - - def current_user - if session[:user_id] - user = User.new - user.id = session[:user_id] - @current_user ||= user - end - end -end diff --git a/vendor/impressionist/test_app/app/controllers/widgets_controller.rb b/vendor/impressionist/test_app/app/controllers/widgets_controller.rb deleted file mode 100644 index b6b99a72..00000000 --- a/vendor/impressionist/test_app/app/controllers/widgets_controller.rb +++ /dev/null @@ -1,12 +0,0 @@ -class WidgetsController < ApplicationController - impressionist :actions=>[:show,:index], :unique => [:controller_name,:action_name,:impressionable_id] - - def show - end - - def index - end - - def new - end -end diff --git a/vendor/impressionist/test_app/app/helpers/application_helper.rb b/vendor/impressionist/test_app/app/helpers/application_helper.rb deleted file mode 100644 index de6be794..00000000 --- a/vendor/impressionist/test_app/app/helpers/application_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module ApplicationHelper -end diff --git a/vendor/impressionist/test_app/app/mailers/.gitkeep b/vendor/impressionist/test_app/app/mailers/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/models/.gitkeep b/vendor/impressionist/test_app/app/models/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/models/article.rb b/vendor/impressionist/test_app/app/models/article.rb deleted file mode 100644 index 0a18546d..00000000 --- a/vendor/impressionist/test_app/app/models/article.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Article < ActiveRecord::Base - is_impressionable -end diff --git a/vendor/impressionist/test_app/app/models/dummy.rb b/vendor/impressionist/test_app/app/models/dummy.rb deleted file mode 100644 index 745c60aa..00000000 --- a/vendor/impressionist/test_app/app/models/dummy.rb +++ /dev/null @@ -1,7 +0,0 @@ -# We don't really care about this model. It's just being used to test the uniqueness controller -# specs. Nevertheless, we need a model because the counter caching functionality expects it. -# -class Dummy < ActiveRecord::Base - self.abstract_class = true # doesn't need to be backed by an actual table - is_impressionable -end diff --git a/vendor/impressionist/test_app/app/models/post.rb b/vendor/impressionist/test_app/app/models/post.rb deleted file mode 100644 index ccc43dac..00000000 --- a/vendor/impressionist/test_app/app/models/post.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Post < ActiveRecord::Base - is_impressionable -end diff --git a/vendor/impressionist/test_app/app/models/user.rb b/vendor/impressionist/test_app/app/models/user.rb deleted file mode 100644 index 6da0f650..00000000 --- a/vendor/impressionist/test_app/app/models/user.rb +++ /dev/null @@ -1,3 +0,0 @@ -class User - attr_accessor :id -end diff --git a/vendor/impressionist/test_app/app/models/widget.rb b/vendor/impressionist/test_app/app/models/widget.rb deleted file mode 100644 index 51bab18d..00000000 --- a/vendor/impressionist/test_app/app/models/widget.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Widget < ActiveRecord::Base - is_impressionable :counter_cache => true -end diff --git a/vendor/impressionist/test_app/app/views/articles/index.html.erb b/vendor/impressionist/test_app/app/views/articles/index.html.erb deleted file mode 100644 index 97e10f82..00000000 --- a/vendor/impressionist/test_app/app/views/articles/index.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%=@impressionist_hash==nil%> diff --git a/vendor/impressionist/test_app/app/views/articles/show.html.erb b/vendor/impressionist/test_app/app/views/articles/show.html.erb deleted file mode 100644 index 7dc920f3..00000000 --- a/vendor/impressionist/test_app/app/views/articles/show.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%=link_to "Same Page", article_url(Article.first)%> diff --git a/vendor/impressionist/test_app/app/views/layouts/application.html.erb b/vendor/impressionist/test_app/app/views/layouts/application.html.erb deleted file mode 100644 index d4557d87..00000000 --- a/vendor/impressionist/test_app/app/views/layouts/application.html.erb +++ /dev/null @@ -1,14 +0,0 @@ - - - - TestApp - <%= stylesheet_link_tag "application", :media => "all" %> - <%= javascript_include_tag "application" %> - <%= csrf_meta_tags %> - - - -<%= yield %> - - - diff --git a/vendor/impressionist/test_app/app/views/posts/edit.html.erb b/vendor/impressionist/test_app/app/views/posts/edit.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/views/posts/index.html.erb b/vendor/impressionist/test_app/app/views/posts/index.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/views/posts/show.html.erb b/vendor/impressionist/test_app/app/views/posts/show.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/views/widgets/index.html.erb b/vendor/impressionist/test_app/app/views/widgets/index.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/views/widgets/new.html.erb b/vendor/impressionist/test_app/app/views/widgets/new.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/app/views/widgets/show.html.erb b/vendor/impressionist/test_app/app/views/widgets/show.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/config.ru b/vendor/impressionist/test_app/config.ru deleted file mode 100644 index 86a587d0..00000000 --- a/vendor/impressionist/test_app/config.ru +++ /dev/null @@ -1,4 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -require ::File.expand_path('../config/environment', __FILE__) -run TestApp::Application diff --git a/vendor/impressionist/test_app/config/application.rb b/vendor/impressionist/test_app/config/application.rb deleted file mode 100644 index d0d0095d..00000000 --- a/vendor/impressionist/test_app/config/application.rb +++ /dev/null @@ -1,59 +0,0 @@ -require File.expand_path('../boot', __FILE__) - -require 'rails/all' - -if defined?(Bundler) - # If you precompile assets before deploying to production, use this line - Bundler.require(*Rails.groups(:assets => %w(development test))) - # If you want your assets lazily compiled in production, use this line - # Bundler.require(:default, :assets, Rails.env) -end - -module TestApp - class Application < Rails::Application - # 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. - - # Custom directories with classes and modules you want to be autoloadable. - # config.autoload_paths += %W(#{config.root}/extras) - - # 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 ] - - # Activate observers that should always be running. - # config.active_record.observers = :cacher, :garbage_collector, :forum_observer - - # 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. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' - - # 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}').to_s] - # config.i18n.default_locale = :de - - # Configure the default encoding used in templates for Ruby 1.9. - config.encoding = "utf-8" - - # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] - - # Use SQL instead of Active Record's schema dumper when creating the 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 - - # Enforce whitelist mode for mass assignment. - # This will create an empty whitelist of attributes available for mass-assignment for all models - # in your app. As such, your models will need to explicitly whitelist or blacklist accessible - # parameters by using an attr_accessible or attr_protected declaration. - # config.active_record.whitelist_attributes = true - - # Enable the asset pipeline - config.assets.enabled = true - - # Version of your assets, change this if you want to expire all your assets - config.assets.version = '1.0' - end -end diff --git a/vendor/impressionist/test_app/config/boot.rb b/vendor/impressionist/test_app/config/boot.rb deleted file mode 100644 index 4489e586..00000000 --- a/vendor/impressionist/test_app/config/boot.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'rubygems' - -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) - -require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/vendor/impressionist/test_app/config/cucumber.yml b/vendor/impressionist/test_app/config/cucumber.yml deleted file mode 100644 index 6f304dfa..00000000 --- a/vendor/impressionist/test_app/config/cucumber.yml +++ /dev/null @@ -1,8 +0,0 @@ -<% -rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" -rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" -std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip" -%> -default: --drb <%= std_opts %> features -wip: --drb --tags @wip:3 --wip features -rerun: --drb <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip diff --git a/vendor/impressionist/test_app/config/database.yml b/vendor/impressionist/test_app/config/database.yml deleted file mode 100644 index 45fed06f..00000000 --- a/vendor/impressionist/test_app/config/database.yml +++ /dev/null @@ -1,30 +0,0 @@ -# SQLite version 3.x -# gem install sqlite3-ruby (not necessary on OS X Leopard) -development: - adapter: sqlite3 - database: db/development.sqlite3 - pool: 5 - timeout: 5000 - -test: &test - adapter: sqlite3 - database: db/test.sqlite3 - pool: 5 - timeout: 5000 - -#pg_test: -# adapter: postgresql -# database: impressionist_test -# username: johnmcaliley -# password: -# host: localhost -# encoding: UTF8 - -production: - adapter: sqlite3 - database: db/production.sqlite3 - pool: 5 - timeout: 5000 - -cucumber: - <<: *test diff --git a/vendor/impressionist/test_app/config/environment.rb b/vendor/impressionist/test_app/config/environment.rb deleted file mode 100644 index f4cc1e44..00000000 --- a/vendor/impressionist/test_app/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the rails application -require File.expand_path('../application', __FILE__) - -# Initialize the rails application -TestApp::Application.initialize! diff --git a/vendor/impressionist/test_app/config/environments/development.rb b/vendor/impressionist/test_app/config/environments/development.rb deleted file mode 100644 index b5306b32..00000000 --- a/vendor/impressionist/test_app/config/environments/development.rb +++ /dev/null @@ -1,37 +0,0 @@ -TestApp::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.cache_classes = false - - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true - - # Show full error reports and disable caching - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Don't care if the mailer can't send - config.action_mailer.raise_delivery_errors = false - - # Print deprecation notices to the Rails logger - config.active_support.deprecation = :log - - # Only use best-standards-support built into browsers - config.action_dispatch.best_standards_support = :builtin - - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - config.active_record.auto_explain_threshold_in_seconds = 0.5 - - # Do not compress assets - config.assets.compress = false - - # Expands the lines which load the assets - config.assets.debug = true -end diff --git a/vendor/impressionist/test_app/config/environments/pg_test.rb b/vendor/impressionist/test_app/config/environments/pg_test.rb deleted file mode 100644 index d17c1aeb..00000000 --- a/vendor/impressionist/test_app/config/environments/pg_test.rb +++ /dev/null @@ -1,35 +0,0 @@ -TestApp::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true - - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true - - # Show full error reports and disable caching - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates - config.action_dispatch.show_exceptions = false - - # 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 - - # 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 - - # Print deprecation notices to the stderr - config.active_support.deprecation = :stderr -end diff --git a/vendor/impressionist/test_app/config/environments/production.rb b/vendor/impressionist/test_app/config/environments/production.rb deleted file mode 100644 index c33789b2..00000000 --- a/vendor/impressionist/test_app/config/environments/production.rb +++ /dev/null @@ -1,67 +0,0 @@ -TestApp::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # Code is not reloaded between requests - config.cache_classes = true - - # Full error reports are disabled and caching is turned on - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Disable Rails's static asset server (Apache or nginx will already do this) - config.serve_static_assets = false - - # Compress JavaScripts and CSS - config.assets.compress = true - - # Don't fallback to assets pipeline if a precompiled asset is missed - config.assets.compile = false - - # Generate digests for assets URLs - config.assets.digest = true - - # Defaults to Rails.root.join("public/assets") - # config.assets.manifest = YOUR_PATH - - # Specifies the header that your server uses for sending files - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true - - # See everything in the log (default is :info) - # config.log_level = :debug - - # Prepend all log lines with the following tags - # config.log_tags = [ :subdomain, :uuid ] - - # Use a different logger for distributed setups - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) - - # Use a different cache store in production - # config.cache_store = :mem_cache_store - - # Enable serving of images, stylesheets, and JavaScripts from an asset server - # config.action_controller.asset_host = "http://assets.example.com" - - # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) - # config.assets.precompile += %w( search.js ) - - # Disable delivery errors, bad email addresses will be ignored - # config.action_mailer.raise_delivery_errors = false - - # Enable threaded mode - # config.threadsafe! - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation can not be found) - config.i18n.fallbacks = true - - # Send deprecation notices to registered listeners - config.active_support.deprecation = :notify - - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 -end diff --git a/vendor/impressionist/test_app/config/environments/test.rb b/vendor/impressionist/test_app/config/environments/test.rb deleted file mode 100644 index 21ec8e47..00000000 --- a/vendor/impressionist/test_app/config/environments/test.rb +++ /dev/null @@ -1,37 +0,0 @@ -TestApp::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true - - # Configure static asset server for tests with Cache-Control for performance - config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" - - # Log error messages when you accidentally call methods on nil - config.whiny_nils = true - - # Show full error reports and disable caching - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates - config.action_dispatch.show_exceptions = false - - # 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 - - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - - # Print deprecation notices to the stderr - config.active_support.deprecation = :stderr -end diff --git a/vendor/impressionist/test_app/config/initializers/backtrace_silencers.rb b/vendor/impressionist/test_app/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 59385cdf..00000000 --- a/vendor/impressionist/test_app/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! diff --git a/vendor/impressionist/test_app/config/initializers/impression.rb b/vendor/impressionist/test_app/config/initializers/impression.rb deleted file mode 100644 index fbdee915..00000000 --- a/vendor/impressionist/test_app/config/initializers/impression.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Use this hook to configure impressionist parameters -Impressionist.setup do |config| - # Define ORM. Could be :active_record (default) and :mongo_mapper - # config.orm = :active_record -end diff --git a/vendor/impressionist/test_app/config/initializers/inflections.rb b/vendor/impressionist/test_app/config/initializers/inflections.rb deleted file mode 100644 index 5d8d9be2..00000000 --- a/vendor/impressionist/test_app/config/initializers/inflections.rb +++ /dev/null @@ -1,15 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format -# (all these examples are active by default): -# ActiveSupport::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 -# -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections do |inflect| -# inflect.acronym 'RESTful' -# end diff --git a/vendor/impressionist/test_app/config/initializers/mime_types.rb b/vendor/impressionist/test_app/config/initializers/mime_types.rb deleted file mode 100644 index 72aca7e4..00000000 --- a/vendor/impressionist/test_app/config/initializers/mime_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf -# Mime::Type.register_alias "text/html", :iphone diff --git a/vendor/impressionist/test_app/config/initializers/secret_token.rb b/vendor/impressionist/test_app/config/initializers/secret_token.rb deleted file mode 100644 index 30f90d45..00000000 --- a/vendor/impressionist/test_app/config/initializers/secret_token.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -TestApp::Application.config.secret_token = '4a6fd2eb397985331d209be32073259ed7c25aef4fafcabb00e483ee548e592322277eb15459bdb257b65f31146eda92684b3e7a98ea1b2dfad9b0d08ab62e10' diff --git a/vendor/impressionist/test_app/config/initializers/session_store.rb b/vendor/impressionist/test_app/config/initializers/session_store.rb deleted file mode 100644 index 8188ba2d..00000000 --- a/vendor/impressionist/test_app/config/initializers/session_store.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Be sure to restart your server when you modify this file. - -TestApp::Application.config.session_store :cookie_store, :key => '_test_app_session' - -# Use the database for sessions instead of the cookie-based default, -# which shouldn't be used to store highly confidential information -# (create the session table with "rails generate session_migration") -# TestApp::Application.config.session_store :active_record_store diff --git a/vendor/impressionist/test_app/config/initializers/wrap_parameters.rb b/vendor/impressionist/test_app/config/initializers/wrap_parameters.rb deleted file mode 100644 index da4fb076..00000000 --- a/vendor/impressionist/test_app/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters :format => [:json] -end - -# Disable root element in JSON by default. -ActiveSupport.on_load(:active_record) do - self.include_root_in_json = false -end diff --git a/vendor/impressionist/test_app/config/locales/en.yml b/vendor/impressionist/test_app/config/locales/en.yml deleted file mode 100644 index 179c14ca..00000000 --- a/vendor/impressionist/test_app/config/locales/en.yml +++ /dev/null @@ -1,5 +0,0 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. - -en: - hello: "Hello world" diff --git a/vendor/impressionist/test_app/config/routes.rb b/vendor/impressionist/test_app/config/routes.rb deleted file mode 100644 index 7bcb78ea..00000000 --- a/vendor/impressionist/test_app/config/routes.rb +++ /dev/null @@ -1,3 +0,0 @@ -TestApp::Application.routes.draw do - resources :articles, :posts, :widgets -end diff --git a/vendor/impressionist/test_app/db/migrate/20110201153144_create_articles.rb b/vendor/impressionist/test_app/db/migrate/20110201153144_create_articles.rb deleted file mode 100644 index 66f46ef4..00000000 --- a/vendor/impressionist/test_app/db/migrate/20110201153144_create_articles.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateArticles < ActiveRecord::Migration - def self.up - create_table :articles do |t| - t.string :name - - t.timestamps - end - end - - def self.down - drop_table :articles - end -end diff --git a/vendor/impressionist/test_app/db/migrate/20110210205028_create_posts.rb b/vendor/impressionist/test_app/db/migrate/20110210205028_create_posts.rb deleted file mode 100644 index f018e1ce..00000000 --- a/vendor/impressionist/test_app/db/migrate/20110210205028_create_posts.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreatePosts < ActiveRecord::Migration - def self.up - create_table :posts do |t| - t.string :name - - t.timestamps - end - end - - def self.down - drop_table :posts - end -end diff --git a/vendor/impressionist/test_app/db/migrate/20111127184039_create_widgets.rb b/vendor/impressionist/test_app/db/migrate/20111127184039_create_widgets.rb deleted file mode 100644 index 5cb1fe2c..00000000 --- a/vendor/impressionist/test_app/db/migrate/20111127184039_create_widgets.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateWidgets < ActiveRecord::Migration - def self.up - create_table :widgets do |t| - t.string :name - t.integer :impressions_count - - t.timestamps - end - end - - def self.down - drop_table :widgets - end -end - diff --git a/vendor/impressionist/test_app/db/seeds.rb b/vendor/impressionist/test_app/db/seeds.rb deleted file mode 100644 index d34dfa02..00000000 --- a/vendor/impressionist/test_app/db/seeds.rb +++ /dev/null @@ -1,7 +0,0 @@ -# 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' }]) -# Mayor.create(:name => 'Emanuel', :city => cities.first) diff --git a/vendor/impressionist/test_app/lib/assets/.gitkeep b/vendor/impressionist/test_app/lib/assets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/lib/tasks/.gitkeep b/vendor/impressionist/test_app/lib/tasks/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/lib/tasks/cucumber.rake b/vendor/impressionist/test_app/lib/tasks/cucumber.rake deleted file mode 100644 index 982054e2..00000000 --- a/vendor/impressionist/test_app/lib/tasks/cucumber.rake +++ /dev/null @@ -1,53 +0,0 @@ -# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. -# It is recommended to regenerate this file in the future when you upgrade to a -# newer version of cucumber-rails. Consider adding your own code to a new file -# instead of editing this one. Cucumber will automatically load all features/**/*.rb -# files. - - -unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks - -vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first -$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil? - -begin - require 'cucumber/rake/task' - - namespace :cucumber do - Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t| - t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. - t.fork = true # You may get faster startup if you set this to false - t.profile = 'default' - end - - Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t| - t.binary = vendored_cucumber_bin - t.fork = true # You may get faster startup if you set this to false - t.profile = 'wip' - end - - Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t| - t.binary = vendored_cucumber_bin - t.fork = true # You may get faster startup if you set this to false - t.profile = 'rerun' - end - - desc 'Run all features' - task :all => [:ok, :wip] - end - desc 'Alias for cucumber:ok' - task :cucumber => 'cucumber:ok' - - task :default => :cucumber - - task :features => :cucumber do - STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***" - end -rescue LoadError - desc 'cucumber rake task not available (cucumber not installed)' - task :cucumber do - abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' - end -end - -end diff --git a/vendor/impressionist/test_app/log/.gitkeep b/vendor/impressionist/test_app/log/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/public/404.html b/vendor/impressionist/test_app/public/404.html deleted file mode 100644 index 9a48320a..00000000 --- a/vendor/impressionist/test_app/public/404.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - -
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
- - diff --git a/vendor/impressionist/test_app/public/422.html b/vendor/impressionist/test_app/public/422.html deleted file mode 100644 index 83660ab1..00000000 --- a/vendor/impressionist/test_app/public/422.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - -
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
- - diff --git a/vendor/impressionist/test_app/public/500.html b/vendor/impressionist/test_app/public/500.html deleted file mode 100644 index f3648a0d..00000000 --- a/vendor/impressionist/test_app/public/500.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - -
-

We're sorry, but something went wrong.

-
- - diff --git a/vendor/impressionist/test_app/public/favicon.ico b/vendor/impressionist/test_app/public/favicon.ico deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/public/images/rails.png b/vendor/impressionist/test_app/public/images/rails.png deleted file mode 100644 index d5edc04e65f555e3ba4dcdaad39dc352e75b575e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6646 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 AQ~&?~ diff --git a/vendor/impressionist/test_app/public/index.html b/vendor/impressionist/test_app/public/index.html deleted file mode 100644 index a1d50995..00000000 --- a/vendor/impressionist/test_app/public/index.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - Ruby on Rails: Welcome aboard - - - - -
- - -
- - - - -
-

Getting started

-

Here’s how to get rolling:

- -
    -
  1. -

    Use rails generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  2. - -
  3. -

    Set up a default route and remove public/index.html

    -

    Routes are set up in config/routes.rb.

    -
  4. - -
  5. -

    Create your database

    -

    Run rake db:create to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

    -
  6. -
-
-
- - -
- - diff --git a/vendor/impressionist/test_app/public/javascripts/application.js b/vendor/impressionist/test_app/public/javascripts/application.js deleted file mode 100644 index fe457769..00000000 --- a/vendor/impressionist/test_app/public/javascripts/application.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place your application-specific JavaScript functions and classes here -// This file is automatically included by javascript_include_tag :defaults diff --git a/vendor/impressionist/test_app/public/javascripts/controls.js b/vendor/impressionist/test_app/public/javascripts/controls.js deleted file mode 100644 index 75d1bed7..00000000 --- a/vendor/impressionist/test_app/public/javascripts/controls.js +++ /dev/null @@ -1,965 +0,0 @@ -// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 - -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005-2009 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 -// 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, -// a getUpdatedChoices function that will be invoked every time -// 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 -// autocompletion. Specific auto-completion logic (AJAX, etc) -// belongs in getUpdatedChoices. -// -// Tokenized incremental autocompletion is enabled automatically -// when an autocompleter is instantiated with the 'tokens' option -// in the options parameter, e.g.: -// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); -// 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 -// allows smart autocompletion after linebreaks. - -if(typeof Effect == 'undefined') - throw("controls.js requires including script.aculo.us' effects.js library"); - -var Autocompleter = { }; -Autocompleter.Base = Class.create({ - baseInitialize: function(element, update, options) { - 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.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.onShow = this.options.onShow || - function(element, update){ - if(!update.style.position || update.style.position=='absolute') { - update.style.position = 'absolute'; - Position.clone(element, update, { - setHeight: false, - offsetTop: element.offsetHeight - }); - } - Effect.Appear(update,{duration:0.15}); - }; - this.options.onHide = this.options.onHide || - function(element, update){ new Effect.Fade(update,{duration:0.15}) }; - - 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, 'keydown', this.onKeyPress.bindAsEventListener(this)); - }, - - show: function() { - if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); - if(!this.iefix && - (Prototype.Browser.IE) && - (Element.getStyle(this.update, 'position')=='absolute')) { - new Insertion.After(this.update, - ''); - this.iefix = $(this.update.id+'_iefix'); - } - 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; - this.update.style.zIndex = 2; - Element.show(this.iefix); - }, - - hide: function() { - this.stopIndicator(); - if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); - if(this.iefix) Element.hide(this.iefix); - }, - - startIndicator: function() { - if(this.options.indicator) Element.show(this.options.indicator); - }, - - stopIndicator: function() { - if(this.options.indicator) Element.hide(this.options.indicator); - }, - - onKeyPress: function(event) { - if(this.active) - switch(event.keyCode) { - case Event.KEY_TAB: - case Event.KEY_RETURN: - this.selectEntry(); - Event.stop(event); - case Event.KEY_ESC: - this.hide(); - this.active = false; - Event.stop(event); - return; - case Event.KEY_LEFT: - case Event.KEY_RIGHT: - return; - case Event.KEY_UP: - this.markPrevious(); - this.render(); - Event.stop(event); - return; - case Event.KEY_DOWN: - this.markNext(); - this.render(); - Event.stop(event); - 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 = - setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); - }, - - activate: function() { - this.changed = false; - this.hasFocus = true; - this.getUpdatedChoices(); - }, - - onHover: function(event) { - var element = Event.findElement(event, 'LI'); - 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; - }, - - render: function() { - if(this.entryCount > 0) { - for (var i = 0; i < this.entryCount; i++) - this.index==i ? - Element.addClassName(this.getEntry(i),"selected") : - Element.removeClassName(this.getEntry(i),"selected"); - if(this.hasFocus) { - this.show(); - this.active = true; - } - } else { - this.active = false; - this.hide(); - } - }, - - markPrevious: function() { - 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++; - 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()); - }, - - updateElement: function(selectedElement) { - if (this.options.updateElement) { - this.options.updateElement(selectedElement); - return; - } - var value = ''; - if (this.options.select) { - 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 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.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); - }, - - updateChoices: function(choices) { - if(!this.changed && this.hasFocus) { - this.update.innerHTML = choices; - Element.cleanWhitespace(this.update); - Element.cleanWhitespace(this.update.down()); - - if(this.update.firstChild && this.update.down().childNodes) { - 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 { - this.entryCount = 0; - } - - this.stopIndicator(); - this.index = 0; - - if(this.entryCount==1 && this.options.autoSelect) { - this.selectEntry(); - this.hide(); - } else { - this.render(); - } - } - }, - - addObservers: function(element) { - Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); - Event.observe(element, "click", this.onClick.bindAsEventListener(this)); - }, - - onObserverEvent: function() { - this.changed = false; - this.tokenBounds = null; - if(this.getToken().length>=this.options.minChars) { - this.getUpdatedChoices(); - } else { - this.active = false; - this.hide(); - } - this.oldElementValue = this.element.value; - }, - - getToken: function() { - var bounds = this.getTokenBounds(); - return this.element.value.substring(bounds[0], bounds[1]).strip(); - }, - - 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 (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); - } -}); - -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; - this.options.onComplete = this.onComplete.bind(this); - this.options.defaultParams = this.options.parameters || null; - this.url = url; - }, - - getUpdatedChoices: function() { - 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) - this.options.parameters += '&' + this.options.defaultParams; - - new Ajax.Request(this.url, this.options); - }, - - onComplete: function(request) { - this.updateChoices(request.responseText); - } -}); - -// The local array autocompleter. Used when you'd prefer to -// inject an array of autocompletion options into the page, rather -// than sending out Ajax queries, which can be quite slow sometimes. -// -// The constructor takes four parameters. The first two are, as usual, -// the id of the monitored textbox, and id of the autocompletion menu. -// The third is the array you want to autocomplete from, and the fourth -// is the options block. -// -// Extra local autocompletion options: -// - choices - How many autocompletion choices to offer -// -// - partialSearch - If false, the autocompleter will match entered -// 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 -// search anywhere in the string, additionally set -// the option fullSearch to true (default: off). -// -// - fullSsearch - Search anywhere in autocomplete array strings. -// -// - partialChars - How many characters to enter before triggering -// a partial match (unlike minChars, which defines -// how many characters are required to do any match -// at all). Defaults to 2. -// -// - ignoreCase - Whether to ignore case when autocompleting. -// Defaults to true. -// -// 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.Base, { - initialize: function(element, update, array, options) { - this.baseInitialize(element, update, options); - this.options.array = array; - }, - - getUpdatedChoices: function() { - this.updateChoices(this.options.selector(this)); - }, - - setOptions: function(options) { - this.options = Object.extend({ - choices: 10, - partialSearch: true, - partialChars: 2, - ignoreCase: true, - fullSearch: false, - selector: function(instance) { - var ret = []; // Beginning matches - var partial = []; // Inside matches - var entry = instance.getToken(); - var count = 0; - - 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()) : - elem.indexOf(entry); - - while (foundPos != -1) { - if (foundPos == 0 && elem.length != entry.length) { - ret.push("
  • " + elem.substr(0, entry.length) + "" + - elem.substr(entry.length) + "
  • "); - break; - } 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("
  • " + elem.substr(0, foundPos) + "" + - elem.substr(foundPos, entry.length) + "" + elem.substr( - foundPos + entry.length) + "
  • "); - break; - } - } - - 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)); - return "
      " + ret.join('') + "
    "; - } - }, options || { }); - } -}); - -// AJAX in-place editor and collection editor -// Full rewrite by Christophe Porteneuve (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 -// waits 1 ms (with setTimeout) until it does the activation -Field.scrollFreeActivate = function(field) { - setTimeout(function() { - Field.activate(field); - }, 1); -}; - -Ajax.InPlaceEditor = Class.create({ - initialize: function(element, url, options) { - this.url = url; - 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) - this.options.externalControl = $(this.options.externalControl); - if (!this.options.externalControl) - this.options.externalControlOnly = false; - this._originalBackground = this.element.getStyle('background-color') || 'transparent'; - this.element.title = this.options.clickToEditText; - 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(); - }, - 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); - }, - 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.onclick = this._boundCancelHandler; - 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.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; - link.className = 'editor_' + mode + '_link'; - if (extraClasses) - link.className += ' ' + extraClasses; - this._form.appendChild(link); - this._controls[mode] = link; - } - }, - createEditField: function() { - 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 (0 < size) fld.size = size; - } else { - fld = document.createElement('textarea'); - fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); - fld.cols = this.options.cols || 40; - } - fld.name = this.options.paramName; - fld.value = text; // No HTML breaks conversion anymore - fld.className = 'editor_field'; - if (this.options.submitOnBlur) - fld.onblur = this._boundSubmitHandler; - this._controls.editor = fld; - if (this.options.loadTextURL) - this.loadExternalText(); - this._form.appendChild(this._controls.editor); - }, - 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.onsubmit = this._boundSubmitHandler; - 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); - }, - destroy: function() { - if (this._oldInnerHTML) - this.element.innerHTML = this._oldInnerHTML; - this.leaveEditMode(); - this.unregisterListeners(); - }, - 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); - }, - enterHover: function(e) { - if (this.options.hoverClassName) - this.element.addClassName(this.options.hoverClassName); - if (this._saving) return; - this.triggerCallback('onEnterHover'); - }, - 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; - } - }, - 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); - } - if (e) Event.stop(e); - }, - 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.element.innerHTML = this.options.savingText; - this.element.addClassName(this.options.savingClassName); - this.element.style.backgroundColor = this._originalBackground; - this.element.show(); - }, - triggerCallback: function(cbName, arg) { - if ('function' == typeof this.options[cbName]) { - this.options[cbName](this, arg); - } - }, - 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)); - }, - 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); - }, - - 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; - } - tempOption.update((text || '').stripScripts().stripTags()); - }, - - checkForExternalText: function() { - this._text = this.getText(); - if (this.options.loadTextURL) - this.loadExternalText(); - else - this.buildOptionList(); - }, - - 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); -}; - -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 - }); - } - }, - Listeners: { - click: 'enterEditMode', - keydown: 'checkForEscapeOrReturn', - mouseover: 'enterHover', - mouseout: 'leaveHover' - } -}); - -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({ - initialize: function(element, delay, callback) { - this.delay = delay || 0.5; - this.element = $(element); - this.callback = callback; - this.timer = null; - this.lastValue = $F(this.element); - Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); - }, - delayedListener: function(event) { - if(this.lastValue == $F(this.element)) return; - if(this.timer) clearTimeout(this.timer); - this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); - this.lastValue = $F(this.element); - }, - onTimerEvent: function() { - this.timer = null; - this.callback(this.element, $F(this.element)); - } -}); diff --git a/vendor/impressionist/test_app/public/javascripts/dragdrop.js b/vendor/impressionist/test_app/public/javascripts/dragdrop.js deleted file mode 100644 index 579715ec..00000000 --- a/vendor/impressionist/test_app/public/javascripts/dragdrop.js +++ /dev/null @@ -1,974 +0,0 @@ -// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 - -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// 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(Object.isUndefined(Effect)) - throw("dragdrop.js requires including script.aculo.us' effects.js library"); - -var Droppables = { - drops: [], - - remove: function(element) { - this.drops = this.drops.reject(function(d) { return d.element==$(element) }); - }, - - add: function(element) { - element = $(element); - var options = Object.extend({ - greedy: true, - hoverclass: null, - tree: false - }, arguments[1] || { }); - - // cache containers - if(options.containment) { - options._containers = []; - var containment = options.containment; - 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 - options.element = element; - - 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; - } 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( - function(v) { return drop.accept.include(v) } ) )) && - Position.within(drop.element, point[0], point[1]) ); - }, - - deactivate: function(drop) { - if(drop.hoverclass) - Element.removeClassName(drop.element, drop.hoverclass); - this.last_active = null; - }, - - activate: function(drop) { - if(drop.hoverclass) - Element.addClassName(drop.element, drop.hoverclass); - this.last_active = drop; - }, - - show: function(point, element) { - if(!this.drops.length) return; - var drop, affected = []; - - this.drops.each( function(drop) { - if(Droppables.isAffected(point, element, drop)) - affected.push(drop); - }); - - 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)); - - if (drop != this.last_active) Droppables.activate(drop); - } - }, - - fire: function(event, element) { - if(!this.last_active) return; - Position.prepare(); - - if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) - 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) { - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - 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); - } 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)]; - // Mozilla-based browsers fire successive mousemove events with - // 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.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) { - if(o[eventName]) o[eventName](eventName, draggable, event); - }); - if(draggable.options[eventName]) draggable.options[eventName](draggable, event); - }, - - _cacheObserverCallbacks: function() { - ['onStart','onEnd','onDrag'].each( function(eventName) { - Draggables[eventName+'Count'] = Draggables.observers.select( - function(o) { return o[eventName]; } - ).length; - }); - } -}; - -/*--------------------------------------------------------------------------*/ - -var Draggable = Class.create({ - initialize: function(element) { - var defaults = { - handle: false, - reverteffect: function(element, top_offset, left_offset) { - var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, - queue: {scope:'_draggable', position:'end'} - }); - }, - endeffect: function(element) { - 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 - } - }); - }, - 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] || 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}); - } - }); - - var options = Object.extend(defaults, arguments[1] || { }); - - this.element = $(element); - - 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 - - this.options = options; - 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(!Object.isUndefined(Draggable._dragging[this.element]) && - Draggable._dragging[this.element]) return; - if(Event.isLeftClick(event)) { - // abort on form elements, fixes a Firefox issue - var src = Event.element(event); - 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 = this.element.cumulativeOffset(); - 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); - 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); - this.originalScrollLeft = where.left; - this.originalScrollTop = where.top; - } else { - this.originalScrollLeft = this.options.scroll.scrollLeft; - 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); - - 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 ]; } - } else { - p = Position.page(this.options.scroll); - p[0] += this.options.scroll.scrollLeft + Position.deltaX; - p[1] += this.options.scroll.scrollTop + Position.deltaY; - p.push(p[0]+this.options.scroll.offsetWidth); - p.push(p[1]+this.options.scroll.offsetHeight); - } - var speed = [0,0]; - if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); - if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); - if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); - if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); - this.startScrolling(speed); - } - - // fix AppleWebKit rendering - 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) { - if (!this._originallyAbsolute) - Position.relativize(this.element); - delete this._originallyAbsolute; - Element.remove(this._clone); - this._clone = null; - } - - 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 && Object.isFunction(revert)) revert = revert(this.element); - - var d = this.currentDelta(); - if(revert && this.options.reverteffect) { - if (dropped == 0 || revert != 'failure') - this.options.reverteffect(this.element, - d[1]-this.delta[1], d[0]-this.delta[0]); - } else { - this.delta = d; - } - - if(this.options.zindex) - this.element.style.zIndex = this.originalZ; - - 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 = this.element.cumulativeOffset(); - 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]) - }.bind(this)); - - if(this.options.snap) { - if(Object.isFunction(this.options.snap)) { - p = this.options.snap(p[0],p[1],this); - } else { - if(Object.isArray(this.options.snap)) { - p = p.map( function(v, i) { - return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)); - } else { - p = p.map( function(v) { - 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); - this.scrollInterval = null; - 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; - this.lastScrolled = current; - if(this.options.scroll == window) { - with (this._getWindowScroll(this.options.scroll)) { - if (this.scrollSpeed[0] || this.scrollSpeed[1]) { - var d = delta / 1000; - this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); - } - } - } else { - 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); - if (this._isScrollChild) { - Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); - Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; - Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; - if (Draggables._lastScrollPointer[0] < 0) - Draggables._lastScrollPointer[0] = 0; - if (Draggables._lastScrollPointer[1] < 0) - 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) { - if (w.document.documentElement && documentElement.scrollTop) { - T = documentElement.scrollTop; - L = documentElement.scrollLeft; - } else if (w.document.body) { - T = body.scrollTop; - L = body.scrollLeft; - } - if (w.innerWidth) { - W = w.innerWidth; - H = w.innerHeight; - } else if (w.document.documentElement && documentElement.clientWidth) { - W = documentElement.clientWidth; - H = documentElement.clientHeight; - } else { - W = body.offsetWidth; - H = body.offsetHeight; - } - } - return { top: T, left: L, width: W, height: H }; - } -}); - -Draggable._dragging = { }; - -/*--------------------------------------------------------------------------*/ - -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: { }, - - _findRootElement: function(element) { - while (element.tagName.toUpperCase() != "BODY") { - if(element.id && Sortable.sortables[element.id]) return element; - element = element.parentNode; - } - }, - - options: function(element) { - element = Sortable._findRootElement($(element)); - if(!element) return; - return Sortable.sortables[element.id]; - }, - - destroy: function(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({ - element: element, - tag: 'li', // assumes li children, override with tag: 'tagname' - dropOnEmpty: false, - tree: false, - treeTag: 'ul', - overlap: 'vertical', // one of 'vertical', 'horizontal' - constraint: 'vertical', // one of 'vertical', 'horizontal', false - containment: element, // also takes array of elements (or id's); or false - handle: false, // or a CSS class - only: false, - 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] || { }); - - // clear any old sortable with same element - this.destroy(element); - - // build options for the draggables - var options_for_draggable = { - revert: true, - quiet: options.quiet, - scroll: options.scroll, - scrollSpeed: options.scrollSpeed, - scrollSensitivity: options.scrollSensitivity, - delay: options.delay, - ghosting: options.ghosting, - constraint: options.constraint, - handle: options.handle }; - - if(options.starteffect) - options_for_draggable.starteffect = options.starteffect; - - if(options.reverteffect) - options_for_draggable.reverteffect = options.reverteffect; - else - if(options.ghosting) options_for_draggable.reverteffect = function(element) { - element.style.top = 0; - element.style.left = 0; - }; - - if(options.endeffect) - options_for_draggable.endeffect = options.endeffect; - - if(options.zindex) - options_for_draggable.zindex = options.zindex; - - // 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); - - options.draggables = []; - options.droppables = []; - - // drop on empty handling - if(options.dropOnEmpty || options.tree) { - Droppables.add(element, options_for_tree); - options.droppables.push(element); - } - - (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); - }); - - if(options.tree) { - (Sortable.findTreeElements(element, options) || []).each( function(e) { - Droppables.add(e, options_for_tree); - e.treeNode = element; - options.droppables.push(e); - }); - } - - // keep reference - this.sortables[element.identify()] = options; - - // for onupdate - Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - - }, - - // return all suitable-for-sortable elements in a guaranteed order - findElements: function(element, options) { - 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); - }, - - onHover: function(element, dropon, overlap) { - if(Element.isParent(dropon, element)) return; - - if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { - return; - } else if(overlap>0.5) { - Sortable.mark(dropon, 'before'); - if(dropon.previousSibling != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, dropon); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } else { - Sortable.mark(dropon, 'after'); - var nextElement = dropon.nextSibling || null; - if(nextElement != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, nextElement); - 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); - } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { - child = index + 1 < children.length ? children[index + 1] : null; - break; - } else { - child = children[index]; - break; - } - } - } - - dropon.insertBefore(element, child); - - Sortable.options(oldParentNode).onChange(element); - droponOptions.onChange(element); - } - }, - - unmark: function() { - if(Sortable._marker) Sortable._marker.hide(); - }, - - mark: function(dropon, position) { - // mark on ghosting only - var sortable = Sortable.options(dropon.parentNode); - if(sortable && !sortable.ghosting) return; - - if(!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 = dropon.cumulativeOffset(); - Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); - - if(position=='after') - 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, - parent: parent, - 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); - - parent.children.push (child); - } - - return parent; - }, - - tree: function(element) { - element = $(element); - var sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - treeTag: sortableOptions.treeTag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format - }, arguments[1] || { }); - - var root = { - id: null, - parent: null, - children: [], - container: element, - position: 0 - }; - - return Sortable._tree(element, options, root); - }, - - /* Construct a [i] index for a particular node */ - _constructIndex: function(node) { - var index = ''; - do { - if (node.id) index = '[' + node.position + ']' + index; - } while ((node = node.parent) != null); - return index; - }, - - sequence: function(element) { - element = $(element); - 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] : ''; - }); - }, - - setSequence: function(element, new_sequence) { - element = $(element); - 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) { - n[1].appendChild(n[0]); - delete nodeMap[ident]; - } - }); - }, - - serialize: function(element) { - element = $(element); - 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]=" + - encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); - }).flatten().join('&'); - } else { - return Sortable.sequence(element, arguments[1]).map( function(item) { - return name + "[]=" + encodeURIComponent(item); - }).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) { - if(!element.hasChildNodes()) return null; - tagName = tagName.toUpperCase(); - if(only) only = [only].flatten(); - var elements = []; - $A(element.childNodes).each( function(e) { - if(e.tagName && e.tagName.toUpperCase()==tagName && - (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) - elements.push(e); - if(recursive) { - var grandchildren = Element.findChildren(e, only, recursive, tagName); - if(grandchildren) elements.push(grandchildren); - } - }); - - return (elements.length>0 ? elements.flatten() : []); -}; - -Element.offsetSize = function (element, type) { - return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; -}; diff --git a/vendor/impressionist/test_app/public/javascripts/effects.js b/vendor/impressionist/test_app/public/javascripts/effects.js deleted file mode 100644 index c977462f..00000000 --- a/vendor/impressionist/test_app/public/javascripts/effects.js +++ /dev/null @@ -1,1123 +0,0 @@ -// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 - -// Copyright (c) 2005-2009 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/ - -// 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)); -}; - -/*--------------------------------------------------------------------------*/ - -Element.collectTextNodes = function(element) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); - }).flatten().join(''); -}; - -Element.collectTextNodesIgnoreClass = function(element, className) { - return $A($(element).childNodes).collect( function(node) { - 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 (Prototype.Browser.WebKit) window.scrollBy(0,0); - return element; -}; - -Element.getInlineOpacity = function(element){ - return $(element).style.opacity || ''; -}; - -Element.forceRerendering = function(element) { - try { - element = $(element); - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch(e) { } -}; - -/*--------------------------------------------------------------------------*/ - -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) { - var tagifyStyle = 'position:relative'; - if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; - - element = $(element); - $A(element.childNodes).each( function(child) { - if (child.nodeType==3) { - child.nodeValue.toArray().each( function(character) { - element.insertBefore( - new Element('span', {style: tagifyStyle}).update( - character == ' ' ? String.fromCharCode(160) : character), - child); - }); - Element.remove(child); - } - }); - }, - multiple: function(element, effect) { - var elements; - 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] || { }); - var masterDelay = options.delay; - - $A(elements).each( function(element, index) { - new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); - }); - }, - PAIRS: { - 'slide': ['SlideDown','SlideUp'], - 'blind': ['BlindDown','BlindUp'], - 'appear': ['Appear','Fade'] - }, - toggle: function(element, effect, options) { - element = $(element); - effect = (effect || 'appear').toLowerCase(); - - return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({ - queue: { position:'end', scope:(element.id || 'global'), limit: 1 } - }, options || {})); - } -}; - -Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; - -/* ------------- core effects ------------- */ - -Effect.ScopedQueue = Class.create(Enumerable, { - initialize: function() { - this.effects = []; - this.interval = null; - }, - _each: function(iterator) { - this.effects._each(iterator); - }, - add: function(effect) { - var timestamp = new Date().getTime(); - - var position = Object.isString(effect.options.queue) ? - effect.options.queue : effect.options.queue.position; - - switch(position) { - case 'front': - // 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; - }); - break; - case 'with-last': - timestamp = this.effects.pluck('startOn').max() || timestamp; - break; - case 'end': - // start effect after last queued effect has finished - 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)) - this.effects.push(effect); - - 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) { - clearInterval(this.interval); - this.interval = null; - } - }, - loop: function() { - var timePos = new Date().getTime(); - for(var i=0, len=this.effects.length;i= this.startOn) { - if (timePos >= this.finishOn) { - this.render(1.0); - this.cancel(); - this.event('beforeFinish'); - if (this.finish) this.finish(); - this.event('afterFinish'); - return; - } - var pos = (timePos - this.startOn) / this.totalTime, - frame = (pos * this.totalFrames).round(); - if (frame > this.currentFrame) { - this.render(pos); - this.currentFrame = frame; - } - } - }, - cancel: function() { - 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); - }, - inspect: function() { - var data = $H(); - for(property in this) - if (!Object.isFunction(this[property])) data.set(property, this[property]); - return '#'; - } -}); - -Effect.Parallel = Class.create(Effect.Base, { - initialize: function(effects) { - this.effects = effects || []; - this.start(arguments[1]); - }, - update: function(position) { - this.effects.invoke('render', position); - }, - finish: function(position) { - this.effects.each( function(effect) { - effect.render(1.0); - effect.cancel(); - effect.event('beforeFinish'); - if (effect.finish) effect.finish(position); - effect.event('afterFinish'); - }); - } -}); - -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() { - this.start(Object.extend({ duration: 0 }, arguments[0] || { })); - }, - update: Prototype.emptyFunction -}); - -Effect.Opacity = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - // make this work on IE on elements without 'layout' - 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] || { }); - this.start(options); - }, - update: function(position) { - this.element.setOpacity(position); - } -}); - -Effect.Move = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - x: 0, - y: 0, - mode: 'relative' - }, arguments[1] || { }); - this.start(options); - }, - setup: function() { - this.element.makePositioned(); - this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); - this.originalTop = parseFloat(this.element.getStyle('top') || '0'); - 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: (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] || { })); -}; - -Effect.Scale = Class.create(Effect.Base, { - initialize: function(element, percent) { - this.element = $(element); - 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 - scaleFrom: 100.0, - scaleTo: percent - }, arguments[2] || { }); - this.start(options); - }, - setup: function() { - this.restoreAfterFinish = this.options.restoreAfterFinish || false; - this.elementPositioning = this.element.getStyle('position'); - - 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) { - 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') - this.dims = [this.element.offsetHeight, this.element.offsetWidth]; - if (/^content/.test(this.options.scaleMode)) - this.dims = [this.element.scrollHeight, this.element.scrollWidth]; - 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) - 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); - }, - setDimensions: function(height, width) { - 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'; - } else { - if (this.options.scaleY) d.top = -topd + 'px'; - if (this.options.scaleX) d.left = -leftd + 'px'; - } - } - this.element.setStyle(d); - } -}); - -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] || { }); - this.start(options); - }, - setup: function() { - // Prevent executing on elements not in the layout flow - if (this.element.getStyle('display')=='none') { this.cancel(); return; } - // Disable background image during the effect - 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) - 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)); - this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); - }, - update: function(position) { - this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ - return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); - }, - finish: function() { - this.element.setStyle(Object.extend(this.oldStyle, { - backgroundColor: this.options.restorecolor - })); - } -}); - -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] || { }); - return new Effect.Opacity(element,options); -}; - -Effect.Appear = function(element) { - element = $(element); - var options = Object.extend({ - from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), - to: 1.0, - // force Safari to render floated elements properly - afterFinishInternal: function(effect) { - effect.element.forceRerendering(); - }, - beforeSetup: function(effect) { - 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(), - position: element.getStyle('position'), - top: element.style.top, - left: element.style.left, - width: element.style.width, - 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, - beforeSetupInternal: function(effect) { - Position.absolutize(effect.effects[0].element); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().setStyle(oldStyle); } - }, arguments[1] || { }) - ); -}; - -Effect.BlindUp = function(element) { - element = $(element); - element.makeClipping(); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - restoreAfterFinish: true, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); - } - }, arguments[1] || { }) - ); -}; - -Effect.BlindDown = function(element) { - element = $(element); - var elementDimensions = element.getDimensions(); - 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(); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping(); - } - }, arguments[1] || { })); -}; - -Effect.SwitchOff = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - return new Effect.Appear(element, Object.extend({ - duration: 0.4, - from: 0, - transition: Effect.Transitions.flicker, - afterFinishInternal: function(effect) { - new Effect.Scale(effect.element, 1, { - duration: 0.3, scaleFromCenter: true, - scaleX: false, scaleContent: false, restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makePositioned().makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); - } - }); - } - }, arguments[1] || { })); -}; - -Effect.DropOut = function(element) { - element = $(element); - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left'), - opacity: element.getInlineOpacity() }; - return new Effect.Parallel( - [ 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(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); - } - }, 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: distance, y: 0, duration: split, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { 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, - 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(); - }, - afterUpdateInternal: function(effect) { - effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping().undoPositioned(); - effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } - }, 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, - scaleMode: 'box', - scaleFrom: 100, - 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().show(); - }, - afterUpdateInternal: function(effect) { - effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().undoPositioned(); - effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); - } - }, arguments[1] || { }) - ); -}; - -// 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, { - restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); - } - }); -}; - -Effect.Grow = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.full - }, arguments[1] || { }); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var initialMoveX, initialMoveY; - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - initialMoveX = initialMoveY = moveX = moveY = 0; - break; - case 'top-right': - initialMoveX = dims.width; - initialMoveY = moveY = 0; - moveX = -dims.width; - break; - case 'bottom-left': - initialMoveX = moveX = 0; - initialMoveY = dims.height; - moveY = -dims.height; - break; - case 'bottom-right': - initialMoveX = dims.width; - initialMoveY = dims.height; - moveX = -dims.width; - moveY = -dims.height; - break; - case 'center': - initialMoveX = dims.width / 2; - initialMoveY = dims.height / 2; - moveX = -dims.width / 2; - moveY = -dims.height / 2; - break; - } - - return new Effect.Move(element, { - x: initialMoveX, - y: initialMoveY, - duration: 0.01, - beforeSetup: function(effect) { - effect.element.hide().makeClipping().makePositioned(); - }, - afterFinishInternal: function(effect) { - new Effect.Parallel( - [ 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 }, - 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(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); - } - }, options) - ); - } - }); -}; - -Effect.Shrink = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.none - }, arguments[1] || { }); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - moveX = moveY = 0; - break; - case 'top-right': - moveX = dims.width; - moveY = 0; - break; - case 'bottom-left': - moveX = 0; - moveY = dims.height; - break; - case 'bottom-right': - moveX = dims.width; - moveY = dims.height; - break; - 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({ - beforeStartInternal: function(effect) { - 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] || { }, - 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); - var oldStyle = { - top: element.style.top, - left: element.style.left, - width: element.style.width, - height: element.style.height }; - element.makeClipping(); - return new Effect.Scale(element, 5, Object.extend({ - scaleContent: false, - scaleX: false, - afterFinishInternal: function(effect) { - new Effect.Scale(element, 1, { - scaleContent: false, - scaleY: false, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().setStyle(oldStyle); - } }); - }}, arguments[1] || { })); -}; - -Effect.Morph = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - 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'; - color = color.parseColor(); - return $R(0,2).map(function(i){ - return parseInt( color.slice(i*2+1,i*2+3), 16 ); - }); - } - 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) || - ( - transform.unit != 'color' && - (isNaN(transform.originalValue) || isNaN(transform.targetValue)) - ) - ); - }); - }, - update: function(position) { - 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({ - initialize: function(tracks){ - this.tracks = []; - this.options = arguments[1] || { }; - this.addTracks(tracks); - }, - addTracks: function(tracks){ - tracks.each(function(track){ - track = $H(track); - var data = track.values().first(); - this.tracks.push($H({ - ids: track.keys().first(), - effect: Effect.Morph, - options: { style: data } - })); - }.bind(this)); - return this; - }, - play: function(){ - return new Effect.Parallel( - this.tracks.map(function(track){ - 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 = $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 style, styleRules = $H(); - if (Prototype.Browser.WebKit) - style = new Element('div',{style:this}).style; - else { - String.__parseStyleElement.innerHTML = '
    '; - style = String.__parseStyleElement.childNodes[0].style; - } - - Element.CSS_PROPERTIES.each(function(property){ - if (style[property]) styleRules.set(property, style[property]); - }); - - if (Prototype.Browser.IE && this.include('opacity')) - styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); - - return styleRules; -}; - -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; - } -}; - -$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; - }; - } -); - -$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( - function(f) { Effect.Methods[f] = Element[f]; } -); - -Element.addMethods(Effect.Methods); diff --git a/vendor/impressionist/test_app/public/javascripts/prototype.js b/vendor/impressionist/test_app/public/javascripts/prototype.js deleted file mode 100644 index 06249a6a..00000000 --- a/vendor/impressionist/test_app/public/javascripts/prototype.js +++ /dev/null @@ -1,6001 +0,0 @@ -/* Prototype JavaScript framework, version 1.7_rc2 - * (c) 2005-2010 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - - Version: '1.7_rc2', - - Browser: (function(){ - var ua = navigator.userAgent; - var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; - return { - IE: !!window.attachEvent && !isOpera, - Opera: isOpera, - WebKit: ua.indexOf('AppleWebKit/') > -1, - Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, - MobileSafari: /Apple.*Mobile/.test(ua) - } - })(), - - BrowserFeatures: { - XPath: !!document.evaluate, - - SelectorsAPI: !!document.querySelector, - - ElementExtensions: (function() { - var constructor = window.Element || window.HTMLElement; - return !!(constructor && constructor.prototype); - })(), - SpecificElementExtensions: (function() { - if (typeof window.HTMLDivElement !== 'undefined') - return true; - - var div = document.createElement('div'), - form = document.createElement('form'), - isSupported = false; - - if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { - isSupported = true; - } - - div = form = null; - - return isSupported; - })() - }, - - ScriptFragment: ']*>([\\S\\s]*?)<\/script>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; - - -var Abstract = { }; - - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -/* Based on Alex Arnell's inheritance implementation. */ - -var Class = (function() { - - var IS_DONTENUM_BUGGY = (function(){ - for (var p in { toString: 1 }) { - if (p === 'toString') return false; - } - return true; - })(); - - function subclass() {}; - function create() { - 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) { - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0, length = properties.length; i < length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - return klass; - } - - function addMethods(source) { - var ancestor = this.superclass && this.superclass.prototype, - properties = Object.keys(source); - - if (IS_DONTENUM_BUGGY) { - if (source.toString != Object.prototype.toString) - properties.push("toString"); - if (source.valueOf != Object.prototype.valueOf) - properties.push("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()[0] == "$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; - } - - return { - create: create, - Methods: { - addMethods: addMethods - } - }; -})(); -(function() { - - var _toString = Object.prototype.toString, - NULL_TYPE = 'Null', - UNDEFINED_TYPE = 'Undefined', - BOOLEAN_TYPE = 'Boolean', - NUMBER_TYPE = 'Number', - STRING_TYPE = 'String', - OBJECT_TYPE = 'Object', - BOOLEAN_CLASS = '[object Boolean]', - NUMBER_CLASS = '[object Number]', - STRING_CLASS = '[object String]', - ARRAY_CLASS = '[object Array]', - NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && - typeof JSON.stringify === 'function' && - JSON.stringify(0) === '0' && - typeof JSON.stringify(Prototype.K) === 'undefined'; - - function Type(o) { - switch(o) { - case null: return NULL_TYPE; - case (void 0): return UNDEFINED_TYPE; - } - var type = typeof o; - switch(type) { - case 'boolean': return BOOLEAN_TYPE; - case 'number': return NUMBER_TYPE; - case 'string': return STRING_TYPE; - } - return OBJECT_TYPE; - } - - function extend(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; - } - - function inspect(object) { - try { - if (isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - } - - function toJSON(value) { - return Str('', { '': value }, []); - } - - function Str(key, holder, stack) { - var value = holder[key], - type = typeof value; - - if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - - var _class = _toString.call(value); - - switch (_class) { - case NUMBER_CLASS: - case BOOLEAN_CLASS: - case STRING_CLASS: - value = value.valueOf(); - } - - switch (value) { - case null: return 'null'; - case true: return 'true'; - case false: return 'false'; - } - - type = typeof value; - switch (type) { - case 'string': - return value.inspect(true); - case 'number': - return isFinite(value) ? String(value) : 'null'; - case 'object': - - for (var i = 0, length = stack.length; i < length; i++) { - if (stack[i] === value) { throw new TypeError(); } - } - stack.push(value); - - var partial = []; - if (_class === ARRAY_CLASS) { - for (var i = 0, length = value.length; i < length; i++) { - var str = Str(i, value, stack); - partial.push(typeof str === 'undefined' ? 'null' : str); - } - partial = '[' + partial.join(',') + ']'; - } else { - var keys = Object.keys(value); - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i], str = Str(key, value, stack); - if (typeof str !== "undefined") { - partial.push(key.inspect(true)+ ':' + str); - } - } - partial = '{' + partial.join(',') + '}'; - } - stack.pop(); - return partial; - } - } - - function stringify(object) { - return JSON.stringify(object); - } - - function toQueryString(object) { - return $H(object).toQueryString(); - } - - function toHTML(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - } - - function keys(object) { - if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } - var results = []; - for (var property in object) { - if (object.hasOwnProperty(property)) { - results.push(property); - } - } - return results; - } - - function values(object) { - var results = []; - for (var property in object) - results.push(object[property]); - return results; - } - - function clone(object) { - return extend({ }, object); - } - - function isElement(object) { - return !!(object && object.nodeType == 1); - } - - function isArray(object) { - return _toString.call(object) === ARRAY_CLASS; - } - - var hasNativeIsArray = (typeof Array.isArray == 'function') - && Array.isArray([]) && !Array.isArray({}); - - if (hasNativeIsArray) { - isArray = Array.isArray; - } - - function isHash(object) { - return object instanceof Hash; - } - - function isFunction(object) { - return typeof object === "function"; - } - - function isString(object) { - return _toString.call(object) === STRING_CLASS; - } - - function isNumber(object) { - return _toString.call(object) === NUMBER_CLASS; - } - - function isUndefined(object) { - return typeof object === "undefined"; - } - - extend(Object, { - extend: extend, - inspect: inspect, - toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, - toQueryString: toQueryString, - toHTML: toHTML, - keys: Object.keys || keys, - values: values, - clone: clone, - isElement: isElement, - isArray: isArray, - isHash: isHash, - isFunction: isFunction, - isString: isString, - isNumber: isNumber, - isUndefined: isUndefined - }); -})(); -Object.extend(Function.prototype, (function() { - var slice = Array.prototype.slice; - - function update(array, args) { - var arrayLength = array.length, length = args.length; - while (length--) array[arrayLength + length] = args[length]; - return array; - } - - function merge(array, args) { - array = slice.call(array, 0); - return update(array, args); - } - - function argumentNames() { - var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] - .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') - .replace(/\s+/g, '').split(','); - return names.length == 1 && !names[0] ? [] : names; - } - - function bind(context) { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; - var __method = this, args = slice.call(arguments, 1); - return function() { - var a = merge(args, arguments); - return __method.apply(context, a); - } - } - - function bindAsEventListener(context) { - var __method = this, args = slice.call(arguments, 1); - return function(event) { - var a = update([event || window.event], args); - return __method.apply(context, a); - } - } - - function curry() { - if (!arguments.length) return this; - var __method = this, args = slice.call(arguments, 0); - return function() { - var a = merge(args, arguments); - return __method.apply(this, a); - } - } - - function delay(timeout) { - var __method = this, args = slice.call(arguments, 1); - timeout = timeout * 1000; - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - } - - function defer() { - var args = update([0.01], arguments); - return this.delay.apply(this, args); - } - - function wrap(wrapper) { - var __method = this; - return function() { - var a = update([__method.bind(this)], arguments); - return wrapper.apply(this, a); - } - } - - function methodize() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - var a = update([this], arguments); - return __method.apply(null, a); - }; - } - - return { - argumentNames: argumentNames, - bind: bind, - bindAsEventListener: bindAsEventListener, - curry: curry, - delay: delay, - defer: defer, - wrap: wrap, - methodize: methodize - } -})()); - - - -(function(proto) { - - - function toISOString() { - 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'; - } - - - function toJSON() { - return this.toISOString(); - } - - if (!proto.toISOString) proto.toISOString = toISOString; - if (!proto.toJSON) proto.toJSON = toJSON; - -})(Date.prototype); - - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - this.currentlyExecuting = false; - } catch(e) { - this.currentlyExecuting = false; - throw e; - } - } - } -}); -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, (function() { - var NATIVE_JSON_PARSE_SUPPORT = window.JSON && - typeof JSON.parse === 'function' && - JSON.parse('{"test": true}').test; - - function prepareReplacement(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; - } - - function gsub(pattern, replacement) { - var result = '', source = this, match; - replacement = prepareReplacement(replacement); - - if (Object.isString(pattern)) - pattern = RegExp.escape(pattern); - - if (!(pattern.length || pattern.source)) { - replacement = replacement(''); - return replacement + source.split('').join(replacement) + replacement; - } - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - } - - function sub(pattern, replacement, count) { - replacement = prepareReplacement(replacement); - count = Object.isUndefined(count) ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - } - - function scan(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - } - - function truncate(length, truncation) { - length = length || 30; - truncation = Object.isUndefined(truncation) ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - } - - function strip() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - } - - function stripTags() { - return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); - } - - function stripScripts() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - } - - function extractScripts() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), - matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - } - - function evalScripts() { - return this.extractScripts().map(function(script) { return eval(script) }); - } - - function escapeHTML() { - return this.replace(/&/g,'&').replace(//g,'>'); - } - - function unescapeHTML() { - return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); - } - - - function toQueryParams(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()), - value = pair.length > 1 ? pair.join('=') : pair[0]; - - if (value != undefined) value = decodeURIComponent(value); - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - } - - function toArray() { - return this.split(''); - } - - function succ() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - } - - function times(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - } - - function camelize() { - return this.replace(/-+(.)?/g, function(match, chr) { - return chr ? chr.toUpperCase() : ''; - }); - } - - function capitalize() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - } - - function underscore() { - return this.replace(/::/g, '/') - .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') - .replace(/([a-z\d])([A-Z])/g, '$1_$2') - .replace(/-/g, '_') - .toLowerCase(); - } - - function dasherize() { - return this.replace(/_/g, '-'); - } - - function inspect(useDoubleQuotes) { - var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { - if (character in String.specialChar) { - return String.specialChar[character]; - } - return '\\u00' + character.charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - } - - function unfilterJSON(filter) { - return this.replace(filter || Prototype.JSONFilter, '$1'); - } - - function isJSON() { - var str = this; - if (str.blank()) return false; - str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); - str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); - str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); - return (/^[\],:{}\s]*$/).test(str); - } - - function evalJSON(sanitize) { - var json = this.unfilterJSON(), - cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - if (cx.test(json)) { - json = json.replace(cx, function (a) { - return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - } - - function parseJSON() { - var json = this.unfilterJSON(); - return JSON.parse(json); - } - - function include(pattern) { - return this.indexOf(pattern) > -1; - } - - function startsWith(pattern) { - return this.lastIndexOf(pattern, 0) === 0; - } - - function endsWith(pattern) { - var d = this.length - pattern.length; - return d >= 0 && this.indexOf(pattern, d) === d; - } - - function empty() { - return this == ''; - } - - function blank() { - return /^\s*$/.test(this); - } - - function interpolate(object, pattern) { - return new Template(this, pattern).evaluate(object); - } - - return { - gsub: gsub, - sub: sub, - scan: scan, - truncate: truncate, - strip: String.prototype.trim || strip, - stripTags: stripTags, - stripScripts: stripScripts, - extractScripts: extractScripts, - evalScripts: evalScripts, - escapeHTML: escapeHTML, - unescapeHTML: unescapeHTML, - toQueryParams: toQueryParams, - parseQuery: toQueryParams, - toArray: toArray, - succ: succ, - times: times, - camelize: camelize, - capitalize: capitalize, - underscore: underscore, - dasherize: dasherize, - inspect: inspect, - unfilterJSON: unfilterJSON, - isJSON: isJSON, - evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, - include: include, - startsWith: startsWith, - endsWith: endsWith, - empty: empty, - blank: blank, - interpolate: interpolate - }; -})()); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (object && Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return (match[1] + ''); - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3], - pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; - - match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : 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 = { }; - -var Enumerable = (function() { - function each(iterator, context) { - var index = 0; - try { - this._each(function(value) { - iterator.call(context, value, index++); - }); - } catch (e) { - if (e != $break) throw e; - } - return this; - } - - function eachSlice(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.collect(iterator, context); - } - - function all(iterator, context) { - iterator = iterator || Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator.call(context, value, index); - if (!result) throw $break; - }); - return result; - } - - function any(iterator, context) { - iterator = iterator || Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator.call(context, value, index)) - throw $break; - }); - return result; - } - - function collect(iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator.call(context, value, index)); - }); - return results; - } - - function detect(iterator, context) { - var result; - this.each(function(value, index) { - if (iterator.call(context, value, index)) { - result = value; - throw $break; - } - }); - return result; - } - - function findAll(iterator, context) { - var results = []; - this.each(function(value, index) { - if (iterator.call(context, value, index)) - results.push(value); - }); - return results; - } - - function grep(filter, iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(RegExp.escape(filter)); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator.call(context, value, index)); - }); - return results; - } - - function include(object) { - if (Object.isFunction(this.indexOf)) - if (this.indexOf(object) != -1) return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - } - - function inGroupsOf(number, fillWith) { - fillWith = Object.isUndefined(fillWith) ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - } - - function inject(memo, iterator, context) { - this.each(function(value, index) { - memo = iterator.call(context, memo, value, index); - }); - return memo; - } - - function invoke(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - } - - function max(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index); - if (result == null || value >= result) - result = value; - }); - return result; - } - - function min(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index); - if (result == null || value < result) - result = value; - }); - return result; - } - - function partition(iterator, context) { - iterator = iterator || Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator.call(context, value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - } - - function pluck(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - } - - function reject(iterator, context) { - var results = []; - this.each(function(value, index) { - if (!iterator.call(context, value, index)) - results.push(value); - }); - return results; - } - - function sortBy(iterator, context) { - return this.map(function(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; - }).pluck('value'); - } - - function toArray() { - return this.map(); - } - - function zip() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - } - - function size() { - return this.toArray().length; - } - - function inspect() { - return '#'; - } - - - - - - - - - - return { - each: each, - eachSlice: eachSlice, - all: all, - every: all, - any: any, - some: any, - collect: collect, - map: collect, - detect: detect, - findAll: findAll, - select: findAll, - filter: findAll, - grep: grep, - include: include, - member: include, - inGroupsOf: inGroupsOf, - inject: inject, - invoke: invoke, - max: max, - min: min, - partition: partition, - pluck: pluck, - reject: reject, - sortBy: sortBy, - toArray: toArray, - entries: toArray, - zip: zip, - size: size, - inspect: inspect, - find: detect - }; -})(); - -function $A(iterable) { - if (!iterable) return []; - if ('toArray' in Object(iterable)) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -Array.from = $A; - - -(function() { - var arrayProto = Array.prototype, - slice = arrayProto.slice, - _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available - - function each(iterator) { - for (var i = 0, length = this.length; i < length; i++) - iterator(this[i]); - } - if (!_each) _each = each; - - function clear() { - this.length = 0; - return this; - } - - function first() { - return this[0]; - } - - function last() { - return this[this.length - 1]; - } - - function compact() { - return this.select(function(value) { - return value != null; - }); - } - - function flatten() { - return this.inject([], function(array, value) { - if (Object.isArray(value)) - return array.concat(value.flatten()); - array.push(value); - return array; - }); - } - - function without() { - var values = slice.call(arguments, 0); - return this.select(function(value) { - return !values.include(value); - }); - } - - function reverse(inline) { - return (inline === false ? this.toArray() : this)._reverse(); - } - - function uniq(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - } - - function intersect(array) { - return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); - }); - } - - - function clone() { - return slice.call(this, 0); - } - - function size() { - return this.length; - } - - function inspect() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } - - function indexOf(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; - } - - function lastIndexOf(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; - } - - function concat() { - var array = slice.call(this, 0), item; - for (var i = 0, length = arguments.length; i < length; i++) { - item = arguments[i]; - if (Object.isArray(item) && !('callee' in item)) { - for (var j = 0, arrayLength = item.length; j < arrayLength; j++) - array.push(item[j]); - } else { - array.push(item); - } - } - return array; - } - - Object.extend(arrayProto, Enumerable); - - if (!arrayProto._reverse) - arrayProto._reverse = arrayProto.reverse; - - Object.extend(arrayProto, { - _each: _each, - clear: clear, - first: first, - last: last, - compact: compact, - flatten: flatten, - without: without, - reverse: reverse, - uniq: uniq, - intersect: intersect, - clone: clone, - toArray: clone, - size: size, - inspect: inspect - }); - - var CONCAT_ARGUMENTS_BUGGY = (function() { - return [].concat(arguments)[0][0] !== 1; - })(1,2) - - if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; - - if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; - if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; -})(); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - function initialize(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - } - - - function _each(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - - function set(key, value) { - return this._object[key] = value; - } - - function get(key) { - if (this._object[key] !== Object.prototype[key]) - return this._object[key]; - } - - function unset(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - } - - function toObject() { - return Object.clone(this._object); - } - - - - function keys() { - return this.pluck('key'); - } - - function values() { - return this.pluck('value'); - } - - function index(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - } - - function merge(object) { - return this.clone().update(object); - } - - function update(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - } - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); - } - - function toQueryString() { - 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('&'); - } - - function inspect() { - return '#'; - } - - function clone() { - return new Hash(this); - } - - return { - initialize: initialize, - _each: _each, - set: set, - get: get, - unset: unset, - toObject: toObject, - toTemplateReplacements: toObject, - keys: keys, - values: values, - index: index, - merge: merge, - update: update, - toQueryString: toQueryString, - inspect: inspect, - toJSON: toObject, - clone: clone - }; -})()); - -Hash.from = $H; -Object.extend(Number.prototype, (function() { - function toColorPart() { - return this.toPaddedString(2, 16); - } - - function succ() { - return this + 1; - } - - function times(iterator, context) { - $R(0, this, true).each(iterator, context); - return this; - } - - function toPaddedString(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - } - - function abs() { - return Math.abs(this); - } - - function round() { - return Math.round(this); - } - - function ceil() { - return Math.ceil(this); - } - - function floor() { - return Math.floor(this); - } - - return { - toColorPart: toColorPart, - succ: succ, - times: times, - toPaddedString: toPaddedString, - abs: abs, - round: round, - ceil: ceil, - floor: floor - }; -})()); - -function $R(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -} - -var ObjectRange = Class.create(Enumerable, (function() { - function initialize(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - } - - function _each(iterator) { - var value = this.start; - while (this.include(value)) { - iterator(value); - value = value.succ(); - } - } - - function include(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } - - return { - initialize: initialize, - _each: _each, - include: include - }; -})()); - - - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - - 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.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.clone(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - params['_method'] = this.method; - this.method = 'post'; - } - - this.parameters = params; - - if (params = Object.toQueryString(params)) { - if (this.method == 'get') - this.url += (this.url.include('?') ? '&' : '?') + params; - else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) - params += '&_='; - } - - try { - 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) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - 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], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - 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)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - 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 : '' - })); - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name) || null; - } catch (e) { return null; } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - - - - - - - - -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)) - }; - - options = Object.clone(options); - var onComplete = options.onComplete; - options.onComplete = (function(response, json) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, json); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - 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); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); - - -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} - -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - 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(Element.extend(query.snapshotItem(i))); - return results; - }; -} - -/*--------------------------------------------------------------------------*/ - -if (!Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - 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 - }); -} - - - -(function(global) { - - var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ - try { - var el = document.createElement(''); - return el.tagName.toLowerCase() === 'input' && el.name === 'x'; - } - catch(err) { - return false; - } - })(); - - var element = global.Element; - - global.Element = function(tagName, attributes) { - attributes = attributes || { }; - tagName = tagName.toLowerCase(); - var cache = Element.cache; - if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && 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(global.Element, element || { }); - if (element) global.Element.prototype = element.prototype; - -})(this); - -Element.idCounter = 1; -Element.cache = { }; - -function purgeElement(element) { - var uid = element._prototypeUID; - if (uid) { - Element.stopObserving(element); - element._prototypeUID = void 0; - delete Element.Storage[uid]; - } -} - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function(element) { - element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); - return element; - }, - - hide: function(element) { - element = $(element); - element.style.display = 'none'; - return element; - }, - - show: function(element) { - element = $(element); - element.style.display = ''; - return element; - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - }, - - update: (function(){ - - var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ - var el = document.createElement("select"), - isBuggy = true; - el.innerHTML = ""; - if (el.options && el.options[0]) { - isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; - } - el = null; - return isBuggy; - })(); - - var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ - try { - var el = document.createElement("table"); - if (el && el.tBodies) { - el.innerHTML = "test"; - var isBuggy = typeof el.tBodies[0] == "undefined"; - el = null; - return isBuggy; - } - } catch (e) { - return true; - } - })(); - - var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { - var s = document.createElement("script"), - isBuggy = false; - try { - s.appendChild(document.createTextNode("")); - isBuggy = !s.firstChild || - s.firstChild && s.firstChild.nodeType !== 3; - } catch (e) { - isBuggy = true; - } - s = null; - return isBuggy; - })(); - - function update(element, content) { - element = $(element); - - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - while (i--) purgeElement(descendants[i]); - - 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 === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { - element.text = content; - return element; - } - - if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) { - if (tagName in Element._insertionTranslations.tags) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { - element.appendChild(node) - }); - } - else { - element.innerHTML = content.stripScripts(); - } - } - else { - element.innerHTML = content.stripScripts(); - } - - content.evalScripts.bind(content).defer(); - return element; - } - - return update; - })(), - - replace: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - 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(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), - attribute = pair.last(), - value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, - - recursivelyCollect: function(element, property, maximumLength) { - element = $(element); - maximumLength = maximumLength || -1; - var elements = []; - - while (element = element[property]) { - if (element.nodeType == 1) - elements.push(Element.extend(element)); - if (elements.length == maximumLength) - break; - } - - return elements; - }, - - ancestors: function(element) { - return Element.recursivelyCollect(element, 'parentNode'); - }, - - descendants: function(element) { - return Element.select(element, "*"); - }, - - firstDescendant: function(element) { - element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; - return $(element); - }, - - immediateDescendants: function(element) { - var results = [], child = $(element).firstChild; - while (child) { - if (child.nodeType === 1) { - results.push(Element.extend(child)); - } - child = child.nextSibling; - } - return results; - }, - - previousSiblings: function(element, maximumLength) { - return Element.recursivelyCollect(element, 'previousSibling'); - }, - - nextSiblings: function(element) { - return Element.recursivelyCollect(element, 'nextSibling'); - }, - - siblings: function(element) { - element = $(element); - return Element.previousSiblings(element).reverse() - .concat(Element.nextSiblings(element)); - }, - - match: function(element, selector) { - element = $(element); - if (Object.isString(selector)) - return Prototype.Selector.match(element, selector); - return selector.match(element); - }, - - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = Element.ancestors(element); - return Object.isNumber(expression) ? ancestors[expression] : - Prototype.Selector.find(ancestors, expression, index); - }, - - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return Element.firstDescendant(element); - return Object.isNumber(expression) ? Element.descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - }, - - previous: function(element, expression, index) { - element = $(element); - if (Object.isNumber(expression)) index = expression, expression = false; - if (!Object.isNumber(index)) index = 0; - - if (expression) { - return Prototype.Selector.find(element.previousSiblings(), expression, index); - } else { - return element.recursivelyCollect("previousSibling", index + 1)[index]; - } - }, - - next: function(element, expression, index) { - element = $(element); - if (Object.isNumber(expression)) index = expression, expression = false; - if (!Object.isNumber(index)) index = 0; - - if (expression) { - return Prototype.Selector.find(element.nextSiblings(), expression, index); - } else { - var maximumLength = Object.isNumber(index) ? index + 1 : 1; - return element.recursivelyCollect("nextSibling", index + 1)[index]; - } - }, - - - select: function(element) { - element = $(element); - var expressions = Array.prototype.slice.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element); - }, - - adjacent: function(element) { - element = $(element); - var expressions = Array.prototype.slice.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element.parentNode).without(element); - }, - - identify: function(element) { - element = $(element); - var id = Element.readAttribute(element, 'id'); - if (id) return id; - do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); - Element.writeAttribute(element, 'id', id); - return id; - }, - - readAttribute: function(element, name) { - element = $(element); - 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]; - 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(element).height; - }, - - getWidth: function(element) { - return Element.getDimensions(element).width; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!Element.hasClassName(element, className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, - - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return Element[Element.hasClassName(element, className) ? - 'removeClassName' : 'addClassName'](element, className); - }, - - cleanWhitespace: function(element) { - element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - - empty: function(element) { - 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 = Element.cumulativeOffset(element); - window.scrollTo(pos[0], pos[1]); - return element; - }, - - getStyle: function(element, style) { - element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[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; - }, - - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, - - 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; - } - 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; - }, - - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - if (Prototype.Browser.Opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, - - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - if (element.parentNode) { - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - } - return Element._returnOffset(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.toUpperCase() == 'BODY') break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - absolutize: function(element) { - element = $(element); - if (Element.getStyle(element, 'position') == 'absolute') return element; - - var offsets = Element.positionedOffset(element), - top = offsets[1], - left = offsets[0], - width = element.clientWidth, - 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; - }, - - relativize: function(element) { - element = $(element); - if (Element.getStyle(element, 'position') == 'relative') return element; - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0), - 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; - }, - - 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); - }, - - 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, - element = forElement; - - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - 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] || { }); - - source = $(source); - var p = Element.viewportOffset(source), delta = [0, 0], parent = null; - - element = $(element); - - if (Element.getStyle(element, 'position') == 'absolute') { - parent = Element.getOffsetParent(element); - delta = Element.viewportOffset(parent); - } - - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - 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.Methods, { - getElementsBySelector: Element.Methods.select, - - childElements: Element.Methods.immediateDescendants -}); - -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } - } -}; - -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': - if (!Element.visible(element)) return null; - - 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) { - Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( - function(proceed, element) { - element = $(element); - if (!element.parentNode) 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); - if (!element.parentNode) return Element._returnOffset(0, 0); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - 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.getStyle = function(element, style) { - element = $(element); - 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 = (function(){ - - var classProp = 'className', - forProp = 'for', - el = document.createElement('div'); - - el.setAttribute(classProp, 'x'); - - if (el.className !== 'x') { - el.setAttribute('class', 'x'); - if (el.className === 'x') { - classProp = 'class'; - } - } - el = null; - - el = document.createElement('label'); - el.setAttribute(forProp, 'x'); - if (el.htmlFor !== 'x') { - el.setAttribute('htmlFor', 'x'); - if (el.htmlFor === 'x') { - forProp = 'htmlFor'; - } - } - el = null; - - return { - read: { - names: { - 'class': classProp, - 'className': classProp, - 'for': forProp, - 'htmlFor': forProp - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute); - }, - _getAttr2: function(element, attribute) { - return element.getAttribute(attribute, 2); - }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: (function(){ - - var el = document.createElement('div'), f; - el.onclick = Prototype.emptyFunction; - var value = el.getAttribute('onclick'); - - if (String(value).indexOf('{') > -1) { - f = function(element, attribute) { - attribute = element.getAttribute(attribute); - if (!attribute) return null; - attribute = attribute.toString(); - attribute = attribute.split('{')[1]; - attribute = attribute.split('}')[0]; - return attribute.strip(); - }; - } - else if (value === '') { - f = function(element, attribute) { - attribute = element.getAttribute(attribute); - if (!attribute) return null; - return attribute.strip(); - }; - } - el = null; - return f; - })(), - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - } - } - })(); - - 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 : ''; - } - } - }; - - 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._getAttr2, - src: v._getAttr2, - 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); - - if (Prototype.BrowserFeatures.ElementExtensions) { - (function() { - function _descendants(element) { - var nodes = element.getElementsByTagName('*'), results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName !== "!") // Filter out comment nodes. - results.push(node); - return results; - } - - Element.Methods.down = function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return element.firstDescendant(); - return Object.isNumber(expression) ? _descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - } - })(); - } - -} - -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; - }; - - 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 ('outerHTML' in document.documentElement) { - 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(), - 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]; - for (var i = t[2]; i--; ) { - 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: ['', '
    ', 1], - TBODY: ['', '
    ', 2], - TR: ['', '
    ', 3], - TD: ['
    ', '
    ', 4], - SELECT: ['', 1] - } -}; - -(function() { - var tags = Element._insertionTranslations.tags; - Object.extend(tags, { - THEAD: tags.TBODY, - TFOOT: tags.TBODY, - TH: tags.TD - }); -})(); - -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); - -(function(div) { - - if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { - window.HTMLElement = { }; - window.HTMLElement.prototype = div['__proto__']; - Prototype.BrowserFeatures.ElementExtensions = true; - } - - div = null; - -})(document.createElement('div')); - -Element.extend = (function() { - - function checkDeficiency(tagName) { - if (typeof window.Element != 'undefined') { - var proto = window.Element.prototype; - if (proto) { - var id = '_' + (Math.random()+'').slice(2), - el = document.createElement(tagName); - proto[id] = 'x'; - var isBuggy = (el[id] !== 'x'); - delete proto[id]; - el = null; - return isBuggy; - } - } - return false; - } - - function extendElementWith(element, methods) { - for (var property in methods) { - var value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - } - - var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); - - if (Prototype.BrowserFeatures.SpecificElementExtensions) { - if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { - return function(element) { - if (element && typeof element._extendedByPrototype == 'undefined') { - var t = element.tagName; - if (t && (/^(?:object|applet|embed)$/i.test(t))) { - extendElementWith(element, Element.Methods); - extendElementWith(element, Element.Methods.Simulated); - extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); - } - } - return element; - } - } - return Prototype.K; - } - - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || typeof element._extendedByPrototype != 'undefined' || - element.nodeType != 1 || element == window) return element; - - var methods = Object.clone(Methods), - tagName = element.tagName.toUpperCase(); - - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - extendElementWith(element, methods); - - element._extendedByPrototype = Prototype.emptyFunction; - return element; - - }, { - refresh: function() { - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -if (document.documentElement.hasAttribute) { - Element.hasAttribute = function(element, attribute) { - return element.hasAttribute(attribute); - }; -} -else { - Element.hasAttribute = Element.Methods.Simulated.hasAttribute; -} - -Element.addMethods = function(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) { - onlyIfAbsent = onlyIfAbsent || false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - 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]; - - var element = document.createElement(tagName), - proto = element['__proto__'] || element.constructor.prototype; - - element = null; - return proto; - } - - var elementPrototype = window.HTMLElement ? HTMLElement.prototype : - Element.prototype; - - if (F.ElementExtensions) { - copy(Element.Methods, elementPrototype); - copy(Element.Methods.Simulated, elementPrototype, true); - } - - 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; - - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; - - -document.viewport = { - - getDimensions: function() { - return { width: this.getWidth(), height: this.getHeight() }; - }, - - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); - } -}; - -(function(viewport) { - var B = Prototype.Browser, doc = document, element, property = {}; - - function getRootElement() { - if (B.WebKit && !doc.evaluate) - return document; - - if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) - return document.body; - - return document.documentElement; - } - - function define(D) { - if (!element) element = getRootElement(); - - property[D] = 'client' + D; - - viewport['get' + D] = function() { return element[property[D]] }; - return viewport['get' + D](); - } - - viewport.getWidth = define.curry('Width'); - - viewport.getHeight = define.curry('Height'); -})(document.viewport); - - -Element.Storage = { - UID: 1 -}; - -Element.addMethods({ - getStorage: function(element) { - if (!(element = $(element))) return; - - var uid; - if (element === window) { - uid = 0; - } else { - if (typeof element._prototypeUID === "undefined") - element._prototypeUID = Element.Storage.UID++; - uid = element._prototypeUID; - } - - if (!Element.Storage[uid]) - Element.Storage[uid] = $H(); - - return Element.Storage[uid]; - }, - - store: function(element, key, value) { - if (!(element = $(element))) return; - - if (arguments.length === 2) { - Element.getStorage(element).update(key); - } else { - Element.getStorage(element).set(key, value); - } - - return element; - }, - - retrieve: function(element, key, defaultValue) { - if (!(element = $(element))) return; - var hash = Element.getStorage(element), value = hash.get(key); - - if (Object.isUndefined(value)) { - hash.set(key, defaultValue); - value = defaultValue; - } - - return value; - }, - - clone: function(element, deep) { - if (!(element = $(element))) return; - var clone = element.cloneNode(deep); - clone._prototypeUID = void 0; - if (deep) { - var descendants = Element.select(clone, '*'), - i = descendants.length; - while (i--) { - descendants[i]._prototypeUID = void 0; - } - } - return Element.extend(clone); - }, - - purge: function(element) { - if (!(element = $(element))) return; - purgeElement(element); - - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - - while (i--) purgeElement(descendants[i]); - - return null; - } -}); - -(function() { - - function toDecimal(pctString) { - var match = pctString.match(/^(\d+)%?$/i); - if (!match) return null; - return (Number(match[1]) / 100); - } - - function getPixelValue(value, property) { - if (Object.isElement(value)) { - element = value; - value = element.getStyle(property); - } - if (value === null) { - return null; - } - - if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { - return window.parseFloat(value); - } - - if (/\d/.test(value) && element.runtimeStyle) { - var style = element.style.left, rStyle = element.runtimeStyle.left; - element.runtimeStyle.left = element.currentStyle.left; - element.style.left = value || 0; - value = element.style.pixelLeft; - element.style.left = style; - element.runtimeStyle.left = rStyle; - - return value; - } - - if (value.include('%')) { - var decimal = toDecimal(value); - var whole; - if (property.include('left') || property.include('right') || - property.include('width')) { - whole = $(element.parentNode).measure('width'); - } else if (property.include('top') || property.include('bottom') || - property.include('height')) { - whole = $(element.parentNode).measure('height'); - } - - return whole * decimal; - } - - return 0; - } - - function toCSSPixels(number) { - if (Object.isString(number) && number.endsWith('px')) { - return number; - } - return number + 'px'; - } - - function isDisplayed(element) { - var originalElement = element; - while (element && element.parentNode) { - var display = element.getStyle('display'); - if (display === 'none') { - return false; - } - element = $(element.parentNode); - } - return true; - } - - var hasLayout = Prototype.K; - if ('currentStyle' in document.documentElement) { - hasLayout = function(element) { - if (!element.currentStyle.hasLayout) { - element.style.zoom = 1; - } - return element; - }; - } - - function cssNameFor(key) { - if (key.include('border')) key = key + '-width'; - return key.camelize(); - } - - Element.Layout = Class.create(Hash, { - initialize: function($super, element, preCompute) { - $super(); - this.element = $(element); - - Element.Layout.PROPERTIES.each( function(property) { - this._set(property, null); - }, this); - - if (preCompute) { - this._preComputing = true; - this._begin(); - Element.Layout.PROPERTIES.each( this._compute, this ); - this._end(); - this._preComputing = false; - } - }, - - _set: function(property, value) { - return Hash.prototype.set.call(this, property, value); - }, - - set: function(property, value) { - throw "Properties of Element.Layout are read-only."; - }, - - get: function($super, property) { - var value = $super(property); - return value === null ? this._compute(property) : value; - }, - - _begin: function() { - if (this._prepared) return; - - var element = this.element; - if (isDisplayed(element)) { - this._prepared = true; - return; - } - - var originalStyles = { - position: element.style.position || '', - width: element.style.width || '', - visibility: element.style.visibility || '', - display: element.style.display || '' - }; - - element.store('prototype_original_styles', originalStyles); - - var position = element.getStyle('position'), - width = element.getStyle('width'); - - element.setStyle({ - position: 'absolute', - visibility: 'hidden', - display: 'block' - }); - - var positionedWidth = element.getStyle('width'); - - var newWidth; - if (width && (positionedWidth === width)) { - newWidth = getPixelValue(width); - } else if (width && (position === 'absolute' || position === 'fixed')) { - newWidth = getPixelValue(width); - } else { - var parent = element.parentNode, pLayout = $(parent).getLayout(); - - newWidth = pLayout.get('width') - - this.get('margin-left') - - this.get('border-left') - - this.get('padding-left') - - this.get('padding-right') - - this.get('border-right') - - this.get('margin-right'); - } - - element.setStyle({ width: newWidth + 'px' }); - - this._prepared = true; - }, - - _end: function() { - var element = this.element; - var originalStyles = element.retrieve('prototype_original_styles'); - element.store('prototype_original_styles', null); - element.setStyle(originalStyles); - this._prepared = false; - }, - - _compute: function(property) { - var COMPUTATIONS = Element.Layout.COMPUTATIONS; - if (!(property in COMPUTATIONS)) { - throw "Property not found."; - } - return this._set(property, COMPUTATIONS[property].call(this, this.element)); - }, - - toObject: function() { - var args = $A(arguments); - var keys = (args.length === 0) ? Element.Layout.PROPERTIES : - args.join(' ').split(' '); - var obj = {}; - keys.each( function(key) { - if (!Element.Layout.PROPERTIES.include(key)) return; - var value = this.get(key); - if (value != null) obj[key] = value; - }, this); - return obj; - }, - - toHash: function() { - var obj = this.toObject.apply(this, arguments); - return new Hash(obj); - }, - - toCSS: function() { - var args = $A(arguments); - var keys = (args.length === 0) ? Element.Layout.PROPERTIES : - args.join(' ').split(' '); - var css = {}; - - keys.each( function(key) { - if (!Element.Layout.PROPERTIES.include(key)) return; - if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; - - var value = this.get(key); - if (value != null) css[cssNameFor(key)] = value + 'px'; - }, this); - return css; - }, - - inspect: function() { - return "#"; - } - }); - - Object.extend(Element.Layout, { - PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'), - - COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'), - - COMPUTATIONS: { - 'height': function(element) { - if (!this._preComputing) this._begin(); - - var bHeight = this.get('border-box-height'); - if (bHeight <= 0) return 0; - - var bTop = this.get('border-top'), - bBottom = this.get('border-bottom'); - - var pTop = this.get('padding-top'), - pBottom = this.get('padding-bottom'); - - if (!this._preComputing) this._end(); - - return bHeight - bTop - bBottom - pTop - pBottom; - }, - - 'width': function(element) { - if (!this._preComputing) this._begin(); - - var bWidth = this.get('border-box-width'); - if (bWidth <= 0) return 0; - - var bLeft = this.get('border-left'), - bRight = this.get('border-right'); - - var pLeft = this.get('padding-left'), - pRight = this.get('padding-right'); - - if (!this._preComputing) this._end(); - - return bWidth - bLeft - bRight - pLeft - pRight; - }, - - 'padding-box-height': function(element) { - var height = this.get('height'), - pTop = this.get('padding-top'), - pBottom = this.get('padding-bottom'); - - return height + pTop + pBottom; - }, - - 'padding-box-width': function(element) { - var width = this.get('width'), - pLeft = this.get('padding-left'), - pRight = this.get('padding-right'); - - return width + pLeft + pRight; - }, - - 'border-box-height': function(element) { - return element.offsetHeight; - }, - - 'border-box-width': function(element) { - return element.offsetWidth; - }, - - 'margin-box-height': function(element) { - var bHeight = this.get('border-box-height'), - mTop = this.get('margin-top'), - mBottom = this.get('margin-bottom'); - - if (bHeight <= 0) return 0; - - return bHeight + mTop + mBottom; - }, - - 'margin-box-width': function(element) { - var bWidth = this.get('border-box-width'), - mLeft = this.get('margin-left'), - mRight = this.get('margin-right'); - - if (bWidth <= 0) return 0; - - return bWidth + mLeft + mRight; - }, - - 'top': function(element) { - var offset = element.positionedOffset(); - return offset.top; - }, - - 'bottom': function(element) { - var offset = element.positionedOffset(), - parent = element.getOffsetParent(), - pHeight = parent.measure('height'); - - var mHeight = this.get('border-box-height'); - - return pHeight - mHeight - offset.top; - }, - - 'left': function(element) { - var offset = element.positionedOffset(); - return offset.left; - }, - - 'right': function(element) { - var offset = element.positionedOffset(), - parent = element.getOffsetParent(), - pWidth = parent.measure('width'); - - var mWidth = this.get('border-box-width'); - - return pWidth - mWidth - offset.left; - }, - - 'padding-top': function(element) { - return getPixelValue(element, 'paddingTop'); - }, - - 'padding-bottom': function(element) { - return getPixelValue(element, 'paddingBottom'); - }, - - 'padding-left': function(element) { - return getPixelValue(element, 'paddingLeft'); - }, - - 'padding-right': function(element) { - return getPixelValue(element, 'paddingRight'); - }, - - 'border-top': function(element) { - return Object.isNumber(element.clientTop) ? element.clientTop : - getPixelValue(element, 'borderTopWidth'); - }, - - 'border-bottom': function(element) { - return Object.isNumber(element.clientBottom) ? element.clientBottom : - getPixelValue(element, 'borderBottomWidth'); - }, - - 'border-left': function(element) { - return Object.isNumber(element.clientLeft) ? element.clientLeft : - getPixelValue(element, 'borderLeftWidth'); - }, - - 'border-right': function(element) { - return Object.isNumber(element.clientRight) ? element.clientRight : - getPixelValue(element, 'borderRightWidth'); - }, - - 'margin-top': function(element) { - return getPixelValue(element, 'marginTop'); - }, - - 'margin-bottom': function(element) { - return getPixelValue(element, 'marginBottom'); - }, - - 'margin-left': function(element) { - return getPixelValue(element, 'marginLeft'); - }, - - 'margin-right': function(element) { - return getPixelValue(element, 'marginRight'); - } - } - }); - - if ('getBoundingClientRect' in document.documentElement) { - Object.extend(Element.Layout.COMPUTATIONS, { - 'right': function(element) { - var parent = hasLayout(element.getOffsetParent()); - var rect = element.getBoundingClientRect(), - pRect = parent.getBoundingClientRect(); - - return (pRect.right - rect.right).round(); - }, - - 'bottom': function(element) { - var parent = hasLayout(element.getOffsetParent()); - var rect = element.getBoundingClientRect(), - pRect = parent.getBoundingClientRect(); - - return (pRect.bottom - rect.bottom).round(); - } - }); - } - - Element.Offset = Class.create({ - initialize: function(left, top) { - this.left = left.round(); - this.top = top.round(); - - this[0] = this.left; - this[1] = this.top; - }, - - relativeTo: function(offset) { - return new Element.Offset( - this.left - offset.left, - this.top - offset.top - ); - }, - - inspect: function() { - return "#".interpolate(this); - }, - - toString: function() { - return "[#{left}, #{top}]".interpolate(this); - }, - - toArray: function() { - return [this.left, this.top]; - } - }); - - function getLayout(element, preCompute) { - return new Element.Layout(element, preCompute); - } - - function measure(element, property) { - return $(element).getLayout().get(property); - } - - function getDimensions(element) { - var layout = $(element).getLayout(); - return { - width: layout.get('width'), - height: layout.get('height') - }; - } - - function getOffsetParent(element) { - if (isDetached(element)) return $(document.body); - - var isInline = (Element.getStyle(element, 'display') === 'inline'); - if (!isInline && 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.nodeName === 'HTML') ? $(document.body) : $(element); - } - } - - return $(document.body); - } - - - function cumulativeOffset(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return new Element.Offset(valueL, valueT); - } - - function positionedOffset(element) { - var layout = element.getLayout(); - - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (isBody(element)) break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - - valueL -= layout.get('margin-top'); - valueT -= layout.get('margin-left'); - - return new Element.Offset(valueL, valueT); - } - - function cumulativeScrollOffset(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return new Element.Offset(valueL, valueT); - } - - function viewportOffset(forElement) { - var valueT = 0, valueL = 0, docBody = document.body; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == docBody && - Element.getStyle(element, 'position') == 'absolute') break; - } while (element = element.offsetParent); - - element = forElement; - do { - if (element != docBody) { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - return new Element.Offset(valueL, valueT); - } - - function absolutize(element) { - element = $(element); - - if (Element.getStyle(element, 'position') === 'absolute') { - return element; - } - - var offsetParent = getOffsetParent(element); - var eOffset = element.viewportOffset(), - pOffset = offsetParent.viewportOffset(); - - var offset = eOffset.relativeTo(pOffset); - var layout = element.getLayout(); - - element.store('prototype_absolutize_original_styles', { - left: element.getStyle('left'), - top: element.getStyle('top'), - width: element.getStyle('width'), - height: element.getStyle('height') - }); - - element.setStyle({ - position: 'absolute', - top: offset.top + 'px', - left: offset.left + 'px', - width: layout.get('width') + 'px', - height: layout.get('height') + 'px' - }); - - return element; - } - - function relativize(element) { - element = $(element); - if (Element.getStyle(element, 'position') === 'relative') { - return element; - } - - var originalStyles = - element.retrieve('prototype_absolutize_original_styles'); - - if (originalStyles) element.setStyle(originalStyles); - return element; - } - - Element.addMethods({ - getLayout: getLayout, - measure: measure, - getDimensions: getDimensions, - getOffsetParent: getOffsetParent, - cumulativeOffset: cumulativeOffset, - positionedOffset: positionedOffset, - cumulativeScrollOffset: cumulativeScrollOffset, - viewportOffset: viewportOffset, - absolutize: absolutize, - relativize: relativize - }); - - function isBody(element) { - return element.nodeName.toUpperCase() === 'BODY'; - } - - function isDetached(element) { - return element !== document.body && - !Element.descendantOf(element, document.body); - } - - if ('getBoundingClientRect' in document.documentElement) { - Element.addMethods({ - viewportOffset: function(element) { - element = $(element); - if (isDetached(element)) return new Element.Offset(0, 0); - - var rect = element.getBoundingClientRect(), - docEl = document.documentElement; - return new Element.Offset(rect.left - docEl.clientLeft, - rect.top - docEl.clientTop); - }, - - positionedOffset: function(element) { - element = $(element); - var parent = element.getOffsetParent(); - if (isDetached(element)) return new Element.Offset(0, 0); - - if (element.offsetParent && - element.offsetParent.nodeName.toUpperCase() === 'HTML') { - return positionedOffset(element); - } - - var eOffset = element.viewportOffset(), - pOffset = isBody(parent) ? viewportOffset(parent) : - parent.viewportOffset(); - var retOffset = eOffset.relativeTo(pOffset); - - var layout = element.getLayout(); - var top = retOffset.top - layout.get('margin-top'); - var left = retOffset.left - layout.get('margin-left'); - - return new Element.Offset(left, top); - } - }); - } -})(); -window.$$ = function() { - var expression = $A(arguments).join(', '); - return Prototype.Selector.select(expression, document); -}; - -Prototype.Selector = (function() { - - function select() { - throw new Error('Method "Prototype.Selector.select" must be defined.'); - } - - function match() { - throw new Error('Method "Prototype.Selector.match" must be defined.'); - } - - function find(elements, expression, index) { - index = index || 0; - var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i; - - for (i = 0; i < length; i++) { - if (match(elements[i], expression) && index == matchIndex++) { - return Element.extend(elements[i]); - } - } - } - - function extendElements(elements) { - for (var i = 0, length = elements.length; i < length; i++) { - Element.extend(elements[i]); - } - return elements; - } - - - var K = Prototype.K; - - return { - select: select, - match: match, - find: find, - extendElements: (Element.extend === K) ? K : extendElements, - extendElement: Element.extend - }; -})(); -Prototype._original_property = window.Sizzle; -/*! - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true; - -[0, 0].sort(function(){ - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function(selector, context, results, seed) { - results = results || []; - var origContext = context = context || document; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context), - soFar = selector; - - while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) - selector += parts.shift(); - - set = posProcess( selector, set ); - } - } - } else { - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - var ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; - } - - if ( context ) { - var ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray(set); - } else { - prune = false; - } - - while ( parts.length ) { - var cur = parts.pop(), pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - throw "Syntax error, unrecognized expression: " + (cur || selector); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - } else if ( context && context.nodeType === 1 ) { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - } else { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function(results){ - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); - } - } - } - } - - return results; -}; - -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); -}; - -Sizzle.find = function(expr, context, isXML){ - var set, match; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice(1,1); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); - set = Expr.find[ type ]( match, context, isXML ); - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = context.getElementsByTagName("*"); - } - - return {set: set, expr: expr}; -}; - -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && isXML(set[0]); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.match[ type ].exec( expr )) != null ) { - var filter = Expr.filter[ type ], found, item; - anyFound = false; - - if ( curLoop == result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - } else { - curLoop[i] = false; - } - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - if ( expr == old ) { - if ( anyFound == null ) { - throw "Syntax error, unrecognized expression: " + expr; - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - match: { - ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ - }, - leftMatch: {}, - attrMap: { - "class": "className", - "for": "htmlFor" - }, - attrHandle: { - href: function(elem){ - return elem.getAttribute("href"); - } - }, - relative: { - "+": function(checkSet, part, isXML){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag && !isXML ) { - part = part.toUpperCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - ">": function(checkSet, part, isXML){ - var isPartStr = typeof part === "string"; - - if ( isPartStr && !/\W/.test(part) ) { - part = isXML ? part : part.toUpperCase(); - - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName === part ? parent : false; - } - } - } else { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( !/\W/.test(part) ) { - var nodeCheck = part = isXML ? part : part.toUpperCase(); - checkFn = dirNodeCheck; - } - - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); - }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = isXML ? part : part.toUpperCase(); - checkFn = dirNodeCheck; - } - - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); - } - }, - find: { - ID: function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? [m] : []; - } - }, - NAME: function(match, context, isXML){ - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); - } - }, - preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) { - if ( !inplace ) - result.push( elem ); - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - ID: function(match){ - return match[1].replace(/\\/g, ""); - }, - TAG: function(match, curLoop){ - for ( var i = 0; curLoop[i] === false; i++ ){} - return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase(); - }, - CHILD: function(match){ - if ( match[1] == "nth" ) { - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - - match[0] = done++; - - return match; - }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - PSEUDO: function(match, curLoop, inplace, result, not){ - if ( match[1] === "not" ) { - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - if ( !inplace ) { - result.push.apply( result, ret ); - } - return false; - } - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - POS: function(match){ - match.unshift( true ); - return match; - } - }, - filters: { - enabled: function(elem){ - return elem.disabled === false && elem.type !== "hidden"; - }, - disabled: function(elem){ - return elem.disabled === true; - }, - checked: function(elem){ - return elem.checked === true; - }, - selected: function(elem){ - elem.parentNode.selectedIndex; - return elem.selected === true; - }, - parent: function(elem){ - return !!elem.firstChild; - }, - empty: function(elem){ - return !elem.firstChild; - }, - has: function(elem, i, match){ - return !!Sizzle( match[3], elem ).length; - }, - header: function(elem){ - return /h\d/i.test( elem.nodeName ); - }, - text: function(elem){ - return "text" === elem.type; - }, - radio: function(elem){ - return "radio" === elem.type; - }, - checkbox: function(elem){ - return "checkbox" === elem.type; - }, - file: function(elem){ - return "file" === elem.type; - }, - password: function(elem){ - return "password" === elem.type; - }, - submit: function(elem){ - return "submit" === elem.type; - }, - image: function(elem){ - return "image" === elem.type; - }, - reset: function(elem){ - return "reset" === elem.type; - }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; - }, - input: function(elem){ - return /input|select|textarea|button/i.test(elem.nodeName); - } - }, - setFilters: { - first: function(elem, i){ - return i === 0; - }, - last: function(elem, i, match, array){ - return i === array.length - 1; - }, - even: function(elem, i){ - return i % 2 === 0; - }, - odd: function(elem, i){ - return i % 2 === 1; - }, - lt: function(elem, i, match){ - return i < match[3] - 0; - }, - gt: function(elem, i, match){ - return i > match[3] - 0; - }, - nth: function(elem, i, match){ - return match[3] - 0 == i; - }, - eq: function(elem, i, match){ - return match[3] - 0 == i; - } - }, - filter: { - PSEUDO: function(elem, match, i, array){ - var name = match[1], filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; - } else if ( name === "not" ) { - var not = match[3]; - - for ( var i = 0, l = not.length; i < l; i++ ) { - if ( not[i] === elem ) { - return false; - } - } - - return true; - } - }, - CHILD: function(elem, match){ - var type = match[1], node = elem; - switch (type) { - case 'only': - case 'first': - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) return false; - } - if ( type == 'first') return true; - node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) return false; - } - return true; - case 'nth': - var first = match[2], last = match[3]; - - if ( first == 1 && last == 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - if ( first == 0 ) { - return diff == 0; - } else { - return ( diff % first == 0 && diff / first >= 0 ); - } - } - }, - ID: function(elem, match){ - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - TAG: function(elem, match){ - return (match === "*" && elem.nodeType === 1) || elem.nodeName === match; - }, - CLASS: function(elem, match){ - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - ATTR: function(elem, match){ - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value != check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source ); -} - -var makeArray = function(array, results) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 ); - -} catch(e){ - makeArray = function(array, results) { - var ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - } else { - if ( typeof array.length === "number" ) { - for ( var i = 0, l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - } else { - for ( var i = 0; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - - var ret = a.sourceIndex - b.sourceIndex; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( document.createRange ) { - sortOrder = function( a, b ) { - if ( !a.ownerDocument || !b.ownerDocument ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - - var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); - aRange.setStart(a, 0); - aRange.setEnd(a, 0); - bRange.setStart(b, 0); - bRange.setEnd(b, 0); - var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} - -(function(){ - var form = document.createElement("div"), - id = "script" + (new Date).getTime(); - form.innerHTML = ""; - - var root = document.documentElement; - root.insertBefore( form, root.firstChild ); - - if ( !!document.getElementById( id ) ) { - Expr.find.ID = function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; - } - }; - - Expr.filter.ID = function(elem, match){ - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - root = form = null; // release memory in IE -})(); - -(function(){ - - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); - - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - div.innerHTML = ""; - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - Expr.attrHandle.href = function(elem){ - return elem.getAttribute("href", 2); - }; - } - - div = null; // release memory in IE -})(); - -if ( document.querySelectorAll ) (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "

    "; - - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function(query, context, extra, seed){ - context = context || document; - - if ( !seed && context.nodeType === 9 && !isXML(context) ) { - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(e){} - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - div = null; // release memory in IE -})(); - -if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ - var div = document.createElement("div"); - div.innerHTML = "
    "; - - if ( div.getElementsByClassName("e").length === 0 ) - return; - - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) - return; - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - div = null; // release memory in IE -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - var sibDir = dir == "previousSibling" && !isXML; - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - if ( sibDir && elem.nodeType === 1 ){ - elem.sizcache = doneName; - elem.sizset = i; - } - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - var sibDir = dir == "previousSibling" && !isXML; - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - if ( sibDir && elem.nodeType === 1 ) { - elem.sizcache = doneName; - elem.sizset = i; - } - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -var contains = document.compareDocumentPosition ? function(a, b){ - return a.compareDocumentPosition(b) & 16; -} : function(a, b){ - return a !== b && (a.contains ? a.contains(b) : true); -}; - -var isXML = function(elem){ - return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || - !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; -}; - -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, - root = context.nodeType ? [context] : context; - - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - - -window.Sizzle = Sizzle; - -})(); - -;(function(engine) { - var extendElements = Prototype.Selector.extendElements; - - function select(selector, scope) { - return extendElements(engine(selector, scope || document)); - } - - function match(element, selector) { - return engine.matches(selector, [element]).length == 1; - } - - Prototype.Selector.engine = engine; - Prototype.Selector.select = select; - Prototype.Selector.match = match; -})(Sizzle); - -window.Sizzle = Prototype._original_property; -delete Prototype._original_property; - -var Form = { - reset: function(form) { - form = $(form); - form.reset(); - return form; - }, - - 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 = elements.inject({ }, function(result, element) { - if (!element.disabled && element.name) { - 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) { - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key].push(value); - } - else result[key] = value; - } - } - return result; - }); - - return options.hash ? data : Object.toQueryString(data); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - getElements: function(form) { - var elements = $(form).getElementsByTagName('*'), - element, - arr = [ ], - serializers = Form.Element.Serializers; - for (var i = 0; element = elements[i]; i++) { - arr.push(element); - } - return arr.inject([], function(elements, child) { - if (serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - }) - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - 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)$/i.test(element.tagName); - }); - }, - - 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 = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - 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); - } -}; - -/*--------------------------------------------------------------------------*/ - - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - 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; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !(/^(?:button|reset|submit)$/i.test(element.type)))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; - -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = { - input: function(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element, value); - default: - return Form.Element.Serializers.textarea(element, value); - } - }, - - inputSelector: function(element, value) { - if (Object.isUndefined(value)) return element.checked ? element.value : null; - else element.checked = !!value; - }, - - textarea: function(element, value) { - if (Object.isUndefined(value)) return element.value; - else element.value = value; - }, - - 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) { - var index = element.selectedIndex; - return index >= 0 ? this.optionValue(element.options[index]) : null; - }, - - selectMany: function(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(this.optionValue(opt)); - } - return values; - }, - - optionValue: function(opt) { - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; - } -}; - -/*--------------------------------------------------------------------------*/ - - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - 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(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -(function() { - - var Event = { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: {} - }; - - var docEl = document.documentElement; - var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl - && 'onmouseleave' in docEl; - - var _isButton; - if (Prototype.Browser.IE) { - var buttonMap = { 0: 1, 1: 4, 2: 2 }; - _isButton = function(event, code) { - return event.button === buttonMap[code]; - }; - } 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); - }; - } - - function isLeftClick(event) { return _isButton(event, 0) } - - function isMiddleClick(event) { return _isButton(event, 1) } - - function isRightClick(event) { return _isButton(event, 2) } - - function element(event) { - event = Event.extend(event); - - var node = event.target, type = event.type, - currentTarget = event.currentTarget; - - if (currentTarget && currentTarget.tagName) { - 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); - } - - function findElement(event, expression) { - var element = Event.element(event); - if (!expression) return element; - while (element) { - if (Object.isElement(element) && Prototype.Selector.match(element, expression)) { - return Element.extend(element); - } - element = element.parentNode; - } - } - - function pointer(event) { - return { x: pointerX(event), y: pointerY(event) }; - } - - function pointerX(event) { - var docElement = document.documentElement, - body = document.body || { scrollLeft: 0 }; - - return event.pageX || (event.clientX + - (docElement.scrollLeft || body.scrollLeft) - - (docElement.clientLeft || 0)); - } - - function pointerY(event) { - var docElement = document.documentElement, - body = document.body || { scrollTop: 0 }; - - return event.pageY || (event.clientY + - (docElement.scrollTop || body.scrollTop) - - (docElement.clientTop || 0)); - } - - - function stop(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - - event.stopped = true; - } - - Event.Methods = { - isLeftClick: isLeftClick, - isMiddleClick: isMiddleClick, - isRightClick: isRightClick, - - element: element, - findElement: findElement, - - pointer: pointer, - pointerX: pointerX, - pointerY: pointerY, - - stop: stop - }; - - - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (Prototype.Browser.IE) { - function _relatedTarget(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); - } - - Object.extend(methods, { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return '[object Event]' } - }); - - Event.extend = function(event, element) { - if (!event) return false; - if (event._extendedByPrototype) return event; - - event._extendedByPrototype = Prototype.emptyFunction; - var pointer = Event.pointer(event); - - Object.extend(event, { - target: event.srcElement || element, - relatedTarget: _relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - - return Object.extend(event, methods); - }; - } else { - Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; - Object.extend(Event.prototype, methods); - Event.extend = Prototype.K; - } - - function _createResponder(element, eventName, handler) { - var registry = Element.retrieve(element, 'prototype_event_registry'); - - if (Object.isUndefined(registry)) { - CACHE.push(element); - registry = Element.retrieve(element, 'prototype_event_registry', $H()); - } - - var respondersForEvent = registry.get(eventName); - if (Object.isUndefined(respondersForEvent)) { - respondersForEvent = []; - registry.set(eventName, respondersForEvent); - } - - if (respondersForEvent.pluck('handler').include(handler)) return false; - - var responder; - if (eventName.include(":")) { - responder = function(event) { - if (Object.isUndefined(event.eventName)) - return false; - - if (event.eventName !== eventName) - return false; - - Event.extend(event, element); - handler.call(element, event); - }; - } else { - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && - (eventName === "mouseenter" || eventName === "mouseleave")) { - if (eventName === "mouseenter" || eventName === "mouseleave") { - responder = function(event) { - Event.extend(event, element); - - var parent = event.relatedTarget; - while (parent && parent !== element) { - try { parent = parent.parentNode; } - catch(e) { parent = element; } - } - - if (parent === element) return; - - handler.call(element, event); - }; - } - } else { - responder = function(event) { - Event.extend(event, element); - handler.call(element, event); - }; - } - } - - responder.handler = handler; - respondersForEvent.push(responder); - return responder; - } - - function _destroyCache() { - for (var i = 0, length = CACHE.length; i < length; i++) { - Event.stopObserving(CACHE[i]); - CACHE[i] = null; - } - } - - var CACHE = []; - - if (Prototype.Browser.IE) - window.attachEvent('onunload', _destroyCache); - - if (Prototype.Browser.WebKit) - window.addEventListener('unload', Prototype.emptyFunction, false); - - - var _getDOMEventName = Prototype.K, - translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; - - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { - _getDOMEventName = function(eventName) { - return (translations[eventName] || eventName); - }; - } - - function observe(element, eventName, handler) { - element = $(element); - - var responder = _createResponder(element, eventName, handler); - - if (!responder) return element; - - if (eventName.include(':')) { - if (element.addEventListener) - element.addEventListener("dataavailable", responder, false); - else { - element.attachEvent("ondataavailable", responder); - element.attachEvent("onfilterchange", responder); - } - } else { - var actualEventName = _getDOMEventName(eventName); - - if (element.addEventListener) - element.addEventListener(actualEventName, responder, false); - else - element.attachEvent("on" + actualEventName, responder); - } - - return element; - } - - function stopObserving(element, eventName, handler) { - element = $(element); - - var registry = Element.retrieve(element, 'prototype_event_registry'); - if (!registry) return element; - - if (!eventName) { - registry.each( function(pair) { - var eventName = pair.key; - stopObserving(element, eventName); - }); - return element; - } - - var responders = registry.get(eventName); - if (!responders) return element; - - if (!handler) { - responders.each(function(r) { - stopObserving(element, eventName, r.handler); - }); - return element; - } - - var responder = responders.find( function(r) { return r.handler === handler; }); - if (!responder) return element; - - if (eventName.include(':')) { - if (element.removeEventListener) - element.removeEventListener("dataavailable", responder, false); - else { - element.detachEvent("ondataavailable", responder); - element.detachEvent("onfilterchange", responder); - } - } else { - var actualEventName = _getDOMEventName(eventName); - if (element.removeEventListener) - element.removeEventListener(actualEventName, responder, false); - else - element.detachEvent('on' + actualEventName, responder); - } - - registry.set(eventName, responders.without(responder)); - - return element; - } - - function fire(element, eventName, memo, bubble) { - element = $(element); - - if (Object.isUndefined(bubble)) - bubble = true; - - 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 = bubble ? 'ondataavailable' : 'onfilterchange'; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) - element.dispatchEvent(event); - else - element.fireEvent(event.eventType, event); - - return Event.extend(event); - } - - Event.Handler = Class.create({ - initialize: function(element, eventName, selector, callback) { - this.element = $(element); - this.eventName = eventName; - this.selector = selector; - this.callback = callback; - this.handler = this.handleEvent.bind(this); - }, - - start: function() { - Event.observe(this.element, this.eventName, this.handler); - return this; - }, - - stop: function() { - Event.stopObserving(this.element, this.eventName, this.handler); - return this; - }, - - handleEvent: function(event) { - var element = event.findElement(this.selector); - if (element) this.callback.call(this.element, event, element); - } - }); - - function on(element, eventName, selector, callback) { - element = $(element); - if (Object.isFunction(selector) && Object.isUndefined(callback)) { - callback = selector, selector = null; - } - - return new Event.Handler(element, eventName, selector, callback).start(); - } - - Object.extend(Event, Event.Methods); - - Object.extend(Event, { - fire: fire, - observe: observe, - stopObserving: stopObserving, - on: on - }); - - Element.addMethods({ - fire: fire, - - observe: observe, - - stopObserving: stopObserving, - - on: on - }); - - Object.extend(document, { - fire: fire.methodize(), - - observe: observe.methodize(), - - stopObserving: stopObserving.methodize(), - - on: on.methodize(), - - loaded: false - }); - - if (window.Event) Object.extend(window.Event, Event); - else window.Event = Event; -})(); - -(function() { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ - - var timer; - - function fireContentLoadedEvent() { - if (document.loaded) return; - if (timer) window.clearTimeout(timer); - document.loaded = true; - document.fire('dom:loaded'); - } - - function checkReadyState() { - if (document.readyState === 'complete') { - document.stopObserving('readystatechange', checkReadyState); - fireContentLoadedEvent(); - } - } - - function pollDoScroll() { - try { document.documentElement.doScroll('left'); } - catch(e) { - timer = pollDoScroll.defer(); - return; - } - fireContentLoadedEvent(); - } - - if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); - } else { - document.observe('readystatechange', checkReadyState); - if (window == top) - timer = pollDoScroll.defer(); - } - - Event.observe(window, 'load', fireContentLoadedEvent); -})(); - -Element.addMethods(); - -/*------------------------------- DEPRECATED -------------------------------*/ - -Hash.toQueryString = Object.toQueryString; - -var Toggle = { display: Element.toggle }; - -Element.Methods.childOf = Element.Methods.descendantOf; - -var Insertion = { - Before: function(element, content) { - return Element.insert(element, {before:content}); - }, - - Top: function(element, content) { - return Element.insert(element, {top:content}); - }, - - Bottom: function(element, content) { - return Element.insert(element, {bottom:content}); - }, - - After: function(element, content) { - return Element.insert(element, {after:content}); - } -}; - -var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); - -var Position = { - includeScrollOffsets: false, - - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = Element.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = Element.cumulativeScrollOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = Element.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - - cumulativeOffset: Element.Methods.cumulativeOffset, - - positionedOffset: Element.Methods.positionedOffset, - - absolutize: function(element) { - Position.prepare(); - return Element.absolutize(element); - }, - - relativize: function(element) { - Position.prepare(); - return Element.relativize(element); - }, - - realOffset: Element.Methods.cumulativeScrollOffset, - - offsetParent: Element.Methods.getOffsetParent, - - page: Element.Methods.viewportOffset, - - 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; - }; - - return function(className, parentElement) { - return $(parentElement || document.body).getElementsByClassName(className); - }; -}(Element.Methods); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set($A(this).concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set($A(this).without(classNameToRemove).join(' ')); - }, - - toString: function() { - return $A(this).join(' '); - } -}; - -Object.extend(Element.ClassNames.prototype, Enumerable); - -/*--------------------------------------------------------------------------*/ - -(function() { - window.Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - }, - - findElements: function(rootElement) { - return Prototype.Selector.select(this.expression, rootElement); - }, - - match: function(element) { - return Prototype.Selector.match(element, this.expression); - }, - - toString: function() { - return this.expression; - }, - - inspect: function() { - return "#"; - } - }); - - Object.extend(Selector, { - matchElements: function(elements, expression) { - var match = Prototype.Selector.match, - results = []; - - for (var i = 0, length = elements.length; i < length; i++) { - var element = elements[i]; - if (match(element, expression)) { - results.push(Element.extend(element)); - } - } - return results; - }, - - findElement: function(elements, expression, index) { - index = index || 0; - var matchIndex = 0, element; - for (var i = 0, length = elements.length; i < length; i++) { - element = elements[i]; - if (Prototype.Selector.match(element, expression) && index === matchIndex++) { - return Element.extend(element); - } - } - }, - - findChildElements: function(element, expressions) { - var selector = expressions.toArray().join(', '); - return Prototype.Selector.select(selector, element || document); - } - }); -})(); diff --git a/vendor/impressionist/test_app/public/javascripts/rails.js b/vendor/impressionist/test_app/public/javascripts/rails.js deleted file mode 100644 index 4283ed89..00000000 --- a/vendor/impressionist/test_app/public/javascripts/rails.js +++ /dev/null @@ -1,175 +0,0 @@ -(function() { - // Technique from Juriy Zaytsev - // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - function isEventSupported(eventName) { - var el = document.createElement('div'); - eventName = 'on' + eventName; - var isSupported = (eventName in el); - if (!isSupported) { - el.setAttribute(eventName, 'return;'); - isSupported = typeof el[eventName] == 'function'; - } - el = null; - return isSupported; - } - - function isForm(element) { - return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM' - } - - function isInput(element) { - if (Object.isElement(element)) { - var name = element.nodeName.toUpperCase() - return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA' - } - else return false - } - - var submitBubbles = isEventSupported('submit'), - changeBubbles = isEventSupported('change') - - if (!submitBubbles || !changeBubbles) { - // augment the Event.Handler class to observe custom events when needed - Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap( - function(init, element, eventName, selector, callback) { - init(element, eventName, selector, callback) - // is the handler being attached to an element that doesn't support this event? - if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) || - (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) { - // "submit" => "emulated:submit" - this.eventName = 'emulated:' + this.eventName - } - } - ) - } - - if (!submitBubbles) { - // discover forms on the page by observing focus events which always bubble - document.on('focusin', 'form', function(focusEvent, form) { - // special handler for the real "submit" event (one-time operation) - if (!form.retrieve('emulated:submit')) { - form.on('submit', function(submitEvent) { - var emulated = form.fire('emulated:submit', submitEvent, true) - // if custom event received preventDefault, cancel the real one too - if (emulated.returnValue === false) submitEvent.preventDefault() - }) - form.store('emulated:submit', true) - } - }) - } - - if (!changeBubbles) { - // discover form inputs on the page - document.on('focusin', 'input, select, texarea', function(focusEvent, input) { - // special handler for real "change" events - if (!input.retrieve('emulated:change')) { - input.on('change', function(changeEvent) { - input.fire('emulated:change', changeEvent, true) - }) - input.store('emulated:change', true) - } - }) - } - - function handleRemote(element) { - var method, url, params; - - var event = element.fire("ajax:before"); - if (event.stopped) return false; - - if (element.tagName.toLowerCase() === 'form') { - method = element.readAttribute('method') || 'post'; - url = element.readAttribute('action'); - params = element.serialize(); - } else { - method = element.readAttribute('data-method') || 'get'; - url = element.readAttribute('href'); - params = {}; - } - - new Ajax.Request(url, { - method: method, - parameters: params, - evalScripts: true, - - onComplete: function(request) { element.fire("ajax:complete", request); }, - onSuccess: function(request) { element.fire("ajax:success", request); }, - onFailure: function(request) { element.fire("ajax:failure", request); } - }); - - element.fire("ajax:after"); - } - - function handleMethod(element) { - var method = element.readAttribute('data-method'), - url = element.readAttribute('href'), - csrf_param = $$('meta[name=csrf-param]')[0], - csrf_token = $$('meta[name=csrf-token]')[0]; - - var form = new Element('form', { method: "POST", action: url, style: "display: none;" }); - element.parentNode.insert(form); - - if (method !== 'post') { - var field = new Element('input', { type: 'hidden', name: '_method', value: method }); - form.insert(field); - } - - if (csrf_param) { - var param = csrf_param.readAttribute('content'), - token = csrf_token.readAttribute('content'), - field = new Element('input', { type: 'hidden', name: param, value: token }); - form.insert(field); - } - - form.submit(); - } - - - document.on("click", "*[data-confirm]", function(event, element) { - var message = element.readAttribute('data-confirm'); - if (!confirm(message)) event.stop(); - }); - - document.on("click", "a[data-remote]", function(event, element) { - if (event.stopped) return; - handleRemote(element); - event.stop(); - }); - - document.on("click", "a[data-method]", function(event, element) { - if (event.stopped) return; - handleMethod(element); - event.stop(); - }); - - document.on("submit", function(event) { - var element = event.findElement(), - message = element.readAttribute('data-confirm'); - if (message && !confirm(message)) { - event.stop(); - return false; - } - - var inputs = element.select("input[type=submit][data-disable-with]"); - inputs.each(function(input) { - input.disabled = true; - input.writeAttribute('data-original-value', input.value); - input.value = input.readAttribute('data-disable-with'); - }); - - var element = event.findElement("form[data-remote]"); - if (element) { - handleRemote(element); - event.stop(); - } - }); - - document.on("ajax:after", "form", function(event, element) { - var inputs = element.select("input[type=submit][disabled=true][data-disable-with]"); - inputs.each(function(input) { - input.value = input.readAttribute('data-original-value'); - input.removeAttribute('data-original-value'); - input.disabled = false; - }); - }); -})(); diff --git a/vendor/impressionist/test_app/public/robots.txt b/vendor/impressionist/test_app/public/robots.txt deleted file mode 100644 index 085187fa..00000000 --- a/vendor/impressionist/test_app/public/robots.txt +++ /dev/null @@ -1,5 +0,0 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-Agent: * -# Disallow: / diff --git a/vendor/impressionist/test_app/public/stylesheets/.gitkeep b/vendor/impressionist/test_app/public/stylesheets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/impressionist/test_app/script/cucumber b/vendor/impressionist/test_app/script/cucumber deleted file mode 100755 index 7fa5c920..00000000 --- a/vendor/impressionist/test_app/script/cucumber +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env ruby - -vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first -if vendored_cucumber_bin - load File.expand_path(vendored_cucumber_bin) -else - require 'rubygems' unless ENV['NO_RUBYGEMS'] - require 'cucumber' - load Cucumber::BINARY -end diff --git a/vendor/impressionist/test_app/script/rails b/vendor/impressionist/test_app/script/rails deleted file mode 100755 index f8da2cff..00000000 --- a/vendor/impressionist/test_app/script/rails +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env ruby -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) -require 'rails/commands' diff --git a/vendor/impressionist/test_app/spec/controllers/controller_spec.rb b/vendor/impressionist/test_app/spec/controllers/controller_spec.rb deleted file mode 100644 index a48b3a06..00000000 --- a/vendor/impressionist/test_app/spec/controllers/controller_spec.rb +++ /dev/null @@ -1,125 +0,0 @@ -require 'spec_helper' - -describe ArticlesController do - fixtures :articles,:impressions,:posts,:widgets - render_views - - it "should make the impressionable_hash available" do - get "index" - response.body.include?("false").should eq true - end - - it "should log an impression with a message" do - get "index" - Impression.all.size.should eq 12 - Article.first.impressions.last.message.should eq "this is a test article impression" - Article.first.impressions.last.controller_name.should eq "articles" - Article.first.impressions.last.action_name.should eq "index" - end - - it "should log an impression without a message" do - get "show", :id=> 1 - Impression.all.size.should eq 12 - Article.first.impressions.last.message.should eq nil - Article.first.impressions.last.controller_name.should eq "articles" - Article.first.impressions.last.action_name.should eq "show" - end - - it "should log the user_id if user is authenticated (@current_user before_filter method)" do - session[:user_id] = 123 - get "show", :id=> 1 - Article.first.impressions.last.user_id.should eq 123 - end - - it "should not log the user_id if user is authenticated" do - get "show", :id=> 1 - Article.first.impressions.last.user_id.should eq nil - end - - it "should log the request_hash, ip_address, referrer and session_hash" do - get "show", :id=> 1 - Impression.last.request_hash.size.should eq 64 - Impression.last.ip_address.should eq "0.0.0.0" - Impression.last.session_hash.size.should eq 32 - Impression.last.referrer.should eq nil - end - - it "should log the referrer when you click a link" do - visit article_url(Article.first) - click_link "Same Page" - Impression.last.referrer.should eq "http://test.host/articles/1" - end -end - -describe PostsController do - it "should log impression at the action level" do - get "show", :id=> 1 - Impression.all.size.should eq 12 - Impression.last.controller_name.should eq "posts" - Impression.last.action_name.should eq "show" - Impression.last.impressionable_type.should eq "Post" - Impression.last.impressionable_id.should eq 1 - end - - it "should log the user_id if user is authenticated (current_user helper method)" do - session[:user_id] = 123 - get "show", :id=> 1 - Post.first.impressions.last.user_id.should eq 123 - end -end - -describe WidgetsController do - - before(:each) do - @widget = Widget.find(1) - Widget.stub(:find).and_return(@widget) - end - - it "should log impression at the per action level" do - get "show", :id=> 1 - Impression.all.size.should eq 12 - get "index" - Impression.all.size.should eq 13 - get "new" - Impression.all.size.should eq 13 - end - - it "should not log impression when user-agent is in wildcard list" do - request.stub!(:user_agent).and_return('somebot') - get "show", :id=> 1 - Impression.all.size.should eq 11 - end - - it "should not log impression when user-agent is in the bot list" do - request.stub!(:user_agent).and_return('Acoon Robot v1.50.001') - get "show", :id=> 1 - Impression.all.size.should eq 11 - end - - describe "impressionist unique options" do - - it "should log unique impressions at the per action level" do - get "show", :id=> 1 - Impression.all.size.should eq 12 - get "show", :id=> 2 - Impression.all.size.should eq 13 - get "show", :id => 2 - Impression.all.size.should eq 13 - get "index" - Impression.all.size.should eq 14 - end - - it "should log unique impressions only once per id" do - get "show", :id=> 1 - Impression.all.size.should eq 12 - get "show", :id=> 2 - Impression.all.size.should eq 13 - get "show", :id => 2 - Impression.all.size.should eq 13 - get "index" - Impression.all.size.should eq 14 - end - - end - -end diff --git a/vendor/impressionist/test_app/spec/controllers/impressionist_uniqueness_spec.rb b/vendor/impressionist/test_app/spec/controllers/impressionist_uniqueness_spec.rb deleted file mode 100644 index f9c3fc3e..00000000 --- a/vendor/impressionist/test_app/spec/controllers/impressionist_uniqueness_spec.rb +++ /dev/null @@ -1,310 +0,0 @@ -require 'spec_helper' - -# we use the posts controller as it uses the impressionsist module. any such controller would do. -describe DummyController do - - before do - @impression_count = Impression.all.size - end - - describe "impressionist filter uniqueness" do - - it "should ignore uniqueness if not requested" do - controller.impressionist_subapp_filter(nil, nil) - controller.impressionist_subapp_filter(nil, nil) - Impression.should have(@impression_count + 2).records - end - - it "should recognize unique session" do - controller.stub!(:session_hash).and_return(request.session_options[:id]) - controller.impressionist_subapp_filter(nil, [:session_hash]) - controller.impressionist_subapp_filter(nil, [:session_hash]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique ip" do - controller.request.stub!(:remote_ip).and_return("1.2.3.4") - controller.impressionist_subapp_filter(nil, [:ip_address]) - controller.impressionist_subapp_filter(nil, [:ip_address]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique request" do - controller.impressionist_subapp_filter(nil, [:request_hash]) - controller.impressionist_subapp_filter(nil, [:request_hash]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique action" do - controller.stub!(:action_name).and_return("test_action") - controller.impressionist_subapp_filter(nil, [:action_name]) - controller.impressionist_subapp_filter(nil, [:action_name]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique controller" do - controller.stub!(:controller_name).and_return("post") - controller.impressionist_subapp_filter(nil, [:controller_name]) - controller.impressionist_subapp_filter(nil, [:controller_name]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique user" do - controller.stub!(:user_id).and_return(42) - controller.impressionist_subapp_filter(nil, [:user_id]) - controller.impressionist_subapp_filter(nil, [:user_id]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique referer" do - controller.request.stub!(:referer).and_return("http://foo/bar") - controller.impressionist_subapp_filter(nil, [:referrer]) - controller.impressionist_subapp_filter(nil, [:referrer]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique id" do - controller.stub!(:params).and_return({:id => "666"}) # for correct impressionable id in filter - controller.impressionist_subapp_filter(nil, [:impressionable_id]) - controller.impressionist_subapp_filter(nil, [:impressionable_id]) - Impression.should have(@impression_count + 1).records - end - - # extra redundant test for important controller and action combination. - it "should recognize different controller and action" do - controller.stub!(:controller_name).and_return("post") - controller.stub!(:action_name).and_return("test_action") - controller.impressionist_subapp_filter(nil, [:controller_name, :action_name]) - controller.impressionist_subapp_filter(nil, [:controller_name, :action_name]) - Impression.should have(@impression_count + 1).records - controller.stub!(:action_name).and_return("another_action") - controller.impressionist_subapp_filter(nil, [:controller_name, :action_name]) - controller.impressionist_subapp_filter(nil, [:controller_name, :action_name]) - Impression.should have(@impression_count + 2).records - controller.stub!(:controller_name).and_return("article") - controller.impressionist_subapp_filter(nil, [:controller_name, :action_name]) - controller.impressionist_subapp_filter(nil, [:controller_name, :action_name]) - Impression.should have(@impression_count + 3).records - end - - it "should recognize different action" do - controller.stub!(:action_name).and_return("test_action") - controller.impressionist_subapp_filter(nil, [:action_name]) - controller.impressionist_subapp_filter(nil, [:action_name]) - Impression.should have(@impression_count + 1).records - controller.stub!(:action_name).and_return("another_action") - controller.impressionist_subapp_filter(nil, [:action_name]) - controller.impressionist_subapp_filter(nil, [:action_name]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different controller" do - controller.stub!(:controller_name).and_return("post") - controller.impressionist_subapp_filter(nil, [:controller_name]) - controller.impressionist_subapp_filter(nil, [:controller_name]) - Impression.should have(@impression_count + 1).records - controller.stub!(:controller_name).and_return("article") - controller.impressionist_subapp_filter(nil, [:controller_name]) - controller.impressionist_subapp_filter(nil, [:controller_name]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different session" do - controller.stub!(:session_hash).and_return("foo") - controller.impressionist_subapp_filter(nil, [:session_hash]) - controller.impressionist_subapp_filter(nil, [:session_hash]) - Impression.should have(@impression_count + 1).records - controller.stub!(:session_hash).and_return("bar") - controller.impressionist_subapp_filter(nil, [:session_hash]) - controller.impressionist_subapp_filter(nil, [:session_hash]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different ip" do - controller.request.stub!(:remote_ip).and_return("1.2.3.4") - controller.impressionist_subapp_filter(nil, [:ip_address]) - controller.impressionist_subapp_filter(nil, [:ip_address]) - Impression.should have(@impression_count + 1).records - controller.request.stub!(:remote_ip).and_return("5.6.7.8") - controller.impressionist_subapp_filter(nil, [:ip_address]) - controller.impressionist_subapp_filter(nil, [:ip_address]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different referer" do - controller.request.stub!(:referer).and_return("http://foo/bar") - controller.impressionist_subapp_filter(nil, [:referrer]) - controller.impressionist_subapp_filter(nil, [:referrer]) - Impression.should have(@impression_count + 1).records - controller.request.stub!(:referer).and_return("http://bar/fo") - controller.impressionist_subapp_filter(nil, [:referrer]) - controller.impressionist_subapp_filter(nil, [:referrer]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different id" do - controller.stub!(:params).and_return({:id => "666"}) # for correct impressionable id in filter - controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id]) - controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id]) - controller.stub!(:params).and_return({:id => "42"}) # for correct impressionable id in filter - controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id]) - controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize combined uniqueness" do - controller.stub!(:action_name).and_return("test_action") - controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash, :action_name]) - controller.impressionist_subapp_filter(nil, [:request_hash, :ip_address, :action_name]) - controller.impressionist_subapp_filter(nil, [:request_hash, :action_name]) - controller.impressionist_subapp_filter(nil, [:ip_address, :action_name]) - controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash]) - controller.impressionist_subapp_filter(nil, [:action_name]) - controller.impressionist_subapp_filter(nil, [:ip_address]) - controller.impressionist_subapp_filter(nil, [:request_hash]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize combined non-uniqueness" do - controller.stub!(:action_name).and_return(nil) - controller.impressionist_subapp_filter(nil, [:ip_address, :action_name]) - controller.stub!(:action_name).and_return("test_action") - controller.impressionist_subapp_filter(nil, [:ip_address, :action_name]) - controller.stub!(:action_name).and_return("another_action") - controller.impressionist_subapp_filter(nil, [:ip_address, :action_name]) - Impression.should have(@impression_count + 3).records - end - - end - - describe "impressionist method uniqueness for impressionables" do - - # in this test we reuse the post model. might break if model changes. - - it "should ignore uniqueness if not requested" do - impressionable = Post.create - controller.impressionist impressionable - controller.impressionist impressionable - Impression.should have(@impression_count + 2).records - end - - it "should recognize unique session" do - controller.stub!(:session_hash).and_return(request.session_options[:id]) - impressionable = Post.create - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique ip" do - controller.request.stub!(:remote_ip).and_return("1.2.3.4") - impressionable = Post.create - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique request" do - impressionable = Post.create - controller.impressionist(impressionable, nil, :unique => [:request_hash]) - controller.impressionist(impressionable, nil, :unique => [:request_hash]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique user" do - controller.stub!(:user_id).and_return(666) - impressionable = Post.create - controller.impressionist(impressionable, nil, :unique => [:user_id]) - controller.impressionist(impressionable, nil, :unique => [:user_id]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize unique referer" do - controller.request.stub!(:referer).and_return("http://foo/bar") - impressionable = Post.create - controller.impressionist(impressionable, nil, :unique => [:referrer]) - controller.impressionist(impressionable, nil, :unique => [:referrer]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize different session" do - impressionable = Post.create - controller.stub!(:session_hash).and_return("foo") - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - Impression.should have(@impression_count + 1).records - controller.stub!(:session_hash).and_return("bar") - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different ip" do - controller.request.stub!(:remote_ip).and_return("1.2.3.4") - impressionable = Post.create - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - Impression.should have(@impression_count + 1).records - controller.request.stub!(:remote_ip).and_return("5.6.7.8") - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize different user" do - impressionable = Post.create - controller.stub!(:user_id).and_return(666) - controller.impressionist(impressionable, nil, :unique => [:user_id]) - controller.impressionist(impressionable, nil, :unique => [:user_id]) - Impression.should have(@impression_count + 1).records - controller.stub!(:user_id).and_return(42) - controller.impressionist(impressionable, nil, :unique => [:user_id]) - controller.impressionist(impressionable, nil, :unique => [:user_id]) - Impression.should have(@impression_count + 2).records - end - - it "should recognize combined uniqueness" do - impressionable = Post.create - controller.stub!(:session_hash).and_return("foo") - controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash]) - controller.impressionist(impressionable, nil, :unique => [:request_hash, :ip_address, :session_hash]) - controller.impressionist(impressionable, nil, :unique => [:request_hash, :session_hash]) - controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash]) - controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash]) - controller.impressionist(impressionable, nil, :unique => [:session_hash]) - controller.impressionist(impressionable, nil, :unique => [:ip_address]) - controller.impressionist(impressionable, nil, :unique => [:request_hash]) - Impression.should have(@impression_count + 1).records - end - - it "should recognize combined non-uniqueness" do - impressionable = Post.create - controller.stub!(:session_hash).and_return(nil) - controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash]) - controller.stub!(:session_hash).and_return("foo") - controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash]) - controller.stub!(:session_hash).and_return("bar") - controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash]) - Impression.should have(@impression_count + 3).records - end - - end - - describe "impressionist filter and method uniqueness" do - - it "should recognize uniqueness" do - impressionable = Post.create - controller.stub!(:controller_name).and_return("posts") # for correct impressionable type in filter - controller.stub!(:params).and_return({:id => impressionable.id.to_s}) # for correct impressionable id in filter - controller.stub!(:session_hash).and_return("foo") - controller.request.stub!(:remote_ip).and_return("1.2.3.4") - # order of the following methods is important for the test! - controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash, :session_hash]) - controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash]) - Impression.should have(@impression_count + 1).records - end - - end - -end - diff --git a/vendor/impressionist/test_app/spec/fixtures/articles.yml b/vendor/impressionist/test_app/spec/fixtures/articles.yml deleted file mode 100644 index 0a0867df..00000000 --- a/vendor/impressionist/test_app/spec/fixtures/articles.yml +++ /dev/null @@ -1,3 +0,0 @@ -one: - id: 1 - name: Test Article diff --git a/vendor/impressionist/test_app/spec/fixtures/impressions.yml b/vendor/impressionist/test_app/spec/fixtures/impressions.yml deleted file mode 100644 index 7342af54..00000000 --- a/vendor/impressionist/test_app/spec/fixtures/impressions.yml +++ /dev/null @@ -1,43 +0,0 @@ -<% 1.upto(7) do |i| %> -impression<%= i %>: - impressionable_type: Article - impressionable_id: 1 - request_hash: a<%=i%> - session_hash: b<%=i%> - ip_address: 127.0.0.<%=i%> - created_at: 2011-01-01 -<% end %> - - -impression8: - impressionable_type: Article - impressionable_id: 1 - request_hash: a1 - session_hash: b1 - ip_address: 127.0.0.1 - created_at: 2010-01-01 - -impression9: - impressionable_type: Article - impressionable_id: 1 - request_hash: a1 - session_hash: b2 - ip_address: 127.0.0.1 - created_at: 2011-01-03 - -impression10: - impressionable_type: Article - impressionable_id: 1 - request_hash: a9 - session_hash: b3 - ip_address: 127.0.0.8 - created_at: 2010-01-01 - -impression11: - impressionable_type: Article - impressionable_id: 1 - request_hash: a10 - session_hash: b4 - ip_address: 127.0.0.1 - created_at: 2010-01-01 - diff --git a/vendor/impressionist/test_app/spec/fixtures/posts.yml b/vendor/impressionist/test_app/spec/fixtures/posts.yml deleted file mode 100644 index b85e6799..00000000 --- a/vendor/impressionist/test_app/spec/fixtures/posts.yml +++ /dev/null @@ -1,3 +0,0 @@ -one: - id: 1 - name: Test Post diff --git a/vendor/impressionist/test_app/spec/fixtures/widgets.yml b/vendor/impressionist/test_app/spec/fixtures/widgets.yml deleted file mode 100644 index 11962466..00000000 --- a/vendor/impressionist/test_app/spec/fixtures/widgets.yml +++ /dev/null @@ -1,4 +0,0 @@ -one: - id: 1 - name: A Widget - impressions_count: 0 diff --git a/vendor/impressionist/test_app/spec/initializers/initializers_spec.rb b/vendor/impressionist/test_app/spec/initializers/initializers_spec.rb deleted file mode 100644 index 879a82a4..00000000 --- a/vendor/impressionist/test_app/spec/initializers/initializers_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'spec_helper' - -describe Impressionist do - it "should be extended from ActiveRecord::Base" do - method = RUBY_VERSION.match("1.8") ? "is_impressionable" : :is_impressionable - ActiveRecord::Base.methods.include?(method).should be_true - end - - it "should include methods in ApplicationController" do - method = RUBY_VERSION.match("1.8") ? "impressionist" : :impressionist - ApplicationController.instance_methods.include?(method).should be_true - end - - it "should include the before_filter method in ApplicationController" do - filters = ApplicationController._process_action_callbacks.select { |c| c.kind == :before } - filters.collect{|filter|filter.filter}.include?(:impressionist_app_filter).should be_true - end -end diff --git a/vendor/impressionist/test_app/spec/models/bots_spec.rb b/vendor/impressionist/test_app/spec/models/bots_spec.rb deleted file mode 100644 index a2983587..00000000 --- a/vendor/impressionist/test_app/spec/models/bots_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe Impressionist::Bots do - - describe "self.bot?" do - it "is true if user_agent is matches wild card" do - Impressionist::Bots.bot?("google.com bot").should be_true - end - - it "is true if user_agent is on bot list" do - Impressionist::Bots.bot?("A-Online Search").should be_true - end - - it "is false if user_agent is blank" do - Impressionist::Bots.bot?("").should be_false - Impressionist::Bots.bot?(nil).should be_false - end - - it "is false if user_agent is safe" do - Impressionist::Bots.bot?('127.0.0.1').should be_false - end - - it "is false if user_agent not given" do - Impressionist::Bots.bot?.should be_false - end - end -end \ No newline at end of file diff --git a/vendor/impressionist/test_app/spec/models/model_spec.rb b/vendor/impressionist/test_app/spec/models/model_spec.rb deleted file mode 100644 index 54601662..00000000 --- a/vendor/impressionist/test_app/spec/models/model_spec.rb +++ /dev/null @@ -1,94 +0,0 @@ -require 'spec_helper' - -describe Impression do - fixtures :articles,:impressions,:posts - - before(:each) do - @article = Article.find(1) - end - - it "should save a blank impression for an Article that has 10 impressions" do - @article.impressions.create - @article.impressions.size.should eq 12 - end - - it "should save an impression with a message" do - @article.impressions.create(:message=>"test message") - @article.impressions.last.message.should eq "test message" - end - - it "should return the impression count for all with no date range specified" do - @article.impressionist_count(:filter=>:all).should eq 11 - end - - it "should return unique impression count with no date range specified" do - @article.impressionist_count.should eq 9 - end - - it "should return impression count with only start date specified" do - @article.impressionist_count(:start_date=>"2011-01-01",:filter=>:all).should eq 8 - end - - it "should return impression count with whole date range specified" do - @article.impressionist_count(:start_date=>"2011-01-01",:end_date=>"2011-01-02",:filter=>:all).should eq 7 - end - - it "should return unique impression count with only start date specified" do - @article.impressionist_count(:start_date=>"2011-01-01").should eq 7 - end - - it "should return unique impression count with date range specified" do - @article.impressionist_count(:start_date=>"2011-01-01",:end_date=>"2011-01-02").should eq 7 - end - - it "should return unique impression count using ip address (which in turn eliminates duplicate request_hashes)" do - @article.impressionist_count(:filter=>:ip_address).should eq 8 - end - - it "should return unique impression count using session_hash (which in turn eliminates duplicate request_hashes)" do - @article.impressionist_count(:filter=>:session_hash).should eq 7 - end - - # tests :dependent => :destroy - it "should delete impressions on deletion of impressionable" do - impressions_count = Impression.all.size - a = Article.create - i = a.impressions.create - a.destroy - a.destroyed?.should be_true - i.destroyed?.should be_true - end - - #OLD COUNT METHODS. DEPRECATE SOON - it "should return the impression count with no date range specified" do - @article.impression_count.should eq 11 - end - - it "should return unique impression count with no date range specified" do - @article.unique_impression_count.should eq 9 - end - - it "should return impression count with only start date specified" do - @article.impression_count("2011-01-01").should eq 8 - end - - it "should return impression count with whole date range specified" do - @article.impression_count("2011-01-01","2011-01-02").should eq 7 - end - - it "should return unique impression count with only start date specified" do - @article.unique_impression_count("2011-01-01").should eq 7 - end - - it "should return unique impression count with date range specified" do - @article.unique_impression_count("2011-01-01","2011-01-02").should eq 7 - end - - it "should return unique impression count using ip address (which in turn eliminates duplicate request_hashes)" do - @article.unique_impression_count_ip.should eq 8 - end - - it "should return unique impression count using session_hash (which in turn eliminates duplicate request_hashes)" do - @article.unique_impression_count_session.should eq 7 - end -end diff --git a/vendor/impressionist/test_app/spec/rails_generators/rails_generators_spec.rb b/vendor/impressionist/test_app/spec/rails_generators/rails_generators_spec.rb deleted file mode 100644 index 2b5ea938..00000000 --- a/vendor/impressionist/test_app/spec/rails_generators/rails_generators_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'spec_helper' -require 'systemu' - -# FIXME this test might break the others if run before them -# -describe Impressionist do - fixtures :articles,:impressions,:posts - it "should delete existing migration and generate the migration file" do - pending - migrations_dir = "#{Rails.root}/db/migrate" - impressions_migration = Dir.entries(migrations_dir).grep(/impressions/)[0] - File.delete("#{migrations_dir}/#{impressions_migration}") unless impressions_migration.blank? - generator_output = systemu("rails g impressionist")[1] - migration_name = generator_output.split("migrate/")[1].strip - Dir.entries(migrations_dir).include?(migration_name).should be_true - end - - it "should run the migration created in the previous spec" do - pending - migrate_output = systemu("rake db:migrate RAILS_ENV=test") - migrate_output[1].include?("CreateImpressionsTable: migrated").should be_true - end -end diff --git a/vendor/impressionist/test_app/spec/spec_helper.rb b/vendor/impressionist/test_app/spec/spec_helper.rb deleted file mode 100644 index 9cbe63b7..00000000 --- a/vendor/impressionist/test_app/spec/spec_helper.rb +++ /dev/null @@ -1,36 +0,0 @@ -ENV["RAILS_ENV"] ||= 'test' -unless ENV['CI'] - require 'simplecov' - SimpleCov.start 'rails' -end -require File.expand_path("../../config/environment", __FILE__) -require 'rspec/rails' - -# Requires supporting ruby files with custom matchers and macros, etc, -# in spec/support/ and its subdirectories. -Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} - -RSpec.configure do |config| - # == Mock Framework - # - # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: - # - # config.mock_with :mocha - # config.mock_with :flexmock - # config.mock_with :rr - config.mock_with :rspec - - # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" - - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = true - - # make the rails logger usable in the tests as logger.xxx "..." - def logger - Rails.logger - end - -end diff --git a/vendor/impressionist/upgrade_migrations/version_0_3_0.rb b/vendor/impressionist/upgrade_migrations/version_0_3_0.rb deleted file mode 100644 index 46681250..00000000 --- a/vendor/impressionist/upgrade_migrations/version_0_3_0.rb +++ /dev/null @@ -1,27 +0,0 @@ -class CreateImpressionsTable < ActiveRecord::Migration - def self.up - add_column :impressions, :session_hash, :string - remove_index :impressions, :name => :poly_index - remove_index :impressions, :name => :controlleraction_index - add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false - add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false - add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false - - end - - def self.down - remove_column :impressions, :session_hash - remove_index :impressions, :name => :poly_request_index - remove_index :impressions, :name => :poly_ip_index - remove_index :impressions, :name => :poly_session_index - remove_index :impressions, :name => :controlleraction_request_index - remove_index :impressions, :name => :controlleraction_ip_index - remove_index :impressions, :name => :controlleraction_session_index - remove_index :impressions, :user_id - add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash, :ip_address], :name => "poly_index", :unique => false - add_index :impressions, [:controller_name,:action_name,:request_hash,:ip_address], :name => "controlleraction_index", :unique => false - end -end diff --git a/vendor/impressionist/upgrade_migrations/version_0_4_0.rb b/vendor/impressionist/upgrade_migrations/version_0_4_0.rb deleted file mode 100644 index ebd7fac5..00000000 --- a/vendor/impressionist/upgrade_migrations/version_0_4_0.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Version04UpdateImpressionsTable < ActiveRecord::Migration - def self.up - add_column :impressions, :referrer, :string - end - - def self.down - remove_column :impressions, :referrer - end -end diff --git a/vendor/impressionist/upgrade_migrations/version_1_1_2.rb b/vendor/impressionist/upgrade_migrations/version_1_1_2.rb deleted file mode 100644 index a4ef8e9a..00000000 --- a/vendor/impressionist/upgrade_migrations/version_1_1_2.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Version04UpdateImpressionsTable < ActiveRecord::Migration - def self.up - add_index :impressions, [:impressionable_type, :message, :impressionable_id], :name => "impressionable_type_message_index", :unique => false - end - - def self.down - remove_index :impressions, :impressionable_type_message_index - end -end