diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5235fdc --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +config/database.yml +db/schema.rb +db/schema.sql +coverage/* +doc/* +log/*.log +log/*.out +log/*.pid +tmp/**/* +tmp/.* +tmp/profile* +uploads/* +vendor/**/**/doc/* +.DS_Store +.project +ssl/* +Icon? diff --git a/Capfile b/Capfile new file mode 100644 index 0000000..e04728e --- /dev/null +++ b/Capfile @@ -0,0 +1,4 @@ +load 'deploy' if respond_to?(:namespace) # cap2 differentiator +Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) } + +load 'config/deploy' # remove this line to skip loading any of the default tasks \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..3bb0e85 --- /dev/null +++ b/Rakefile @@ -0,0 +1,10 @@ +# 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.join(File.dirname(__FILE__), 'config', 'boot')) + +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +require 'tasks/rails' diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..6635a3f --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,10 @@ +# Filters added to this controller apply to all controllers in the application. +# Likewise, all the methods added will be available for all controllers. + +class ApplicationController < ActionController::Base + helper :all # include all helpers, all the time + protect_from_forgery # See ActionController::RequestForgeryProtection for details + + # Scrub sensitive parameters from your log + # filter_parameter_logging :password +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..b6c3ea7 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,22 @@ +# Methods added to this helper will be available to all templates in the application. +module ApplicationHelper + # print javascript for each item in array of files in head section + def javascript(*files) + content_for(:javascripts) { javascript_include_tag(*files) } + end + + # print stylesheet for each item in array of files in head section + def stylesheet(*files) + content_for(:stylesheets) { stylesheet_link_tag(*files) } + end + + def favicon + "" + end + + def flash_notices + [:notice, :error, :warning].collect do |type| + content_tag('div', flash[type], :class=>"message #{type}", :id => "flash_messages") if flash[type] + end + end +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..8bb04b1 --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,37 @@ + + + + + Title <%= yield(:title) %> + <%= favicon %> + + + + + <%= javascript_include_merged :base %> + <%= yield(:javascripts) %> + + <%= stylesheet_link_tag "application" %> + <%= yield(:stylesheets) %> + + + + <%= flash_notices %> + + <%= yield :layout %> + + <%= yield(:bottom) %> + + \ No newline at end of file diff --git a/app/views/layouts/maintenance.html.erb b/app/views/layouts/maintenance.html.erb new file mode 100644 index 0000000..516c888 --- /dev/null +++ b/app/views/layouts/maintenance.html.erb @@ -0,0 +1,63 @@ + + + + + + + Manutenção + + + + + + +
+
+

Estamos em manutenção

+

Nosso serviço está fora do ar <%= reason ? reason : "para manutenção" %> a partir de <%= Time.now.strftime("%H:%M %Z") %>.

+

Nós voltaremos <%= deadline ? deadline : "o quanto antes possível" %>.

+
+
+ + + diff --git a/config/asset_packages.yml b/config/asset_packages.yml new file mode 100644 index 0000000..ee2d8d8 --- /dev/null +++ b/config/asset_packages.yml @@ -0,0 +1,11 @@ +--- +javascripts: +- base: + - prototype + - effects + - dragdrop + - controls + - application +stylesheets: +- base: [] + diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..dd5e3b6 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,110 @@ +# Don't change this file! +# Configure your app in config/environment.rb and config/environments/*.rb + +RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) + +module Rails + class << self + def boot! + unless booted? + preinitialize + pick_boot.run + end + end + + def booted? + defined? Rails::Initializer + end + + def pick_boot + (vendor_rails? ? VendorBoot : GemBoot).new + end + + def vendor_rails? + File.exist?("#{RAILS_ROOT}/vendor/rails") + end + + def preinitialize + load(preinitializer_path) if File.exist?(preinitializer_path) + end + + def preinitializer_path + "#{RAILS_ROOT}/config/preinitializer.rb" + end + end + + class Boot + def run + load_initializer + Rails::Initializer.run(:set_load_path) + end + end + + class VendorBoot < Boot + def load_initializer + require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" + Rails::Initializer.run(:install_gem_spec_stubs) + Rails::GemDependency.add_frozen_gem_path + end + end + + class GemBoot < Boot + def load_initializer + self.class.load_rubygems + load_rails_gem + require 'initializer' + end + + def load_rails_gem + if version = self.class.gem_version + gem 'rails', version + else + gem 'rails' + end + rescue Gem::LoadError => load_error + $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) + exit 1 + end + + class << self + def rubygems_version + Gem::RubyGemsVersion rescue nil + end + + def gem_version + if defined? RAILS_GEM_VERSION + RAILS_GEM_VERSION + elsif ENV.include?('RAILS_GEM_VERSION') + ENV['RAILS_GEM_VERSION'] + else + parse_gem_version(read_environment_rb) + end + end + + def load_rubygems + min_version = '1.3.2' + require 'rubygems' + unless rubygems_version >= min_version + $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) + exit 1 + end + + rescue LoadError + $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) + exit 1 + end + + def parse_gem_version(text) + $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ + end + + private + def read_environment_rb + File.read("#{RAILS_ROOT}/config/environment.rb") + end + end + end +end + +# All that for this: +Rails.boot! diff --git a/config/deploy.rb b/config/deploy.rb new file mode 100644 index 0000000..7ea55ef --- /dev/null +++ b/config/deploy.rb @@ -0,0 +1,123 @@ +# APP SETTINGS +set :application, "APPNAME" +set :domain_name , "www.appname.com" + +# GIT SETTINGS +set :scm, :git +set :repository, "git@github.com:danielvlopes/REPO.git" +set :branch, "master" +set :deploy_via, :remote_cache + +# SSH SETTINGS +set :user , "USERNAME" +set :deploy_to, "~/#{application}" +set :shared_directory, "#{deploy_to}/shared" +set :use_sudo, false +set :group_writable, false +default_run_options[:pty] = true + +# ROLES +role :app, domain_name +role :web, domain_name +role :db, domain_name, :primary => true + +#TASKS +task :after_update_code, :roles => [:web, :db, :app] do + run "chmod 755 #{release_path}/public" + db.upload_database_yaml + assets.package +end + +namespace :deploy do + # Restart passenger on deploy + desc "Restarting mod_rails with restart.txt" + task :restart, :roles => :app, :except => { :no_release => true } do + run "touch #{current_path}/tmp/restart.txt" + end + + [:start, :stop].each do |t| + desc "#{t} task is a no-op with mod_rails" + task t, :roles => :app do ; end + end + + namespace :web do + task :disable, :roles => :web do + on_rollback { rm "#{shared_path}/system/maintenance.html" } + + require 'erb' + deadline, reason = ENV['UNTIL'], ENV['REASON'] + maintenance = ERB.new(File.read("./app/views/layouts/maintenance.html.erb")).result(binding) + + put maintenance, "#{shared_path}/system/maintenance.html", :mode => 0644 + end + end +end + +namespace :log do + desc "tail production log files" + task :tail, :roles => :app do + run "tail -f #{shared_path}/log/production.log" do |channel, stream, data| + puts # para uma linha extra + puts "#{channel[:host]}: #{data}" + break if stream == :err + end + end +end + +namespace :ssh do + desc "upload you public ssh key" + task :upload_key, :roles => :app do + public_key_path = File.expand_path("~/.ssh/id_rsa.pub") + unless File.exists?(public_key_path) + puts %{ + Public key not found #{public_key_path} + Create your key - without passphrase: + ssh_keygen -t rsa + } + exit 0 + end + ssh_path = "/home/#{user}/.ssh" + run "test -d #{ssh_path} || mkdir -pm 755 #{ssh_path}" + upload public_key_path, "#{ssh_path}/../id_rsa.pub" + run "test -f #{ssh_path}/authorized_keys || touch #{ssh_path}/authorized_keys" + run "cat #{ssh_path}/../id_rsa.pub >> #{ssh_path}/authorized_keys" + run "chmod 755 #{ssh_path}/authorized_keys" + run "rm #{ssh_path}/../id_rsa.pub" + end +end + +namespace :assets do + desc "create asset packages for production" + task :package, :roles => :web do + run "cd #{current_path} && rake asset:packager:build_all" + end +end + +namespace :db do + + desc "remote backup and download the MySQL database" + task :backup, :roles => :db do + backup_rb ||= "#{current_path}/lib/backup.rb" + run "if [ -f #{backup_rb} ]; then ruby #{backup_rb} backup #{deploy_to} ; fi" + get "#{deploy_to}/etc/dump.tar.gz", "#{Date.today.to_s}.tar.gz" + run "rm #{deploy_to}/etc/dump.tar.gz" + end + + desc "upload and restore of remote MySQL database" + task :restore, :roles => :db do + unless File.exists?("dump.tar.gz") + puts "Backup dump.tar.gz not found" + exit 0 + end + backup_rb ||= "#{current_path}/lib/backup.rb" + upload "dump.tar.gz", "#{deploy_to}/etc/dump.tar.gz" + run "if [ -f #{backup_rb} ]; then ruby #{backup_rb} restore #{deploy_to} ; fi" + end + + desc "upload database.yml" + task :upload_database_yaml do + upload File.join(File.dirname(__FILE__), "database.yml"), "#{shared_path}/database.yml" + run "ln -s #{shared_path}/database.yml #{release_path}/config/database.yml" + end + +end \ No newline at end of file diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..5b45199 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,42 @@ +# Be sure to restart your server when you modify this file + +# Specifies gem version of Rails to use when vendor/rails is not present +RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION + +# Bootstrap the Rails environment, frameworks, and default configuration +require File.join(File.dirname(__FILE__), 'boot') + +Rails::Initializer.run do |config| + config.gem 'erubis' + # 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. + + # Add additional load paths for your own custom dirs + # config.load_paths += %W( #{RAILS_ROOT}/extras ) + + # Specify gems that this application depends on and have them installed with rake gems:install + # config.gem "bj" + # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" + # config.gem "sqlite3-ruby", :lib => "sqlite3" + # config.gem "aws-s3", :lib => "aws/s3" + + # 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 ] + + # Skip frameworks you're not going to use. To use Rails without a database, + # you must remove the Active Record framework. + # config.frameworks -= [ :active_record, :active_resource, :action_mailer ] + + # 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. + config.time_zone = 'UTC' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] + # config.i18n.default_locale = :de +end \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..85c9a60 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,17 @@ +# Settings specified here will take precedence over those in config/environment.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 webserver 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.action_controller.consider_all_requests_local = true +config.action_view.debug_rjs = true +config.action_controller.perform_caching = false + +# Don't care if the mailer can't send +config.action_mailer.raise_delivery_errors = false \ No newline at end of file diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..27119d2 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,28 @@ +# Settings specified here will take precedence over those in config/environment.rb + +# The production environment is meant for finished, "live" apps. +# Code is not reloaded between requests +config.cache_classes = true + +# Full error reports are disabled and caching is turned on +config.action_controller.consider_all_requests_local = false +config.action_controller.perform_caching = true +config.action_view.cache_template_loading = true + +# See everything in the log (default is :info) +# config.log_level = :debug + +# Use a different logger for distributed setups +# config.logger = SyslogLogger.new + +# Use a different cache store in production +# config.cache_store = :mem_cache_store + +# Enable serving of images, stylesheets, and javascripts from an asset server +# config.action_controller.asset_host = "http://assets.example.com" + +# Disable delivery errors, bad email addresses will be ignored +# config.action_mailer.raise_delivery_errors = false + +# Enable threaded mode +# config.threadsafe! \ No newline at end of file diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..8b15d6d --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,32 @@ +# Settings specified here will take precedence over those in config/environment.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.action_controller.consider_all_requests_local = true +config.action_controller.perform_caching = false +config.action_view.cache_template_loading = true + +# 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 +config.gem "rspec" +config.gem "rspec-rails" +config.gem "remarkable_rails" +config.gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com" \ No newline at end of file diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..c2169ed --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# 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 do debug a problem that might steem from framework code. +# Rails.backtrace_cleaner.remove_silencers! \ No newline at end of file diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..d531b8b --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,10 @@ +# 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 diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..72aca7e --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,5 @@ +# 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/config/initializers/new_rails_defaults.rb b/config/initializers/new_rails_defaults.rb new file mode 100644 index 0000000..c94db0a --- /dev/null +++ b/config/initializers/new_rails_defaults.rb @@ -0,0 +1,21 @@ +# Be sure to restart your server when you modify this file. + +# These settings change the behavior of Rails 2 apps and will be defaults +# for Rails 3. You can remove this initializer when Rails 3 is released. + +if defined?(ActiveRecord) + # Include Active Record class name as root for JSON serialized output. + ActiveRecord::Base.include_root_in_json = true + + # Store the full class name (including module namespace) in STI type column. + ActiveRecord::Base.store_full_sti_class = true +end + +ActionController::Routing.generate_best_match = false + +# Use ISO 8601 format for JSON serialized times and dates. +ActiveSupport.use_standard_json_time_format = true + +# Don't escape HTML entities in JSON, leave that for the #json_escape helper. +# if you're including raw json in an HTML page. +ActiveSupport.escape_html_entities_in_json = false \ No newline at end of file diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..8755a94 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,15 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key for verifying cookie session data integrity. +# If you change this key, all old sessions 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. +ActionController::Base.session = { + :key => '_railsmg_session', + :secret => 'dfde05570f361b7cd5f68ba862cd32ff771346ad00de30608a770ffcba0d66dac53552f88db40be749f0c16b50320a80b384fe432adff8ba79517088d2cc2a6c' +} + +# 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 "rake db:sessions:create") +# ActionController::Base.session_store = :active_record_store diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..f265c06 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,5 @@ +# Sample localization file for English. Add more files in this directory for other locales. +# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. + +en: + hello: "Hello world" \ No newline at end of file diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml new file mode 100644 index 0000000..15d9653 --- /dev/null +++ b/config/locales/pt-BR.yml @@ -0,0 +1,143 @@ +pt-BR: + # formatos de data e hora + date: + formats: + default: "%d/%m/%Y" + short: "%d de %B" + long: "%d de %B de %Y" + + day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado] + abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb] + month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro] + abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez] + order: [ :day, :month, :year ] + + time: + formats: + default: "%A, %d de %B de %Y, %H:%M h" + short: "%d/%m, %H:%M h" + long: "%A, %d de %B de %Y, %H:%M h" + am: '' + pm: '' + + # date helper distanci em palavras + datetime: + distance_in_words: + half_a_minute: 'meio minuto' + less_than_x_seconds: + one: 'menos de 1 segundo' + other: 'menos de {{count}} segundos' + + x_seconds: + one: '1 segundo' + other: '{{count}} segundos' + + less_than_x_minutes: + one: 'menos de um minuto' + other: 'menos de {{count}} minutos' + + x_minutes: + one: '1 minuto' + other: '{{count}} minutos' + + about_x_hours: + one: 'aproximadamente 1 hora' + other: 'aproximadamente {{count}} horas' + + x_days: + one: '1 dia' + other: '{{count}} dias' + + about_x_months: + one: 'aproximadamente 1 mês' + other: 'aproximadamente {{count}} meses' + + x_months: + one: '1 mês' + other: '{{count}} meses' + + about_x_years: + one: 'aproximadamente 1 ano' + other: 'aproximadamente {{count}} anos' + + over_x_years: + one: 'mais de 1 ano' + other: 'mais de {{count}} anos' + prompts: + year: "Ano" + month: "Mês" + day: "Dia" + hour: "Hora" + minute: "Minuto" + second: "Segundos" + + # numeros + number: + format: + precision: 3 + separator: ',' + delimiter: '.' + currency: + format: + unit: 'R$' + precision: 2 + format: '%u %n' + separator: ',' + delimiter: '.' + percentage: + format: + delimiter: '.' + precision: + format: + delimiter: '.' + human: + format: + precision: 1 + delimiter: '.' + storage_units: + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " e " + last_word_connector: " e " + + # Active Record + activerecord: + errors: + template: + header: + one: "Não foi possível gravar {{model}}: 1 erro" + other: "Não foi possível gravar {{model}}: {{count}} erros." + body: "Por favor, verifique o(s) seguinte(s) campo(s):" + messages: + inclusion: "não está incluído na lista" + exclusion: "não está disponível" + invalid: "não é válido" + confirmation: "não está de acordo com a confirmação" + accepted: "deve ser aceito" + empty: "não pode ficar vazio" + blank: "não pode ficar em branco" + too_long: "é muito longo (máximo: {{count}} caracteres)" + too_short: "é muito curto (mínimo: {{count}} caracteres)" + wrong_length: "não possui o tamanho esperado ({{count}} caracteres)" + taken: "já está em uso" + not_a_number: "não é um número" + greater_than: "deve ser maior do que {{count}}" + greater_than_or_equal_to: "deve ser maior ou igual a {{count}}" + equal_to: "deve ser igual a {{count}}" + less_than: "deve ser menor do que {{count}}" + less_than_or_equal_to: "deve ser menor ou igual a {{count}}" + odd: "deve ser ímpar" + even: "deve ser par" + record_invalid: "A validação falhou: {{errors}}" \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..ea14ce1 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,43 @@ +ActionController::Routing::Routes.draw do |map| + # The priority is based upon order of creation: first created -> highest priority. + + # Sample of regular route: + # map.connect 'products/:id', :controller => 'catalog', :action => 'view' + # Keep in mind you can assign values other than :controller and :action + + # Sample of named route: + # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' + # This route can be invoked with purchase_url(:id => product.id) + + # Sample resource route (maps HTTP verbs to controller actions automatically): + # map.resources :products + + # Sample resource route with options: + # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } + + # Sample resource route with sub-resources: + # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller + + # Sample resource route with more complex sub-resources + # map.resources :products do |products| + # products.resources :comments + # products.resources :sales, :collection => { :recent => :get } + # end + + # Sample resource route within a namespace: + # map.namespace :admin do |admin| + # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) + # admin.resources :products + # end + + # You can have the root of your site routed with map.root -- just remember to delete public/index.html. + # map.root :controller => "welcome" + + # See how all your routes lay out with "rake routes" + + # Install the default routes as the lowest priority. + # Note: These default routes make all actions in every controller accessible via GET requests. You should + # consider removing or commenting them out if you're using named routes and resources. + map.connect ':controller/:action/:id' + map.connect ':controller/:action/:id.:format' +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..3174d0c --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) +# Major.create(:name => 'Daley', :city => cities.first) diff --git a/lib/backup.rb b/lib/backup.rb new file mode 100644 index 0000000..8690e3f --- /dev/null +++ b/lib/backup.rb @@ -0,0 +1,28 @@ +#!/usr/bin/env ruby -wKU +require 'yaml' +require 'erb' + +operation, deploy_to = ARGV +cfg = YAML::load(ERB.new(IO.read("#{deploy_to}/shared/database.yml")).result) +exit 0 unless cfg['production'] # get out if dont find database.yml +prd = cfg['production'] +mysql_opts = "-u #{prd['username']} -p#{prd['password']} #{prd['database']}" + +commands = [] + +case operation +when 'backup' + commands << "test -d #{deploy_to}/etc || mkdir -pm 755 #{deploy_to}/etc" + commands << "mysqldump #{mysql_opts} > #{deploy_to}/etc/dump.sql" + commands << "cd #{deploy_to}/etc && tar cvfz dump.tar.gz dump.sql" + commands << "rm #{deploy_to}/etc/dump.sql" +when 'restore' + commands << "cd #{deploy_to}/etc && if [ -f dump.tar.gz ]; then tar xvfz dump.tar.gz dump.sql ; fi" + commands << "if [ -f #{deploy_to}/etc/dump.sql ]; then mysql -u #{mysql_opts} < #{deploy_to}/etc/dump.sql && rm #{deploy_to}/etc/dump.sql ; fi" +end + +commands.each do |cmd| + puts "running: #{cmd.gsub(prd['password'], '*****')}" + `#{cmd}` +end +puts "#{operation} finished sucessfuly." diff --git a/lib/tasks/rspec.rake b/lib/tasks/rspec.rake new file mode 100644 index 0000000..dba3ffc --- /dev/null +++ b/lib/tasks/rspec.rake @@ -0,0 +1,144 @@ +gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9 +rspec_gem_dir = nil +Dir["#{RAILS_ROOT}/vendor/gems/*"].each do |subdir| + rspec_gem_dir = subdir if subdir.gsub("#{RAILS_ROOT}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb") +end +rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec') + +if rspec_gem_dir && (test ?d, rspec_plugin_dir) + raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n" +end + +if rspec_gem_dir + $LOAD_PATH.unshift("#{rspec_gem_dir}/lib") +elsif File.exist?(rspec_plugin_dir) + $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib") +end + +# Don't load rspec if running "rake gems:*" +unless ARGV.any? {|a| a =~ /^gems/} + +begin + require 'spec/rake/spectask' +rescue MissingSourceFile + module Spec + module Rake + class SpecTask + def initialize(name) + task name do + # if rspec-rails is a configured gem, this will output helpful material and exit ... + require File.expand_path(File.join(File.dirname(__FILE__),"..","..","config","environment")) + + # ... otherwise, do this: + raise <<-MSG + +#{"*" * 80} +* You are trying to run an rspec rake task defined in +* #{__FILE__}, +* but rspec can not be found in vendor/gems, vendor/plugins or system gems. +#{"*" * 80} +MSG + end + end + end + end + end +end + +Rake.application.instance_variable_get('@tasks').delete('default') + +spec_prereq = File.exist?(File.join(RAILS_ROOT, 'config', 'database.yml')) ? "db:test:prepare" : :noop +task :noop do +end + +task :default => :spec +task :stats => "spec:statsetup" + +desc "Run all specs in spec directory (excluding plugin specs)" +Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['spec/**/*_spec.rb'] +end + +namespace :spec do + desc "Run all specs in spec directory with RCov (excluding plugin specs)" + Spec::Rake::SpecTask.new(:rcov) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['spec/**/*_spec.rb'] + t.rcov = true + t.rcov_opts = lambda do + IO.readlines("#{RAILS_ROOT}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten + end + end + + desc "Print Specdoc for all specs (excluding plugin specs)" + Spec::Rake::SpecTask.new(:doc) do |t| + t.spec_opts = ["--format", "specdoc", "--dry-run"] + t.spec_files = FileList['spec/**/*_spec.rb'] + end + + desc "Print Specdoc for all plugin examples" + Spec::Rake::SpecTask.new(:plugin_doc) do |t| + t.spec_opts = ["--format", "specdoc", "--dry-run"] + t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*') + end + + [:models, :controllers, :views, :helpers, :lib, :integration].each do |sub| + desc "Run the code examples in spec/#{sub}" + Spec::Rake::SpecTask.new(sub => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"] + end + end + + desc "Run the code examples in vendor/plugins (except RSpec's own)" + Spec::Rake::SpecTask.new(:plugins => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*').exclude("vendor/plugins/rspec-rails/*") + end + + namespace :plugins do + desc "Runs the examples for rspec_on_rails" + Spec::Rake::SpecTask.new(:rspec_on_rails) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['vendor/plugins/rspec-rails/spec/**/*_spec.rb'] + end + end + + # Setup specs for stats + task :statsetup do + require 'code_statistics' + ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models') + ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views') + ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers') + ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers') + ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib') + ::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing') + ::STATS_DIRECTORIES << %w(Integration\ specs spec/integration) if File.exist?('spec/integration') + ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models') + ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views') + ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers') + ::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers') + ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib') + ::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing') + ::CodeStatistics::TEST_TYPES << "Integration specs" if File.exist?('spec/integration') + end + + namespace :db do + namespace :fixtures do + desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z." + task :load => :environment do + ActiveRecord::Base.establish_connection(Rails.env) + base_dir = File.join(Rails.root, 'spec', 'fixtures') + fixtures_dir = ENV['FIXTURES_DIR'] ? File.join(base_dir, ENV['FIXTURES_DIR']) : base_dir + + require 'active_record/fixtures' + (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } : Dir.glob(File.join(fixtures_dir, '*.{yml,csv}'))).each do |fixture_file| + Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*')) + end + end + end + end +end + +end diff --git a/log/.gitignore b/log/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..eff660b --- /dev/null +++ b/public/404.html @@ -0,0 +1,30 @@ + + + + + + + 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.

+
+ + \ No newline at end of file diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000..b54e4a3 --- /dev/null +++ b/public/422.html @@ -0,0 +1,30 @@ + + + + + + + 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.

+
+ + \ No newline at end of file diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..ec3bbf0 --- /dev/null +++ b/public/500.html @@ -0,0 +1,30 @@ + + + + + + + We're sorry, but something went wrong (500) + + + + + +
+

We're sorry, but something went wrong.

+

We've been notified about this issue and we'll take a look at it shortly.

+
+ + diff --git a/public/images/rails.png b/public/images/rails.png new file mode 100644 index 0000000..d5edc04 Binary files /dev/null and b/public/images/rails.png differ diff --git a/public/images/ua_ch.jpg b/public/images/ua_ch.jpg new file mode 100644 index 0000000..a2725fb Binary files /dev/null and b/public/images/ua_ch.jpg differ diff --git a/public/images/ua_ff.jpg b/public/images/ua_ff.jpg new file mode 100644 index 0000000..90f5551 Binary files /dev/null and b/public/images/ua_ff.jpg differ diff --git a/public/images/ua_ie.jpg b/public/images/ua_ie.jpg new file mode 100644 index 0000000..dd370fa Binary files /dev/null and b/public/images/ua_ie.jpg differ diff --git a/public/images/ua_op.jpg b/public/images/ua_op.jpg new file mode 100644 index 0000000..3e3cdf2 Binary files /dev/null and b/public/images/ua_op.jpg differ diff --git a/public/images/ua_sf.jpg b/public/images/ua_sf.jpg new file mode 100644 index 0000000..820ff07 Binary files /dev/null and b/public/images/ua_sf.jpg differ diff --git a/public/javascripts/application.js b/public/javascripts/application.js new file mode 100644 index 0000000..fe45776 --- /dev/null +++ b/public/javascripts/application.js @@ -0,0 +1,2 @@ +// Place your application-specific JavaScript functions and classes here +// This file is automatically included by javascript_include_tag :defaults diff --git a/public/javascripts/controls.js b/public/javascripts/controls.js new file mode 100644 index 0000000..ca29aef --- /dev/null +++ b/public/javascripts/controls.js @@ -0,0 +1,963 @@ +// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com) +// Contributors: +// Richard Livsey +// Rahul Bhargava +// Rob Wills +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// Autocompleter.Base handles all the autocompletion functionality +// 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 ""; + } + }, 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)); + } +}); \ No newline at end of file diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js new file mode 100644 index 0000000..07229f9 --- /dev/null +++ b/public/javascripts/dragdrop.js @@ -0,0 +1,973 @@ +// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// +// 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 = Position.cumulativeOffset(this.element); + this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging = true; + if(!this.delta) + this.delta = this.currentDelta(); + + if(this.options.zindex) { + this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + this.element.style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + 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 = Position.cumulativeOffset(this.element); + if(this.options.ghosting) { + var r = Position.realOffset(this.element); + pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; + } + + var d = this.currentDelta(); + pos[0] -= d[0]; pos[1] -= d[1]; + + if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { + pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; + pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; + } + + var p = [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) + }.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.id] = 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 = Position.cumulativeOffset(dropon); + 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')]; +}; \ No newline at end of file diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js new file mode 100644 index 0000000..5a639d2 --- /dev/null +++ b/public/javascripts/effects.js @@ -0,0 +1,1128 @@ +// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// 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) { + element = $(element); + effect = (effect || 'appear').toLowerCase(); + var options = Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 } + }, arguments[2] || { }); + Effect[element.visible() ? + Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, 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); \ No newline at end of file diff --git a/public/javascripts/prototype.js b/public/javascripts/prototype.js new file mode 100644 index 0000000..dfe8ab4 --- /dev/null +++ b/public/javascripts/prototype.js @@ -0,0 +1,4320 @@ +/* Prototype JavaScript framework, version 1.6.0.3 + * (c) 2005-2008 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * + *--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.6.0.3', + + Browser: { + IE: !!(window.attachEvent && + navigator.userAgent.indexOf('Opera') === -1), + Opera: navigator.userAgent.indexOf('Opera') > -1, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && + navigator.userAgent.indexOf('KHTML') === -1, + MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) + }, + + BrowserFeatures: { + XPath: !!document.evaluate, + SelectorsAPI: !!document.querySelector, + ElementExtensions: !!window.HTMLElement, + SpecificElementExtensions: + document.createElement('div')['__proto__'] && + document.createElement('div')['__proto__'] !== + document.createElement('form')['__proto__'] + }, + + ScriptFragment: ']*>([\\S\\s]*?)<\/script>', + JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, + + emptyFunction: function() { }, + K: function(x) { return x } +}; + +if (Prototype.Browser.MobileSafari) + Prototype.BrowserFeatures.SpecificElementExtensions = false; + + +/* Based on Alex Arnell's inheritance implementation. */ +var Class = { + create: function() { + var parent = null, properties = $A(arguments); + if (Object.isFunction(properties[0])) + parent = properties.shift(); + + function klass() { + this.initialize.apply(this, arguments); + } + + Object.extend(klass, Class.Methods); + klass.superclass = parent; + klass.subclasses = []; + + if (parent) { + var subclass = function() { }; + subclass.prototype = parent.prototype; + klass.prototype = new subclass; + parent.subclasses.push(klass); + } + + for (var i = 0; i < properties.length; i++) + klass.addMethods(properties[i]); + + if (!klass.prototype.initialize) + klass.prototype.initialize = Prototype.emptyFunction; + + klass.prototype.constructor = klass; + + return klass; + } +}; + +Class.Methods = { + addMethods: function(source) { + var ancestor = this.superclass && this.superclass.prototype; + var properties = Object.keys(source); + + if (!Object.keys({ toString: true }).length) + properties.push("toString", "valueOf"); + + for (var i = 0, length = properties.length; i < length; i++) { + var property = properties[i], value = source[property]; + if (ancestor && Object.isFunction(value) && + value.argumentNames().first() == "$super") { + var method = value; + value = (function(m) { + return function() { return ancestor[m].apply(this, arguments) }; + })(property).wrap(method); + + value.valueOf = method.valueOf.bind(method); + value.toString = method.toString.bind(method); + } + this.prototype[property] = value; + } + + return this; + } +}; + +var Abstract = { }; + +Object.extend = function(destination, source) { + for (var property in source) + destination[property] = source[property]; + return destination; +}; + +Object.extend(Object, { + inspect: function(object) { + try { + if (Object.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; + } + }, + + toJSON: function(object) { + var type = typeof object; + switch (type) { + case 'undefined': + case 'function': + case 'unknown': return; + case 'boolean': return object.toString(); + } + + if (object === null) return 'null'; + if (object.toJSON) return object.toJSON(); + if (Object.isElement(object)) return; + + var results = []; + for (var property in object) { + var value = Object.toJSON(object[property]); + if (!Object.isUndefined(value)) + results.push(property.toJSON() + ': ' + value); + } + + return '{' + results.join(', ') + '}'; + }, + + toQueryString: function(object) { + return $H(object).toQueryString(); + }, + + toHTML: function(object) { + return object && object.toHTML ? object.toHTML() : String.interpret(object); + }, + + keys: function(object) { + var keys = []; + for (var property in object) + keys.push(property); + return keys; + }, + + values: function(object) { + var values = []; + for (var property in object) + values.push(object[property]); + return values; + }, + + clone: function(object) { + return Object.extend({ }, object); + }, + + isElement: function(object) { + return !!(object && object.nodeType == 1); + }, + + isArray: function(object) { + return object != null && typeof object == "object" && + 'splice' in object && 'join' in object; + }, + + isHash: function(object) { + return object instanceof Hash; + }, + + isFunction: function(object) { + return typeof object == "function"; + }, + + isString: function(object) { + return typeof object == "string"; + }, + + isNumber: function(object) { + return typeof object == "number"; + }, + + isUndefined: function(object) { + return typeof object == "undefined"; + } +}); + +Object.extend(Function.prototype, { + argumentNames: function() { + var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1] + .replace(/\s+/g, '').split(','); + return names.length == 1 && !names[0] ? [] : names; + }, + + bind: function() { + if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } + }, + + bindAsEventListener: function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function(event) { + return __method.apply(object, [event || window.event].concat(args)); + } + }, + + curry: function() { + if (!arguments.length) return this; + var __method = this, args = $A(arguments); + return function() { + return __method.apply(this, args.concat($A(arguments))); + } + }, + + delay: function() { + var __method = this, args = $A(arguments), timeout = args.shift() * 1000; + return window.setTimeout(function() { + return __method.apply(__method, args); + }, timeout); + }, + + defer: function() { + var args = [0.01].concat($A(arguments)); + return this.delay.apply(this, args); + }, + + wrap: function(wrapper) { + var __method = this; + return function() { + return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); + } + }, + + methodize: function() { + if (this._methodized) return this._methodized; + var __method = this; + return this._methodized = function() { + return __method.apply(null, [this].concat($A(arguments))); + }; + } +}); + +Date.prototype.toJSON = function() { + return '"' + this.getUTCFullYear() + '-' + + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + + this.getUTCDate().toPaddedString(2) + 'T' + + this.getUTCHours().toPaddedString(2) + ':' + + this.getUTCMinutes().toPaddedString(2) + ':' + + this.getUTCSeconds().toPaddedString(2) + 'Z"'; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) { } + } + + return returnValue; + } +}; + +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(); + } finally { + this.currentlyExecuting = false; + } + } + } +}); +Object.extend(String, { + interpret: function(value) { + return value == null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(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; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = Object.isUndefined(count) ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return String(this); + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = Object.isUndefined(truncation) ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : String(this); + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var self = arguments.callee; + self.text.data = this; + return self.div.innerHTML; + }, + + unescapeHTML: function() { + var div = new Element('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? (div.childNodes.length > 1 ? + $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : + div.childNodes[0].nodeValue) : ''; + }, + + toQueryParams: function(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()); + var 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; + }); + }, + + toArray: function() { + return this.split(''); + }, + + succ: function() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + }, + + times: function(count) { + return count < 1 ? '' : new Array(count + 1).join(this); + }, + + camelize: function() { + var parts = this.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = this.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + capitalize: function() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); + }, + + underscore: function() { + return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); + }, + + dasherize: function() { + return this.gsub(/_/,'-'); + }, + + inspect: function(useDoubleQuotes) { + var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { + var character = String.specialChar[match[0]]; + return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + }, + + toJSON: function() { + return this.inspect(true); + }, + + unfilterJSON: function(filter) { + return this.sub(filter || Prototype.JSONFilter, '#{1}'); + }, + + isJSON: function() { + var str = this; + if (str.blank()) return false; + str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); + return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); + }, + + evalJSON: function(sanitize) { + var json = this.unfilterJSON(); + try { + if (!sanitize || json.isJSON()) return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); + }, + + include: function(pattern) { + return this.indexOf(pattern) > -1; + }, + + startsWith: function(pattern) { + return this.indexOf(pattern) === 0; + }, + + endsWith: function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }, + + empty: function() { + return this == ''; + }, + + blank: function() { + return /^\s*$/.test(this); + }, + + interpolate: function(object, pattern) { + return new Template(this, pattern).evaluate(object); + } +}); + +if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { + escapeHTML: function() { + return this.replace(/&/g,'&').replace(//g,'>'); + }, + unescapeHTML: function() { + return this.stripTags().replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (Object.isFunction(replacement)) return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +}; + +String.prototype.parseQuery = String.prototype.toQueryParams; + +Object.extend(String.prototype.escapeHTML, { + div: document.createElement('div'), + text: document.createTextNode('') +}); + +String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text); + +var Template = Class.create({ + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + if (Object.isFunction(object.toTemplateReplacements)) + object = object.toTemplateReplacements(); + + return this.template.gsub(this.pattern, function(match) { + if (object == null) return ''; + + var before = match[1] || ''; + if (before == '\\') return match[2]; + + var ctx = object, expr = match[3]; + var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; + match = pattern.exec(expr); + if (match == null) return before; + + while (match != null) { + var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; + ctx = ctx[comp]; + if (null == ctx || '' == match[3]) break; + expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); + match = pattern.exec(expr); + } + + return before + String.interpret(ctx); + }); + } +}); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; + +var $break = { }; + +var Enumerable = { + each: function(iterator, context) { + var index = 0; + try { + this._each(function(value) { + iterator.call(context, value, index++); + }); + } catch (e) { + if (e != $break) throw e; + } + return this; + }, + + eachSlice: function(number, iterator, context) { + var index = -number, slices = [], array = this.toArray(); + if (number < 1) return array; + while ((index += number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.collect(iterator, context); + }, + + all: function(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; + }, + + any: function(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; + }, + + collect: function(iterator, context) { + iterator = iterator || Prototype.K; + var results = []; + this.each(function(value, index) { + results.push(iterator.call(context, value, index)); + }); + return results; + }, + + detect: function(iterator, context) { + var result; + this.each(function(value, index) { + if (iterator.call(context, value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator, context) { + var results = []; + this.each(function(value, index) { + if (iterator.call(context, value, index)) + results.push(value); + }); + return results; + }, + + grep: function(filter, iterator, context) { + iterator = iterator || Prototype.K; + var results = []; + + if (Object.isString(filter)) + filter = new RegExp(filter); + + this.each(function(value, index) { + if (filter.match(value)) + results.push(iterator.call(context, value, index)); + }); + return results; + }, + + include: function(object) { + if (Object.isFunction(this.indexOf)) + if (this.indexOf(object) != -1) return true; + + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inGroupsOf: function(number, fillWith) { + fillWith = Object.isUndefined(fillWith) ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + }, + + inject: function(memo, iterator, context) { + this.each(function(value, index) { + memo = iterator.call(context, memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(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; + }, + + min: function(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; + }, + + partition: function(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]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator, context) { + var results = []; + this.each(function(value, index) { + if (!iterator.call(context, value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(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'); + }, + + toArray: function() { + return this.map(); + }, + + zip: function() { + 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)); + }); + }, + + size: function() { + return this.toArray().length; + }, + + inspect: function() { + return '#'; + } +}; + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + filter: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray, + every: Enumerable.all, + some: Enumerable.any +}); +function $A(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + var length = iterable.length || 0, results = new Array(length); + while (length--) results[length] = iterable[length]; + return results; +} + +if (Prototype.Browser.WebKit) { + $A = function(iterable) { + if (!iterable) return []; + // In Safari, only use the `toArray` method if it's not a NodeList. + // A NodeList is a function, has an function `item` property, and a numeric + // `length` property. Adapted from Google Doctype. + if (!(typeof iterable === 'function' && typeof iterable.length === + 'number' && typeof iterable.item === 'function') && iterable.toArray) + return iterable.toArray(); + var length = iterable.length || 0, results = new Array(length); + while (length--) results[length] = iterable[length]; + return results; + }; +} + +Array.from = $A; + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(Object.isArray(value) ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + reduce: function() { + return this.length > 1 ? this : this[0]; + }, + + uniq: function(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + }, + + intersect: function(array) { + return this.uniq().findAll(function(item) { + return array.detect(function(value) { return item === value }); + }); + }, + + clone: function() { + return [].concat(this); + }, + + size: function() { + return this.length; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + }, + + toJSON: function() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (!Object.isUndefined(value)) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } +}); + +// use native browser JS 1.6 implementation if available +if (Object.isFunction(Array.prototype.forEach)) + Array.prototype._each = Array.prototype.forEach; + +if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { + i || (i = 0); + var length = this.length; + if (i < 0) i = length + i; + for (; i < length; i++) + if (this[i] === item) return i; + return -1; +}; + +if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { + i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; + var n = this.slice(0, i).reverse().indexOf(item); + return (n < 0) ? n : i - n - 1; +}; + +Array.prototype.toArray = Array.prototype.clone; + +function $w(string) { + if (!Object.isString(string)) return []; + string = string.strip(); + return string ? string.split(/\s+/) : []; +} + +if (Prototype.Browser.Opera){ + Array.prototype.concat = function() { + var array = []; + for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); + for (var i = 0, length = arguments.length; i < length; i++) { + if (Object.isArray(arguments[i])) { + for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) + array.push(arguments[i][j]); + } else { + array.push(arguments[i]); + } + } + return array; + }; +} +Object.extend(Number.prototype, { + toColorPart: function() { + return this.toPaddedString(2, 16); + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator, context) { + $R(0, this, true).each(iterator, context); + return this; + }, + + toPaddedString: function(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + }, + + toJSON: function() { + return isFinite(this) ? this.toString() : 'null'; + } +}); + +$w('abs round ceil floor').each(function(method){ + Number.prototype[method] = Math[method].methodize(); +}); +function $H(object) { + return new Hash(object); +}; + +var Hash = Class.create(Enumerable, (function() { + + function toQueryPair(key, value) { + if (Object.isUndefined(value)) return key; + return key + '=' + encodeURIComponent(String.interpret(value)); + } + + return { + initialize: function(object) { + this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); + }, + + _each: function(iterator) { + for (var key in this._object) { + var value = this._object[key], pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + set: function(key, value) { + return this._object[key] = value; + }, + + get: function(key) { + // simulating poorly supported hasOwnProperty + if (this._object[key] !== Object.prototype[key]) + return this._object[key]; + }, + + unset: function(key) { + var value = this._object[key]; + delete this._object[key]; + return value; + }, + + toObject: function() { + return Object.clone(this._object); + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + index: function(value) { + var match = this.detect(function(pair) { + return pair.value === value; + }); + return match && match.key; + }, + + merge: function(object) { + return this.clone().update(object); + }, + + update: function(object) { + return new Hash(object).inject(this, function(result, pair) { + result.set(pair.key, pair.value); + return result; + }); + }, + + toQueryString: function() { + return this.inject([], function(results, pair) { + var key = encodeURIComponent(pair.key), values = pair.value; + + if (values && typeof values == 'object') { + if (Object.isArray(values)) + return results.concat(values.map(toQueryPair.curry(key))); + } else results.push(toQueryPair(key, values)); + return results; + }).join('&'); + }, + + inspect: function() { + return '#'; + }, + + toJSON: function() { + return Object.toJSON(this.toObject()); + }, + + clone: function() { + return new Hash(this); + } + } +})()); + +Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; +Hash.from = $H; +var ObjectRange = Class.create(Enumerable, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + while (this.include(value)) { + iterator(value); + value = value.succ(); + } + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +}; + +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)) { + // simulate other verbs over post + params['_method'] = this.method; + this.method = 'post'; + } + + this.parameters = params; + + if (params = Object.toQueryString(params)) { + // when GET, append parameters to URL + if (this.method == 'get') + this.url += (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params += '&_='; + } + + try { + 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'; + } + + // user-defined headers + 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') { + // avoid memory leak in MSIE: clean up + 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 (!window.Node) var Node = { }; + +if (!Node.ELEMENT_NODE) { + // DOM level 2 ECMAScript Language Binding + Object.extend(Node, { + ELEMENT_NODE: 1, + ATTRIBUTE_NODE: 2, + TEXT_NODE: 3, + CDATA_SECTION_NODE: 4, + ENTITY_REFERENCE_NODE: 5, + ENTITY_NODE: 6, + PROCESSING_INSTRUCTION_NODE: 7, + COMMENT_NODE: 8, + DOCUMENT_NODE: 9, + DOCUMENT_TYPE_NODE: 10, + DOCUMENT_FRAGMENT_NODE: 11, + NOTATION_NODE: 12 + }); +} + +(function() { + var element = this.Element; + this.Element = function(tagName, attributes) { + attributes = attributes || { }; + tagName = tagName.toLowerCase(); + var cache = Element.cache; + if (Prototype.Browser.IE && attributes.name) { + tagName = '<' + tagName + ' name="' + attributes.name + '">'; + delete attributes.name; + return Element.writeAttribute(document.createElement(tagName), attributes); + } + if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); + return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); + }; + Object.extend(this.Element, element || { }); + if (element) this.Element.prototype = element.prototype; +}).call(window); + +Element.cache = { }; + +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(element, content) { + element = $(element); + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) return element.update().insert(content); + content = Object.toHTML(content); + element.innerHTML = content.stripScripts(); + content.evalScripts.bind(content).defer(); + return element; + }, + + replace: function(element, 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(); + var value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property) { + element = $(element); + var elements = []; + while (element = element[property]) + if (element.nodeType == 1) + elements.push(Element.extend(element)); + return elements; + }, + + ancestors: function(element) { + return $(element).recursivelyCollect('parentNode'); + }, + + descendants: function(element) { + return $(element).select("*"); + }, + + firstDescendant: function(element) { + element = $(element).firstChild; + while (element && element.nodeType != 1) element = element.nextSibling; + return $(element); + }, + + immediateDescendants: function(element) { + if (!(element = $(element).firstChild)) return []; + while (element && element.nodeType != 1) element = element.nextSibling; + if (element) return [element].concat($(element).nextSiblings()); + return []; + }, + + previousSiblings: function(element) { + return $(element).recursivelyCollect('previousSibling'); + }, + + nextSiblings: function(element) { + return $(element).recursivelyCollect('nextSibling'); + }, + + siblings: function(element) { + element = $(element); + return element.previousSiblings().reverse().concat(element.nextSiblings()); + }, + + match: function(element, selector) { + if (Object.isString(selector)) + selector = new Selector(selector); + return selector.match($(element)); + }, + + up: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(element.parentNode); + var ancestors = element.ancestors(); + return Object.isNumber(expression) ? ancestors[expression] : + Selector.findElement(ancestors, expression, index); + }, + + down: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + return Object.isNumber(expression) ? element.descendants()[expression] : + Element.select(element, expression)[index || 0]; + }, + + previous: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); + var previousSiblings = element.previousSiblings(); + return Object.isNumber(expression) ? previousSiblings[expression] : + Selector.findElement(previousSiblings, expression, index); + }, + + next: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); + var nextSiblings = element.nextSiblings(); + return Object.isNumber(expression) ? nextSiblings[expression] : + Selector.findElement(nextSiblings, expression, index); + }, + + select: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element, args); + }, + + adjacent: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element.parentNode, args).without(element); + }, + + identify: function(element) { + element = $(element); + var id = element.readAttribute('id'), self = arguments.callee; + if (id) return id; + do { id = 'anonymous_element_' + self.counter++ } while ($(id)); + element.writeAttribute('id', id); + return id; + }, + + readAttribute: function(element, name) { + element = $(element); + if (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().height; + }, + + getWidth: function(element) { + return $(element).getDimensions().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(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(className) ? + 'removeClassName' : 'addClassName'](className); + }, + + // removes whitespace-only text node children + 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(); + 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; + }, + + getDimensions: function(element) { + element = $(element); + var display = element.getStyle('display'); + if (display != 'none' && display != null) // Safari bug + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + var originalDisplay = els.display; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = 'block'; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = originalDisplay; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (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; + 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('position') == 'absolute') return element; + // Position.prepare(); // To be done manually by Scripty when it needs it. + + var offsets = element.positionedOffset(); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.width = width + 'px'; + element.style.height = height + 'px'; + return element; + }, + + relativize: function(element) { + element = $(element); + if (element.getStyle('position') == 'relative') return element; + // Position.prepare(); // To be done manually by Scripty when it needs it. + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + return element; + }, + + 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; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent == document.body && + Element.getStyle(element, 'position') == 'absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } + } while (element = element.parentNode); + + return Element._returnOffset(valueL, valueT); + }, + + clonePosition: function(element, source) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || { }); + + // find page position of source + source = $(source); + var p = source.viewportOffset(); + + // find coordinate system to use + element = $(element); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(element, 'position') == 'absolute') { + parent = element.getOffsetParent(); + delta = parent.viewportOffset(); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if (options.setWidth) element.style.width = source.offsetWidth + 'px'; + if (options.setHeight) element.style.height = source.offsetHeight + 'px'; + return element; + } +}; + +Element.Methods.identify.counter = 1; + +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': + // returns '0px' for hidden elements; we want it to return null + if (!Element.visible(element)) return null; + + // returns the border-box dimensions rather than the content-box + // dimensions, so we subtract padding and borders from the value + var dim = parseInt(proceed(element, style), 10); + + if (dim !== element['offset' + style.capitalize()]) + return dim + 'px'; + + var properties; + if (style === 'height') { + properties = ['border-top-width', 'padding-top', + 'padding-bottom', 'border-bottom-width']; + } + else { + properties = ['border-left-width', 'padding-left', + 'padding-right', 'border-right-width']; + } + return properties.inject(dim, function(memo, property) { + var val = proceed(element, property); + return val === null ? memo : memo - parseInt(val, 10); + }) + 'px'; + default: return proceed(element, style); + } + } + ); + + Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( + function(proceed, element, attribute) { + if (attribute === 'title') return element.title; + return proceed(element, attribute); + } + ); +} + +else if (Prototype.Browser.IE) { + // IE doesn't report offsets correctly for static elements, so we change them + // to "relative" to get the values, then change them back. + Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( + function(proceed, element) { + element = $(element); + // IE throws an error if element is not in document + try { element.offsetParent } + catch(e) { return $(document.body) } + var position = element.getStyle('position'); + if (position !== 'static') return proceed(element); + element.setStyle({ position: 'relative' }); + var value = proceed(element); + element.setStyle({ position: position }); + return value; + } + ); + + $w('positionedOffset viewportOffset').each(function(method) { + Element.Methods[method] = Element.Methods[method].wrap( + function(proceed, element) { + element = $(element); + try { element.offsetParent } + catch(e) { return Element._returnOffset(0,0) } + var position = element.getStyle('position'); + if (position !== 'static') return proceed(element); + // Trigger hasLayout on the offset parent so that IE6 reports + // accurate offsetTop and offsetLeft values for position: fixed. + var offsetParent = element.getOffsetParent(); + if (offsetParent && offsetParent.getStyle('position') === 'fixed') + offsetParent.setStyle({ zoom: 1 }); + element.setStyle({ position: 'relative' }); + var value = proceed(element); + element.setStyle({ position: position }); + return value; + } + ); + }); + + Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap( + function(proceed, element) { + try { element.offsetParent } + catch(e) { return Element._returnOffset(0,0) } + return proceed(element); + } + ); + + Element.Methods.getStyle = function(element, style) { + element = $(element); + style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); + var value = element.style[style]; + if (!value && element.currentStyle) value = element.currentStyle[style]; + + if (style == 'opacity') { + if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value == 'auto') { + if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) + return element['offset' + style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity = function(element, value) { + function stripAlpha(filter){ + return filter.replace(/alpha\([^\)]*\)/gi,''); + } + element = $(element); + var currentStyle = element.currentStyle; + if ((currentStyle && !currentStyle.hasLayout) || + (!currentStyle && element.style.zoom == 'normal')) + element.style.zoom = 1; + + var filter = element.getStyle('filter'), style = element.style; + if (value == 1 || value === '') { + (filter = stripAlpha(filter)) ? + style.filter = filter : style.removeAttribute('filter'); + return element; + } else if (value < 0.00001) value = 0; + style.filter = stripAlpha(filter) + + 'alpha(opacity=' + (value * 100) + ')'; + return element; + }; + + Element._attributeTranslations = { + read: { + names: { + 'class': 'className', + 'for': 'htmlFor' + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _getAttrNode: function(element, attribute) { + var node = element.getAttributeNode(attribute); + return node ? node.value : ""; + }, + _getEv: function(element, attribute) { + attribute = element.getAttribute(attribute); + return attribute ? attribute.toString().slice(23, -2) : null; + }, + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + return element.title; + } + } + } + }; + + 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._getAttr, + src: v._getAttr, + type: v._getAttr, + action: v._getAttrNode, + disabled: v._flag, + checked: v._flag, + readonly: v._flag, + multiple: v._flag, + onload: v._getEv, + onunload: v._getEv, + onclick: v._getEv, + ondblclick: v._getEv, + onmousedown: v._getEv, + onmouseup: v._getEv, + onmouseover: v._getEv, + onmousemove: v._getEv, + onmouseout: v._getEv, + onfocus: v._getEv, + onblur: v._getEv, + onkeypress: v._getEv, + onkeydown: v._getEv, + onkeyup: v._getEv, + onsubmit: v._getEv, + onreset: v._getEv, + onselect: v._getEv, + onchange: v._getEv + }); + })(Element._attributeTranslations.read.values); +} + +else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1) ? 0.999999 : + (value === '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +else if (Prototype.Browser.WebKit) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + + if (value == 1) + if(element.tagName.toUpperCase() == 'IMG' && element.width) { + element.width++; element.width--; + } else try { + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch (e) { } + + return element; + }; + + // Safari returns margins on body which is incorrect if the child is absolutely + // positioned. For performance reasons, redefine Element#cumulativeOffset for + // KHTML/WebKit only. + Element.Methods.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return Element._returnOffset(valueL, valueT); + }; +} + +if (Prototype.Browser.IE || Prototype.Browser.Opera) { + // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements + Element.Methods.update = function(element, content) { + element = $(element); + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) return element.update().insert(content); + + content = Object.toHTML(content); + var tagName = element.tagName.toUpperCase(); + + if (tagName in Element._insertionTranslations.tags) { + $A(element.childNodes).each(function(node) { element.removeChild(node) }); + Element._getContentFromAnonymousElement(tagName, content.stripScripts()) + .each(function(node) { element.appendChild(node) }); + } + else element.innerHTML = content.stripScripts(); + + content.evalScripts.bind(content).defer(); + return element; + }; +} + +if ('outerHTML' in document.createElement('div')) { + Element.Methods.replace = function(element, content) { + element = $(element); + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) { + element.parentNode.replaceChild(content, element); + return element; + } + + content = Object.toHTML(content); + var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); + + if (Element._insertionTranslations.tags[tagName]) { + var nextSibling = element.next(); + var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); + parent.removeChild(element); + if (nextSibling) + fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); + else + fragments.each(function(node) { parent.appendChild(node) }); + } + else element.outerHTML = content.stripScripts(); + + content.evalScripts.bind(content).defer(); + return element; + }; +} + +Element._returnOffset = function(l, t) { + var result = [l, t]; + result.left = l; + result.top = t; + return result; +}; + +Element._getContentFromAnonymousElement = function(tagName, html) { + var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; + if (t) { + div.innerHTML = t[0] + html + t[1]; + t[2].times(function() { div = div.firstChild }); + } else div.innerHTML = html; + return $A(div.childNodes); +}; + +Element._insertionTranslations = { + before: function(element, node) { + element.parentNode.insertBefore(node, element); + }, + top: function(element, node) { + element.insertBefore(node, element.firstChild); + }, + bottom: function(element, node) { + element.appendChild(node); + }, + after: function(element, node) { + element.parentNode.insertBefore(node, element.nextSibling); + }, + tags: { + TABLE: ['', '
    ', 1], + TBODY: ['', '
    ', 2], + TR: ['', '
    ', 3], + TD: ['
    ', '
    ', 4], + SELECT: ['', 1] + } +}; + +(function() { + Object.extend(this.tags, { + THEAD: this.tags.TBODY, + TFOOT: this.tags.TBODY, + TH: this.tags.TD + }); +}).call(Element._insertionTranslations); + +Element.Methods.Simulated = { + hasAttribute: function(element, attribute) { + attribute = Element._attributeTranslations.has[attribute] || attribute; + var node = $(element).getAttributeNode(attribute); + return !!(node && node.specified); + } +}; + +Element.Methods.ByTag = { }; + +Object.extend(Element, Element.Methods); + +if (!Prototype.BrowserFeatures.ElementExtensions && + document.createElement('div')['__proto__']) { + window.HTMLElement = { }; + window.HTMLElement.prototype = document.createElement('div')['__proto__']; + Prototype.BrowserFeatures.ElementExtensions = true; +} + +Element.extend = (function() { + if (Prototype.BrowserFeatures.SpecificElementExtensions) + return Prototype.K; + + var Methods = { }, ByTag = Element.Methods.ByTag; + + var extend = Object.extend(function(element) { + if (!element || element._extendedByPrototype || + element.nodeType != 1 || element == window) return element; + + var methods = Object.clone(Methods), + tagName = element.tagName.toUpperCase(), property, value; + + // extend methods for specific tags + if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); + + for (property in methods) { + value = methods[property]; + if (Object.isFunction(value) && !(property in element)) + element[property] = value.methodize(); + } + + element._extendedByPrototype = Prototype.emptyFunction; + return element; + + }, { + refresh: function() { + // extend methods for all tags (Safari doesn't need this) + if (!Prototype.BrowserFeatures.ElementExtensions) { + Object.extend(Methods, Element.Methods); + Object.extend(Methods, Element.Methods.Simulated); + } + } + }); + + extend.refresh(); + return extend; +})(); + +Element.hasAttribute = function(element, attribute) { + if (element.hasAttribute) return element.hasAttribute(attribute); + return Element.Methods.Simulated.hasAttribute(element, attribute); +}; + +Element.addMethods = function(methods) { + 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]; + + window[klass] = { }; + window[klass].prototype = document.createElement(tagName)['__proto__']; + return window[klass]; + } + + if (F.ElementExtensions) { + copy(Element.Methods, HTMLElement.prototype); + copy(Element.Methods.Simulated, HTMLElement.prototype, true); + } + + 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() { + var dimensions = { }, B = Prototype.Browser; + $w('width height').each(function(d) { + var D = d.capitalize(); + if (B.WebKit && !document.evaluate) { + // Safari <3.0 needs self.innerWidth/Height + dimensions[d] = self['inner' + D]; + } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) { + // Opera <9.5 needs document.body.clientWidth/Height + dimensions[d] = document.body['client' + D] + } else { + dimensions[d] = document.documentElement['client' + D]; + } + }); + return dimensions; + }, + + getWidth: function() { + return this.getDimensions().width; + }, + + getHeight: function() { + return this.getDimensions().height; + }, + + getScrollOffsets: function() { + return Element._returnOffset( + window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, + window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); + } +}; +/* Portions of the Selector class are derived from Jack Slocum's DomQuery, + * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style + * license. Please see http://www.yui-ext.com/ for more information. */ + +var Selector = Class.create({ + initialize: function(expression) { + this.expression = expression.strip(); + + if (this.shouldUseSelectorsAPI()) { + this.mode = 'selectorsAPI'; + } else if (this.shouldUseXPath()) { + this.mode = 'xpath'; + this.compileXPathMatcher(); + } else { + this.mode = "normal"; + this.compileMatcher(); + } + + }, + + shouldUseXPath: function() { + if (!Prototype.BrowserFeatures.XPath) return false; + + var e = this.expression; + + // Safari 3 chokes on :*-of-type and :empty + if (Prototype.Browser.WebKit && + (e.include("-of-type") || e.include(":empty"))) + return false; + + // XPath can't do namespaced attributes, nor can it read + // the "checked" property from DOM nodes + if ((/(\[[\w-]*?:|:checked)/).test(e)) + return false; + + return true; + }, + + shouldUseSelectorsAPI: function() { + if (!Prototype.BrowserFeatures.SelectorsAPI) return false; + + if (!Selector._div) Selector._div = new Element('div'); + + // Make sure the browser treats the selector as valid. Test on an + // isolated element to minimize cost of this check. + try { + Selector._div.querySelector(this.expression); + } catch(e) { + return false; + } + + return true; + }, + + compileMatcher: function() { + var e = this.expression, ps = Selector.patterns, h = Selector.handlers, + c = Selector.criteria, le, p, m; + + if (Selector._cache[e]) { + this.matcher = Selector._cache[e]; + return; + } + + this.matcher = ["this.matcher = function(root) {", + "var r = root, h = Selector.handlers, c = false, n;"]; + + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : + new Template(c[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.matcher.push("return h.unique(n);\n}"); + eval(this.matcher.join('\n')); + Selector._cache[this.expression] = this.matcher; + }, + + compileXPathMatcher: function() { + var e = this.expression, ps = Selector.patterns, + x = Selector.xpath, le, m; + + if (Selector._cache[e]) { + this.xpath = Selector._cache[e]; return; + } + + this.matcher = ['.//*']; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + if (m = e.match(ps[i])) { + this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : + new Template(x[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.xpath = this.matcher.join(''); + Selector._cache[this.expression] = this.xpath; + }, + + findElements: function(root) { + root = root || document; + var e = this.expression, results; + + switch (this.mode) { + case 'selectorsAPI': + // querySelectorAll queries document-wide, then filters to descendants + // of the context element. That's not what we want. + // Add an explicit context to the selector if necessary. + if (root !== document) { + var oldId = root.id, id = $(root).identify(); + e = "#" + id + " " + e; + } + + results = $A(root.querySelectorAll(e)).map(Element.extend); + root.id = oldId; + + return results; + case 'xpath': + return document._getElementsByXPath(this.xpath, root); + default: + return this.matcher(root); + } + }, + + match: function(element) { + this.tokens = []; + + var e = this.expression, ps = Selector.patterns, as = Selector.assertions; + var le, p, m; + + while (e && le !== e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + // use the Selector.assertions methods unless the selector + // is too complex. + if (as[i]) { + this.tokens.push([i, Object.clone(m)]); + e = e.replace(m[0], ''); + } else { + // reluctantly do a document-wide search + // and look for a match in the array + return this.findElements(document).include(element); + } + } + } + } + + var match = true, name, matches; + for (var i = 0, token; token = this.tokens[i]; i++) { + name = token[0], matches = token[1]; + if (!Selector.assertions[name](element, matches)) { + match = false; break; + } + } + + return match; + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } +}); + +Object.extend(Selector, { + _cache: { }, + + xpath: { + descendant: "//*", + child: "/*", + adjacent: "/following-sibling::*[1]", + laterSibling: '/following-sibling::*', + tagName: function(m) { + if (m[1] == '*') return ''; + return "[local-name()='" + m[1].toLowerCase() + + "' or local-name()='" + m[1].toUpperCase() + "']"; + }, + className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", + id: "[@id='#{1}']", + attrPresence: function(m) { + m[1] = m[1].toLowerCase(); + return new Template("[@#{1}]").evaluate(m); + }, + attr: function(m) { + m[1] = m[1].toLowerCase(); + m[3] = m[5] || m[6]; + return new Template(Selector.xpath.operators[m[2]]).evaluate(m); + }, + pseudo: function(m) { + var h = Selector.xpath.pseudos[m[1]]; + if (!h) return ''; + if (Object.isFunction(h)) return h(m); + return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); + }, + operators: { + '=': "[@#{1}='#{3}']", + '!=': "[@#{1}!='#{3}']", + '^=': "[starts-with(@#{1}, '#{3}')]", + '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", + '*=': "[contains(@#{1}, '#{3}')]", + '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", + '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" + }, + pseudos: { + 'first-child': '[not(preceding-sibling::*)]', + 'last-child': '[not(following-sibling::*)]', + 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', + 'empty': "[count(*) = 0 and (count(text()) = 0)]", + 'checked': "[@checked]", + 'disabled': "[(@disabled) and (@type!='hidden')]", + 'enabled': "[not(@disabled) and (@type!='hidden')]", + 'not': function(m) { + var e = m[6], p = Selector.patterns, + x = Selector.xpath, le, v; + + var exclusion = []; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in p) { + if (m = e.match(p[i])) { + v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); + exclusion.push("(" + v.substring(1, v.length - 1) + ")"); + e = e.replace(m[0], ''); + break; + } + } + } + return "[not(" + exclusion.join(" and ") + ")]"; + }, + 'nth-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); + }, + 'nth-last-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); + }, + 'nth-of-type': function(m) { + return Selector.xpath.pseudos.nth("position() ", m); + }, + 'nth-last-of-type': function(m) { + return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); + }, + 'first-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); + }, + 'last-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); + }, + 'only-of-type': function(m) { + var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); + }, + nth: function(fragment, m) { + var mm, formula = m[6], predicate; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + if (mm = formula.match(/^(\d+)$/)) // digit only + return '[' + fragment + "= " + mm[1] + ']'; + if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (mm[1] == "-") mm[1] = -1; + var a = mm[1] ? Number(mm[1]) : 1; + var b = mm[2] ? Number(mm[2]) : 0; + predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + + "((#{fragment} - #{b}) div #{a} >= 0)]"; + return new Template(predicate).evaluate({ + fragment: fragment, a: a, b: b }); + } + } + } + }, + + criteria: { + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', + attr: function(m) { + m[3] = (m[5] || m[6]); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); + }, + pseudo: function(m) { + if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); + return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); + }, + descendant: 'c = "descendant";', + child: 'c = "child";', + adjacent: 'c = "adjacent";', + laterSibling: 'c = "laterSibling";' + }, + + patterns: { + // combinators must be listed first + // (and descendant needs to be last combinator) + laterSibling: /^\s*~\s*/, + child: /^\s*>\s*/, + adjacent: /^\s*\+\s*/, + descendant: /^\s/, + + // selectors follow + tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, + id: /^#([\w\-\*]+)(\b|$)/, + className: /^\.([\w\-\*]+)(\b|$)/, + pseudo: +/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, + attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/, + attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ + }, + + // for Selector.match and Element#match + assertions: { + tagName: function(element, matches) { + return matches[1].toUpperCase() == element.tagName.toUpperCase(); + }, + + className: function(element, matches) { + return Element.hasClassName(element, matches[1]); + }, + + id: function(element, matches) { + return element.id === matches[1]; + }, + + attrPresence: function(element, matches) { + return Element.hasAttribute(element, matches[1]); + }, + + attr: function(element, matches) { + var nodeValue = Element.readAttribute(element, matches[1]); + return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); + } + }, + + handlers: { + // UTILITY FUNCTIONS + // joins two collections + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + a.push(node); + return a; + }, + + // marks an array of nodes for counting + mark: function(nodes) { + var _true = Prototype.emptyFunction; + for (var i = 0, node; node = nodes[i]; i++) + node._countedByPrototype = _true; + return nodes; + }, + + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._countedByPrototype = undefined; + return nodes; + }, + + // mark each child node with its position (for nth calls) + // "ofType" flag indicates whether we're indexing for nth-of-type + // rather than nth-child + index: function(parentNode, reverse, ofType) { + parentNode._countedByPrototype = Prototype.emptyFunction; + if (reverse) { + for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { + var node = nodes[i]; + if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; + } + } else { + for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) + if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; + } + }, + + // filters out duplicates and extends all nodes + unique: function(nodes) { + if (nodes.length == 0) return nodes; + var results = [], n; + for (var i = 0, l = nodes.length; i < l; i++) + if (!(n = nodes[i])._countedByPrototype) { + n._countedByPrototype = Prototype.emptyFunction; + results.push(Element.extend(n)); + } + return Selector.handlers.unmark(results); + }, + + // COMBINATOR FUNCTIONS + descendant: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName('*')); + return results; + }, + + child: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) { + for (var j = 0, child; child = node.childNodes[j]; j++) + if (child.nodeType == 1 && child.tagName != '!') results.push(child); + } + return results; + }, + + adjacent: function(nodes) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + var next = this.nextElementSibling(node); + if (next) results.push(next); + } + return results; + }, + + laterSibling: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, Element.nextSiblings(node)); + return results; + }, + + nextElementSibling: function(node) { + while (node = node.nextSibling) + if (node.nodeType == 1) return node; + return null; + }, + + previousElementSibling: function(node) { + while (node = node.previousSibling) + if (node.nodeType == 1) return node; + return null; + }, + + // TOKEN FUNCTIONS + tagName: function(nodes, root, tagName, combinator) { + var uTagName = tagName.toUpperCase(); + var results = [], h = Selector.handlers; + if (nodes) { + if (combinator) { + // fastlane for ordinary descendant combinators + if (combinator == "descendant") { + for (var i = 0, node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName(tagName)); + return results; + } else nodes = this[combinator](nodes); + if (tagName == "*") return nodes; + } + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName.toUpperCase() === uTagName) results.push(node); + return results; + } else return root.getElementsByTagName(tagName); + }, + + id: function(nodes, root, id, combinator) { + var targetNode = $(id), h = Selector.handlers; + if (!targetNode) return []; + if (!nodes && root == document) return [targetNode]; + if (nodes) { + if (combinator) { + if (combinator == 'child') { + for (var i = 0, node; node = nodes[i]; i++) + if (targetNode.parentNode == node) return [targetNode]; + } else if (combinator == 'descendant') { + for (var i = 0, node; node = nodes[i]; i++) + if (Element.descendantOf(targetNode, node)) return [targetNode]; + } else if (combinator == 'adjacent') { + for (var i = 0, node; node = nodes[i]; i++) + if (Selector.handlers.previousElementSibling(targetNode) == node) + return [targetNode]; + } else nodes = h[combinator](nodes); + } + for (var i = 0, node; node = nodes[i]; i++) + if (node == targetNode) return [targetNode]; + return []; + } + return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; + }, + + className: function(nodes, root, className, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + return Selector.handlers.byClassName(nodes, root, className); + }, + + byClassName: function(nodes, root, className) { + if (!nodes) nodes = Selector.handlers.descendant([root]); + var needle = ' ' + className + ' '; + for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { + nodeClassName = node.className; + if (nodeClassName.length == 0) continue; + if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) + results.push(node); + } + return results; + }, + + attrPresence: function(nodes, root, attr, combinator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + if (nodes && combinator) nodes = this[combinator](nodes); + var results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (Element.hasAttribute(node, attr)) results.push(node); + return results; + }, + + attr: function(nodes, root, attr, value, operator, combinator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + if (nodes && combinator) nodes = this[combinator](nodes); + var handler = Selector.operators[operator], results = []; + for (var i = 0, node; node = nodes[i]; i++) { + var nodeValue = Element.readAttribute(node, attr); + if (nodeValue === null) continue; + if (handler(nodeValue, value)) results.push(node); + } + return results; + }, + + pseudo: function(nodes, name, value, root, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + if (!nodes) nodes = root.getElementsByTagName("*"); + return Selector.pseudos[name](nodes, value, root); + } + }, + + pseudos: { + 'first-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.previousElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'last-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.nextElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'only-child': function(nodes, value, root) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) + results.push(node); + return results; + }, + 'nth-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root); + }, + 'nth-last-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true); + }, + 'nth-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, false, true); + }, + 'nth-last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true, true); + }, + 'first-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, false, true); + }, + 'last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, true, true); + }, + 'only-of-type': function(nodes, formula, root) { + var p = Selector.pseudos; + return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); + }, + + // handles the an+b logic + getIndices: function(a, b, total) { + if (a == 0) return b > 0 ? [b] : []; + return $R(1, total).inject([], function(memo, i) { + if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); + return memo; + }); + }, + + // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type + nth: function(nodes, formula, root, reverse, ofType) { + if (nodes.length == 0) return []; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + var h = Selector.handlers, results = [], indexed = [], m; + h.mark(nodes); + for (var i = 0, node; node = nodes[i]; i++) { + if (!node.parentNode._countedByPrototype) { + h.index(node.parentNode, reverse, ofType); + indexed.push(node.parentNode); + } + } + if (formula.match(/^\d+$/)) { // just a number + formula = Number(formula); + for (var i = 0, node; node = nodes[i]; i++) + if (node.nodeIndex == formula) results.push(node); + } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (m[1] == "-") m[1] = -1; + var a = m[1] ? Number(m[1]) : 1; + var b = m[2] ? Number(m[2]) : 0; + var indices = Selector.pseudos.getIndices(a, b, nodes.length); + for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { + for (var j = 0; j < l; j++) + if (node.nodeIndex == indices[j]) results.push(node); + } + } + h.unmark(nodes); + h.unmark(indexed); + return results; + }, + + 'empty': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + // IE treats comments as element nodes + if (node.tagName == '!' || node.firstChild) continue; + results.push(node); + } + return results; + }, + + 'not': function(nodes, selector, root) { + var h = Selector.handlers, selectorType, m; + var exclusions = new Selector(selector).findElements(root); + h.mark(exclusions); + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node._countedByPrototype) results.push(node); + h.unmark(exclusions); + return results; + }, + + 'enabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node.disabled && (!node.type || node.type !== 'hidden')) + results.push(node); + return results; + }, + + 'disabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.disabled) results.push(node); + return results; + }, + + 'checked': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.checked) results.push(node); + return results; + } + }, + + operators: { + '=': function(nv, v) { return nv == v; }, + '!=': function(nv, v) { return nv != v; }, + '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); }, + '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); }, + '*=': function(nv, v) { return nv == v || nv && nv.include(v); }, + '$=': function(nv, v) { return nv.endsWith(v); }, + '*=': function(nv, v) { return nv.include(v); }, + '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, + '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() + + '-').include('-' + (v || "").toUpperCase() + '-'); } + }, + + split: function(expression) { + var expressions = []; + expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + return expressions; + }, + + matchElements: function(elements, expression) { + var matches = $$(expression), h = Selector.handlers; + h.mark(matches); + for (var i = 0, results = [], element; element = elements[i]; i++) + if (element._countedByPrototype) results.push(element); + h.unmark(matches); + return results; + }, + + findElement: function(elements, expression, index) { + if (Object.isNumber(expression)) { + index = expression; expression = false; + } + return Selector.matchElements(elements, expression || '*')[index || 0]; + }, + + findChildElements: function(element, expressions) { + expressions = Selector.split(expressions.join(',')); + var results = [], h = Selector.handlers; + for (var i = 0, l = expressions.length, selector; i < l; i++) { + selector = new Selector(expressions[i].strip()); + h.concat(results, selector.findElements(element)); + } + return (l > 1) ? h.unique(results) : results; + } +}); + +if (Prototype.Browser.IE) { + Object.extend(Selector.handlers, { + // IE returns comment nodes on getElementsByTagName("*"). + // Filter them out. + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + if (node.tagName !== "!") a.push(node); + return a; + }, + + // IE improperly serializes _countedByPrototype in (inner|outer)HTML. + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node.removeAttribute('_countedByPrototype'); + return nodes; + } + }); +} + +function $$() { + return Selector.findChildElements(document, $A(arguments)); +} +var Form = { + reset: function(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) { + // a key is already present; construct an array of values + if (!Object.isArray(result[key])) result[key] = [result[key]]; + result[key].push(value); + } + else result[key] = value; + } + } + 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) { + return $A($(form).getElementsByTagName('*')).inject([], + function(elements, child) { + if (Form.Element.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'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + form = $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form = $(form), options = Object.clone(options || { }); + + var params = options.parameters, action = 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'].include(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) { + // extend element because hasAttribute may not be native + 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); + } +}); +if (!window.Event) var Event = { }; + +Object.extend(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: { }, + + relatedTarget: function(event) { + var element; + switch(event.type) { + case 'mouseover': element = event.fromElement; break; + case 'mouseout': element = event.toElement; break; + default: return null; + } + return Element.extend(element); + } +}); + +Event.Methods = (function() { + 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); + }; + } + + return { + isLeftClick: function(event) { return isButton(event, 0) }, + isMiddleClick: function(event) { return isButton(event, 1) }, + isRightClick: function(event) { return isButton(event, 2) }, + + element: function(event) { + event = Event.extend(event); + + var node = event.target, + type = event.type, + currentTarget = event.currentTarget; + + if (currentTarget && currentTarget.tagName) { + // Firefox screws up the "click" event when moving between radio buttons + // via arrow keys. It also screws up the "load" and "error" events on images, + // reporting the document as the target instead of the original image. + if (type === 'load' || type === 'error' || + (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' + && currentTarget.type === 'radio')) + node = currentTarget; + } + if (node.nodeType == Node.TEXT_NODE) node = node.parentNode; + return Element.extend(node); + }, + + findElement: function(event, expression) { + var element = Event.element(event); + if (!expression) return element; + var elements = [element].concat(element.ancestors()); + return Selector.findElement(elements, expression, 0); + }, + + pointer: function(event) { + var docElement = document.documentElement, + body = document.body || { scrollLeft: 0, scrollTop: 0 }; + return { + x: event.pageX || (event.clientX + + (docElement.scrollLeft || body.scrollLeft) - + (docElement.clientLeft || 0)), + y: event.pageY || (event.clientY + + (docElement.scrollTop || body.scrollTop) - + (docElement.clientTop || 0)) + }; + }, + + pointerX: function(event) { return Event.pointer(event).x }, + pointerY: function(event) { return Event.pointer(event).y }, + + stop: function(event) { + Event.extend(event); + event.preventDefault(); + event.stopPropagation(); + event.stopped = true; + } + }; +})(); + +Event.extend = (function() { + var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { + m[name] = Event.Methods[name].methodize(); + return m; + }); + + if (Prototype.Browser.IE) { + Object.extend(methods, { + stopPropagation: function() { this.cancelBubble = true }, + preventDefault: function() { this.returnValue = false }, + inspect: function() { return "[object Event]" } + }); + + return function(event) { + if (!event) return false; + if (event._extendedByPrototype) return event; + + event._extendedByPrototype = Prototype.emptyFunction; + var pointer = Event.pointer(event); + Object.extend(event, { + target: event.srcElement, + relatedTarget: Event.relatedTarget(event), + pageX: pointer.x, + pageY: pointer.y + }); + return Object.extend(event, methods); + }; + + } else { + Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__']; + Object.extend(Event.prototype, methods); + return Prototype.K; + } +})(); + +Object.extend(Event, (function() { + var cache = Event.cache; + + function getEventID(element) { + if (element._prototypeEventID) return element._prototypeEventID[0]; + arguments.callee.id = arguments.callee.id || 1; + return element._prototypeEventID = [++arguments.callee.id]; + } + + function getDOMEventName(eventName) { + if (eventName && eventName.include(':')) return "dataavailable"; + return eventName; + } + + function getCacheForID(id) { + return cache[id] = cache[id] || { }; + } + + function getWrappersForEventName(id, eventName) { + var c = getCacheForID(id); + return c[eventName] = c[eventName] || []; + } + + function createWrapper(element, eventName, handler) { + var id = getEventID(element); + var c = getWrappersForEventName(id, eventName); + if (c.pluck("handler").include(handler)) return false; + + var wrapper = function(event) { + if (!Event || !Event.extend || + (event.eventName && event.eventName != eventName)) + return false; + + Event.extend(event); + handler.call(element, event); + }; + + wrapper.handler = handler; + c.push(wrapper); + return wrapper; + } + + function findWrapper(id, eventName, handler) { + var c = getWrappersForEventName(id, eventName); + return c.find(function(wrapper) { return wrapper.handler == handler }); + } + + function destroyWrapper(id, eventName, handler) { + var c = getCacheForID(id); + if (!c[eventName]) return false; + c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); + } + + function destroyCache() { + for (var id in cache) + for (var eventName in cache[id]) + cache[id][eventName] = null; + } + + + // Internet Explorer needs to remove event handlers on page unload + // in order to avoid memory leaks. + if (window.attachEvent) { + window.attachEvent("onunload", destroyCache); + } + + // Safari has a dummy event handler on page unload so that it won't + // use its bfcache. Safari <= 3.1 has an issue with restoring the "document" + // object when page is returned to via the back button using its bfcache. + if (Prototype.Browser.WebKit) { + window.addEventListener('unload', Prototype.emptyFunction, false); + } + + return { + observe: function(element, eventName, handler) { + element = $(element); + var name = getDOMEventName(eventName); + + var wrapper = createWrapper(element, eventName, handler); + if (!wrapper) return element; + + if (element.addEventListener) { + element.addEventListener(name, wrapper, false); + } else { + element.attachEvent("on" + name, wrapper); + } + + return element; + }, + + stopObserving: function(element, eventName, handler) { + element = $(element); + var id = getEventID(element), name = getDOMEventName(eventName); + + if (!handler && eventName) { + getWrappersForEventName(id, eventName).each(function(wrapper) { + element.stopObserving(eventName, wrapper.handler); + }); + return element; + + } else if (!eventName) { + Object.keys(getCacheForID(id)).each(function(eventName) { + element.stopObserving(eventName); + }); + return element; + } + + var wrapper = findWrapper(id, eventName, handler); + if (!wrapper) return element; + + if (element.removeEventListener) { + element.removeEventListener(name, wrapper, false); + } else { + element.detachEvent("on" + name, wrapper); + } + + destroyWrapper(id, eventName, handler); + + return element; + }, + + fire: function(element, eventName, memo) { + element = $(element); + if (element == document && document.createEvent && !element.dispatchEvent) + element = document.documentElement; + + var event; + if (document.createEvent) { + event = document.createEvent("HTMLEvents"); + event.initEvent("dataavailable", true, true); + } else { + event = document.createEventObject(); + event.eventType = "ondataavailable"; + } + + event.eventName = eventName; + event.memo = memo || { }; + + if (document.createEvent) { + element.dispatchEvent(event); + } else { + element.fireEvent(event.eventType, event); + } + + return Event.extend(event); + } + }; +})()); + +Object.extend(Event, Event.Methods); + +Element.addMethods({ + fire: Event.fire, + observe: Event.observe, + stopObserving: Event.stopObserving +}); + +Object.extend(document, { + fire: Element.Methods.fire.methodize(), + observe: Element.Methods.observe.methodize(), + stopObserving: Element.Methods.stopObserving.methodize(), + loaded: false +}); + +(function() { + /* Support for the DOMContentLoaded event is based on work by Dan Webb, + Matthias Miller, Dean Edwards and John Resig. */ + + var timer; + + function fireContentLoadedEvent() { + if (document.loaded) return; + if (timer) window.clearInterval(timer); + document.fire("dom:loaded"); + document.loaded = true; + } + + if (document.addEventListener) { + if (Prototype.Browser.WebKit) { + timer = window.setInterval(function() { + if (/loaded|complete/.test(document.readyState)) + fireContentLoadedEvent(); + }, 0); + + Event.observe(window, "load", fireContentLoadedEvent); + + } else { + document.addEventListener("DOMContentLoaded", + fireContentLoadedEvent, false); + } + + } else { + document.write(" + + + + + + +

    Stock Prices

    + + + + + + + diff --git a/vendor/gems/erubis-2.6.5/benchmark/templates/bench_erb.rhtml b/vendor/gems/erubis-2.6.5/benchmark/templates/bench_erb.rhtml new file mode 100644 index 0000000..3dde9d5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/benchmark/templates/bench_erb.rhtml @@ -0,0 +1,29 @@ + +<% +n = 0 +for item in list + n += 1 + %> + + + + + +<% if item['change'] < 0.0 %> + + +<% else %> + + +<% end %> + +<% +end + %> + diff --git a/vendor/gems/erubis-2.6.5/benchmark/templates/bench_erubis.rhtml b/vendor/gems/erubis-2.6.5/benchmark/templates/bench_erubis.rhtml new file mode 100644 index 0000000..3dde9d5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/benchmark/templates/bench_erubis.rhtml @@ -0,0 +1,29 @@ + +<% +n = 0 +for item in list + n += 1 + %> + + + + + +<% if item['change'] < 0.0 %> + + +<% else %> + + +<% end %> + +<% +end + %> + diff --git a/vendor/gems/erubis-2.6.5/benchmark/templates/bench_eruby.rhtml b/vendor/gems/erubis-2.6.5/benchmark/templates/bench_eruby.rhtml new file mode 100644 index 0000000..3dde9d5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/benchmark/templates/bench_eruby.rhtml @@ -0,0 +1,29 @@ + +<% +n = 0 +for item in list + n += 1 + %> + + + + + +<% if item['change'] < 0.0 %> + + +<% else %> + + +<% end %> + +<% +end + %> + diff --git a/vendor/gems/erubis-2.6.5/bin/erubis b/vendor/gems/erubis-2.6.5/bin/erubis new file mode 100755 index 0000000..f5a16a0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/bin/erubis @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby + +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require 'erubis/main' + +Erubis::Main.main(ARGV) diff --git a/vendor/gems/erubis-2.6.5/contrib/erubis b/vendor/gems/erubis-2.6.5/contrib/erubis new file mode 100755 index 0000000..fd0810e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/contrib/erubis @@ -0,0 +1,3330 @@ +#!/usr/bin/env ruby + +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +#--begin of require 'erubis/main' +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require 'yaml' +#--begin of require 'erubis' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +## +## an implementation of eRuby +## +## ex. +## input = <<'END' +##
      +## <% for item in @list %> +##
    • <%= item %> +## <%== item %>
    • +## <% end %> +##
    +## END +## list = ['', 'b&b', '"ccc"'] +## eruby = Erubis::Eruby.new(input) +## puts "--- code ---" +## puts eruby.src +## puts "--- result ---" +## context = Erubis::Context.new() # or new(:list=>list) +## context[:list] = list +## puts eruby.evaluate(context) +## +## result: +## --- source --- +## _buf = ''; _buf << '
      +## '; for item in @list +## _buf << '
    • '; _buf << ( item ).to_s; _buf << ' +## '; _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
    • +## '; end +## _buf << '
    +## '; +## _buf.to_s +## --- result --- +##
      +##
    • +## <aaa>
    • +##
    • b&b +## b&b
    • +##
    • "ccc" +## "ccc"
    • +##
    +## + + +module Erubis + VERSION = ('$Release: 2.6.5 $' =~ /([.\d]+)/) && $1 +end + +#--begin of require 'erubis/engine' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +#--begin of require 'erubis/generator' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--begin of require 'abstract' +## +## $Rev: 1 $ +## $Release: 0.1.0 $ +## copyright(c) 2006 kuwata-lab.com all rights reserved. +## +## +## helper to define abstract method in Ruby. +## +## +## example1. (shorter notation) +## +## require 'abstract' +## class Foo +## abstract_method 'arg1, arg2=""', :method1, :method2, :method3 +## end +## +## +## example2. (RDoc friendly notation) +## +## require 'abstract' +## class Bar +## # ... method1 description ... +## def method1(arg1, arg2="") +## not_implemented +## end +## +## # ... method2 description ... +## def method2(arg1, arg2="") +## not_implemented +## end +## end +## + + +## +class Module + + ## + ## define abstract methods + ## + def abstract_method args_str, *method_names + method_names.each do |name| + module_eval <<-END + def #{name}(#{args_str}) + mesg = "class \#{self.class.name} must implement abstract method `#{self.name}##{name}()'." + #mesg = "\#{self.class.name}##{name}() is not implemented." + err = NotImplementedError.new mesg + err.set_backtrace caller() + raise err + end + END + end + end + +end + + +## +module Kernel + + ## + ## raise NotImplementedError + ## + def not_implemented #:doc: + backtrace = caller() + method_name = (backtrace.shift =~ /`(\w+)'$/) && $1 + mesg = "class #{self.class.name} must implement abstract method '#{method_name}()'." + #mesg = "#{self.class.name}##{method_name}() is not implemented." + err = NotImplementedError.new mesg + err.set_backtrace backtrace + raise err + end + private :not_implemented + +end +#--end of require 'abstract' + +module Erubis + + + ## + ## code generator, called by Converter module + ## + module Generator + + def self.supported_properties() # :nodoc: + return [ + [:escapefunc, nil, "escape function name"], + ] + end + + attr_accessor :escapefunc + + def init_generator(properties={}) + @escapefunc = properties[:escapefunc] + end + + + ## (abstract) escape text string + ## + ## ex. + ## def escape_text(text) + ## return text.dump + ## # or return "'" + text.gsub(/['\\]/, '\\\\\&') + "'" + ## end + def escape_text(text) + not_implemented + end + + ## return escaped expression code (ex. 'h(...)' or 'htmlspecialchars(...)') + def escaped_expr(code) + code.strip! + return "#{@escapefunc}(#{code})" + end + + ## (abstract) add @preamble to src + def add_preamble(src) + not_implemented + end + + ## (abstract) add text string to src + def add_text(src, text) + not_implemented + end + + ## (abstract) add statement code to src + def add_stmt(src, code) + not_implemented + end + + ## (abstract) add expression literal code to src. this is called by add_expr(). + def add_expr_literal(src, code) + not_implemented + end + + ## (abstract) add escaped expression code to src. this is called by add_expr(). + def add_expr_escaped(src, code) + not_implemented + end + + ## (abstract) add expression code to src for debug. this is called by add_expr(). + def add_expr_debug(src, code) + not_implemented + end + + ## (abstract) add @postamble to src + def add_postamble(src) + not_implemented + end + + + end + + +end +#--end of require 'erubis/generator' +#--begin of require 'erubis/converter' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'abstract' + +module Erubis + + + ## + ## convert + ## + module Converter + + attr_accessor :preamble, :postamble, :escape + + def self.supported_properties # :nodoc: + return [ + [:preamble, nil, "preamble (no preamble when false)"], + [:postamble, nil, "postamble (no postamble when false)"], + [:escape, nil, "escape expression or not in default"], + ] + end + + def init_converter(properties={}) + @preamble = properties[:preamble] + @postamble = properties[:postamble] + @escape = properties[:escape] + end + + ## convert input string into target language + def convert(input) + codebuf = "" # or [] + @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble)) + convert_input(codebuf, input) + @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble)) + @_proc = nil # clear cached proc object + return codebuf # or codebuf.join() + end + + protected + + ## + ## detect spaces at beginning of line + ## + def detect_spaces_at_bol(text, is_bol) + lspace = nil + if text.empty? + lspace = "" if is_bol + elsif text[-1] == ?\n + lspace = "" + else + rindex = text.rindex(?\n) + if rindex + s = text[rindex+1..-1] + if s =~ /\A[ \t]*\z/ + lspace = s + #text = text[0..rindex] + text[rindex+1..-1] = '' + end + else + if is_bol && text =~ /\A[ \t]*\z/ + #lspace = text + #text = nil + lspace = text.dup + text[0..-1] = '' + end + end + end + return lspace + end + + ## + ## (abstract) convert input to code + ## + def convert_input(codebuf, input) + not_implemented + end + + end + + + module Basic + end + + + ## + ## basic converter which supports '<% ... %>' notation. + ## + module Basic::Converter + include Erubis::Converter + + def self.supported_properties # :nodoc: + return [ + [:pattern, '<% %>', "embed pattern"], + [:trim, true, "trim spaces around <% ... %>"], + ] + end + + attr_accessor :pattern, :trim + + def init_converter(properties={}) + super(properties) + @pattern = properties[:pattern] + @trim = properties[:trim] != false + end + + protected + + ## return regexp of pattern to parse eRuby script + def pattern_regexp(pattern) + @prefix, @postfix = pattern.split() # '<% %>' => '<%', '%>' + #return /(.*?)(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m + #return /(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m + return /#{@prefix}(=+|-|\#|%)?(.*?)([-=])?#{@postfix}([ \t]*\r?\n)?/m + end + module_function :pattern_regexp + + #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + #DEFAULT_REGEXP = /<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + DEFAULT_REGEXP = pattern_regexp('<% %>') + + public + + def convert_input(src, input) + pat = @pattern + regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat) + pos = 0 + is_bol = true # is beginning of line + input.scan(regexp) do |indicator, code, tailch, rspace| + match = Regexp.last_match() + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + ch = indicator ? indicator[0] : nil + lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol) + is_bol = rspace ? true : false + add_text(src, text) if text && !text.empty? + ## * when '<%= %>', do nothing + ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>' + if ch == ?= # <%= %> + rspace = nil if tailch && !tailch.empty? + add_text(src, lspace) if lspace + add_expr(src, code, indicator) + add_text(src, rspace) if rspace + elsif ch == ?\# # <%# %> + n = code.count("\n") + (rspace ? 1 : 0) + if @trim && lspace && rspace + add_stmt(src, "\n" * n) + else + add_text(src, lspace) if lspace + add_stmt(src, "\n" * n) + add_text(src, rspace) if rspace + end + elsif ch == ?% # <%% %> + s = "#{lspace}#{@prefix||='<%'}#{code}#{tailch}#{@postfix||='%>'}#{rspace}" + add_text(src, s) + else # <% %> + if @trim && lspace && rspace + add_stmt(src, "#{lspace}#{code}#{rspace}") + else + add_text(src, lspace) if lspace + add_stmt(src, code) + add_text(src, rspace) if rspace + end + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + add_text(src, rest) + end + + ## add expression code to src + def add_expr(src, code, indicator) + case indicator + when '=' + @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code) + when '==' + @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code) + when '===' + add_expr_debug(src, code) + end + end + + end + + + module PI + end + + ## + ## Processing Instructions (PI) converter for XML. + ## this class converts '' and '${...}' notation. + ## + module PI::Converter + include Erubis::Converter + + def self.desc # :nodoc: + "use processing instructions (PI) instead of '<% %>'" + end + + def self.supported_properties # :nodoc: + return [ + [:trim, true, "trim spaces around <% ... %>"], + [:pi, 'rb', "PI (Processing Instrunctions) name"], + [:embchar, '@', "char for embedded expression pattern('@{...}@')"], + [:pattern, '<% %>', "embed pattern"], + ] + end + + attr_accessor :pi, :prefix + + def init_converter(properties={}) + super(properties) + @trim = properties.fetch(:trim, true) + @pi = properties[:pi] if properties[:pi] + @embchar = properties[:embchar] || '@' + @pattern = properties[:pattern] + @pattern = '<% %>' if @pattern.nil? #|| @pattern == true + end + + def convert(input) + code = super(input) + return @header || @footer ? "#{@header}#{code}#{@footer}" : code + end + + protected + + def convert_input(codebuf, input) + unless @regexp + @pi ||= 'e' + ch = Regexp.escape(@embchar) + if @pattern + left, right = @pattern.split(' ') + @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/m + else + @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}/m + end + end + # + is_bol = true + pos = 0 + input.scan(@regexp) do |pi_arg, stmt, rspace, + indicator1, expr1, indicator2, expr2| + match = Regexp.last_match + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + lspace = stmt ? detect_spaces_at_bol(text, is_bol) : nil + is_bol = stmt && rspace ? true : false + add_text(codebuf, text) # unless text.empty? + # + if stmt + if @trim && lspace && rspace + add_pi_stmt(codebuf, "#{lspace}#{stmt}#{rspace}", pi_arg) + else + add_text(codebuf, lspace) if lspace + add_pi_stmt(codebuf, stmt, pi_arg) + add_text(codebuf, rspace) if rspace + end + else + add_pi_expr(codebuf, expr1 || expr2, indicator1 || indicator2) + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + add_text(codebuf, rest) + end + + #-- + #def convert_input(codebuf, input) + # parse_stmts(codebuf, input) + # #parse_stmts2(codebuf, input) + #end + # + #def parse_stmts(codebuf, input) + # #regexp = pattern_regexp(@pattern) + # @pi ||= 'e' + # @stmt_pattern ||= /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?/m + # is_bol = true + # pos = 0 + # input.scan(@stmt_pattern) do |pi_arg, code, rspace| + # match = Regexp.last_match + # len = match.begin(0) - pos + # text = input[pos, len] + # pos = match.end(0) + # lspace = detect_spaces_at_bol(text, is_bol) + # is_bol = rspace ? true : false + # parse_exprs(codebuf, text) # unless text.empty? + # if @trim && lspace && rspace + # add_pi_stmt(codebuf, "#{lspace}#{code}#{rspace}", pi_arg) + # else + # add_text(codebuf, lspace) + # add_pi_stmt(codebuf, code, pi_arg) + # add_text(codebuf, rspace) + # end + # end + # rest = $' || input + # parse_exprs(codebuf, rest) + #end + # + #def parse_exprs(codebuf, input) + # unless @expr_pattern + # ch = Regexp.escape(@embchar) + # if @pattern + # left, right = @pattern.split(' ') + # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/ + # else + # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}/ + # end + # end + # pos = 0 + # input.scan(@expr_pattern) do |indicator1, code1, indicator2, code2| + # indicator = indicator1 || indicator2 + # code = code1 || code2 + # match = Regexp.last_match + # len = match.begin(0) - pos + # text = input[pos, len] + # pos = match.end(0) + # add_text(codebuf, text) # unless text.empty? + # add_pi_expr(codebuf, code, indicator) + # end + # rest = $' || input + # add_text(codebuf, rest) + #end + #++ + + def add_pi_stmt(codebuf, code, pi_arg) # :nodoc: + case pi_arg + when nil ; add_stmt(codebuf, code) + when 'header' ; @header = code + when 'footer' ; @footer = code + when 'comment'; add_stmt(codebuf, "\n" * code.count("\n")) + when 'value' ; add_expr_literal(codebuf, code) + else ; add_stmt(codebuf, code) + end + end + + def add_pi_expr(codebuf, code, indicator) # :nodoc: + case indicator + when nil, '', '==' # @{...}@ or <%== ... %> + @escape == false ? add_expr_literal(codebuf, code) : add_expr_escaped(codebuf, code) + when '!', '=' # @!{...}@ or <%= ... %> + @escape == false ? add_expr_escaped(codebuf, code) : add_expr_literal(codebuf, code) + when '!!', '===' # @!!{...}@ or <%=== ... %> + add_expr_debug(codebuf, code) + else + # ignore + end + end + + end + + +end +#--end of require 'erubis/converter' +#--begin of require 'erubis/evaluator' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--begin of require 'erubis/error' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +module Erubis + + + ## + ## base error class + ## + class ErubisError < StandardError + end + + + ## + ## raised when method or function is not supported + ## + class NotSupportedError < ErubisError + end + + +end +#--end of require 'erubis/error' +#--begin of require 'erubis/context' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +module Erubis + + + ## + ## context object for Engine#evaluate + ## + ## ex. + ## template = <<'END' + ## Hello <%= @user %>! + ## <% for item in @list %> + ## - <%= item %> + ## <% end %> + ## END + ## + ## context = Erubis::Context.new(:user=>'World', :list=>['a','b','c']) + ## # or + ## # context = Erubis::Context.new + ## # context[:user] = 'World' + ## # context[:list] = ['a', 'b', 'c'] + ## + ## eruby = Erubis::Eruby.new(template) + ## print eruby.evaluate(context) + ## + class Context + include Enumerable + + def initialize(hash=nil) + hash.each do |name, value| + self[name] = value + end if hash + end + + def [](key) + return instance_variable_get("@#{key}") + end + + def []=(key, value) + return instance_variable_set("@#{key}", value) + end + + def keys + return instance_variables.collect { |name| name[1..-1] } + end + + def each + instance_variables.each do |name| + key = name[1..-1] + value = instance_variable_get(name) + yield(key, value) + end + end + + def to_hash + hash = {} + self.keys.each { |key| hash[key] = self[key] } + return hash + end + + def update(context_or_hash) + arg = context_or_hash + if arg.is_a?(Hash) + arg.each do |key, val| + self[key] = val + end + else + arg.instance_variables.each do |varname| + key = varname[1..-1] + val = arg.instance_variable_get(varname) + self[key] = val + end + end + end + + end + + +end +#--end of require 'erubis/context' + + +module Erubis + + EMPTY_BINDING = binding() + + + ## + ## evaluate code + ## + module Evaluator + + def self.supported_properties # :nodoc: + return [] + end + + attr_accessor :src, :filename + + def init_evaluator(properties) + @filename = properties[:filename] + end + + def result(*args) + raise NotSupportedError.new("evaluation of code except Ruby is not supported.") + end + + def evaluate(*args) + raise NotSupportedError.new("evaluation of code except Ruby is not supported.") + end + + end + + + ## + ## evaluator for Ruby + ## + module RubyEvaluator + include Evaluator + + def self.supported_properties # :nodoc: + list = Evaluator.supported_properties + return list + end + + ## eval(@src) with binding object + def result(_binding_or_hash=TOPLEVEL_BINDING) + _arg = _binding_or_hash + if _arg.is_a?(Hash) + _b = binding() + eval _arg.collect{|k,v| "#{k} = _arg[#{k.inspect}]; "}.join, _b + elsif _arg.is_a?(Binding) + _b = _arg + elsif _arg.nil? + _b = binding() + else + raise ArgumentError.new("#{self.class.name}#result(): argument should be Binding or Hash but passed #{_arg.class.name} object.") + end + return eval(@src, _b, (@filename || '(erubis')) + end + + ## invoke context.instance_eval(@src) + def evaluate(_context=Context.new) + _context = Context.new(_context) if _context.is_a?(Hash) + #return _context.instance_eval(@src, @filename || '(erubis)') + #@_proc ||= eval("proc { #{@src} }", Erubis::EMPTY_BINDING, @filename || '(erubis)') + @_proc ||= eval("proc { #{@src} }", binding(), @filename || '(erubis)') + return _context.instance_eval(&@_proc) + end + + ## if object is an Class or Module then define instance method to it, + ## else define singleton method to it. + def def_method(object, method_name, filename=nil) + m = object.is_a?(Module) ? :module_eval : :instance_eval + object.__send__(m, "def #{method_name}; #{@src}; end", filename || @filename || '(erubis)') + end + + + end + + +end +#--end of require 'erubis/evaluator' +#--already included require 'erubis/context' + + +module Erubis + + + ## + ## (abstract) abstract engine class. + ## subclass must include evaluator and converter module. + ## + class Engine + #include Evaluator + #include Converter + #include Generator + + def initialize(input=nil, properties={}) + #@input = input + init_generator(properties) + init_converter(properties) + init_evaluator(properties) + @src = convert(input) if input + end + + + ## + ## convert input string and set it to @src + ## + def convert!(input) + @src = convert(input) + end + + + ## + ## load file, write cache file, and return engine object. + ## this method create code cache file automatically. + ## cachefile name can be specified with properties[:cachename], + ## or filname + 'cache' is used as default. + ## + def self.load_file(filename, properties={}) + cachename = properties[:cachename] || (filename + '.cache') + properties[:filename] = filename + if test(?f, cachename) && File.mtime(filename) <= File.mtime(cachename) + engine = self.new(nil, properties) + engine.src = File.read(cachename) + else + input = File.open(filename, 'rb') {|f| f.read } + engine = self.new(input, properties) + File.open(cachename, 'wb') do |f| + f.flock(File::LOCK_EX) + f.write(engine.src) + f.flush() + end + end + engine.src.untaint # ok? + return engine + end + + + ## + ## helper method to convert and evaluate input text with context object. + ## context may be Binding, Hash, or Object. + ## + def process(input, context=nil, filename=nil) + code = convert(input) + filename ||= '(erubis)' + if context.is_a?(Binding) + return eval(code, context, filename) + else + context = Context.new(context) if context.is_a?(Hash) + return context.instance_eval(code, filename) + end + end + + + ## + ## helper method evaluate Proc object with contect object. + ## context may be Binding, Hash, or Object. + ## + def process_proc(proc_obj, context=nil, filename=nil) + if context.is_a?(Binding) + filename ||= '(erubis)' + return eval(proc_obj, context, filename) + else + context = Context.new(context) if context.is_a?(Hash) + return context.instance_eval(&proc_obj) + end + end + + + end # end of class Engine + + + ## + ## (abstract) base engine class for Eruby, Eperl, Ejava, and so on. + ## subclass must include generator. + ## + class Basic::Engine < Engine + include Evaluator + include Basic::Converter + include Generator + end + + + class PI::Engine < Engine + include Evaluator + include PI::Converter + include Generator + end + + +end +#--end of require 'erubis/engine' +#require 'erubis/generator' +#require 'erubis/converter' +#require 'erubis/evaluator' +#require 'erubis/error' +#require 'erubis/context' +#--begin of require 'erubis/helper' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +module Erubis + + ## + ## helper for xml + ## + module XmlHelper + + module_function + + ESCAPE_TABLE = { + '&' => '&', + '<' => '<', + '>' => '>', + '"' => '"', + "'" => ''', + } + + def escape_xml(value) + value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] } # or /[&<>"']/ + #value.to_s.gsub(/[&<>"]/) { ESCAPE_TABLE[$&] } + end + + def escape_xml2(value) + return value.to_s.gsub(/\&/,'&').gsub(//,'>').gsub(/"/,'"') + end + + alias h escape_xml + alias html_escape escape_xml + + def url_encode(str) + return str.gsub(/[^-_.a-zA-Z0-9]+/) { |s| + s.unpack('C*').collect { |i| "%%%02X" % i }.join + } + end + + alias u url_encode + + end + + +end +#--end of require 'erubis/helper' +#--begin of require 'erubis/enhancer' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +module Erubis + + + ## + ## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped + ## + ## ex. + ## class XmlEruby < Eruby + ## include EscapeEnhancer + ## end + ## + ## this is language-indenedent. + ## + module EscapeEnhancer + + def self.desc # :nodoc: + "switch '<%= %>' to escaped and '<%== %>' to unescaped" + end + + #-- + #def self.included(klass) + # klass.class_eval <<-END + # alias _add_expr_literal add_expr_literal + # alias _add_expr_escaped add_expr_escaped + # alias add_expr_literal _add_expr_escaped + # alias add_expr_escaped _add_expr_literal + # END + #end + #++ + + def add_expr(src, code, indicator) + case indicator + when '=' + @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code) + when '==' + @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code) + when '===' + add_expr_debug(src, code) + end + end + + end + + + #-- + ## (obsolete) + #module FastEnhancer + #end + #++ + + + ## + ## use $stdout instead of string + ## + ## this is only for Eruby. + ## + module StdoutEnhancer + + def self.desc # :nodoc: + "use $stdout instead of array buffer or string buffer" + end + + def add_preamble(src) + src << "_buf = $stdout;" + end + + def add_postamble(src) + src << "\n''\n" + end + + end + + + ## + ## use print statement instead of '_buf << ...' + ## + ## this is only for Eruby. + ## + module PrintOutEnhancer + + def self.desc # :nodoc: + "use print statement instead of '_buf << ...'" + end + + def add_preamble(src) + end + + def add_text(src, text) + src << " print '" << escape_text(text) << "';" unless text.empty? + end + + def add_expr_literal(src, code) + src << ' print((' << code << ').to_s);' + end + + def add_expr_escaped(src, code) + src << ' print ' << escaped_expr(code) << ';' + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + end + + end + + + ## + ## enable print function + ## + ## Notice: use Eruby#evaluate() and don't use Eruby#result() + ## to be enable print function. + ## + ## this is only for Eruby. + ## + module PrintEnabledEnhancer + + def self.desc # :nodoc: + "enable to use print function in '<% %>'" + end + + def add_preamble(src) + src << "@_buf = " + super + end + + def print(*args) + args.each do |arg| + @_buf << arg.to_s + end + end + + def evaluate(context=nil) + _src = @src + if context.is_a?(Hash) + context.each do |key, val| instance_variable_set("@#{key}", val) end + elsif context + context.instance_variables.each do |name| + instance_variable_set(name, context.instance_variable_get(name)) + end + end + return instance_eval(_src, (@filename || '(erubis)')) + end + + end + + + ## + ## return array instead of string + ## + ## this is only for Eruby. + ## + module ArrayEnhancer + + def self.desc # :nodoc: + "return array instead of string" + end + + def add_preamble(src) + src << "_buf = [];" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf\n" + end + + end + + + ## + ## use an Array object as buffer (included in Eruby by default) + ## + ## this is only for Eruby. + ## + module ArrayBufferEnhancer + + def self.desc # :nodoc: + "use an Array object for buffering (included in Eruby class)" + end + + def add_preamble(src) + src << "_buf = [];" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.join\n" + end + + end + + + ## + ## use String class for buffering + ## + ## this is only for Eruby. + ## + module StringBufferEnhancer + + def self.desc # :nodoc: + "use a String object for buffering" + end + + def add_preamble(src) + src << "_buf = '';" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.to_s\n" + end + + end + + + ## + ## use StringIO class for buffering + ## + ## this is only for Eruby. + ## + module StringIOEnhancer # :nodoc: + + def self.desc # :nodoc: + "use a StringIO object for buffering" + end + + def add_preamble(src) + src << "_buf = StringIO.new;" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.string\n" + end + + end + + + ## + ## set buffer variable name to '_erbout' as well as '_buf' + ## + ## this is only for Eruby. + ## + module ErboutEnhancer + + def self.desc # :nodoc: + "set '_erbout = _buf = \"\";' to be compatible with ERB." + end + + def add_preamble(src) + src << "_erbout = _buf = '';" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.to_s\n" + end + + end + + + ## + ## remove text and leave code, especially useful when debugging. + ## + ## ex. + ## $ erubis -s -E NoText file.eruby | more + ## + ## this is language independent. + ## + module NoTextEnhancer + + def self.desc # :nodoc: + "remove text and leave code (useful when debugging)" + end + + def add_text(src, text) + src << ("\n" * text.count("\n")) + if text[-1] != ?\n + text =~ /^(.*?)\z/ + src << (' ' * $1.length) + end + end + + end + + + ## + ## remove code and leave text, especially useful when validating HTML tags. + ## + ## ex. + ## $ erubis -s -E NoCode file.eruby | tidy -errors + ## + ## this is language independent. + ## + module NoCodeEnhancer + + def self.desc # :nodoc: + "remove code and leave text (useful when validating HTML)" + end + + def add_preamble(src) + end + + def add_postamble(src) + end + + def add_text(src, text) + src << text + end + + def add_expr(src, code, indicator) + src << "\n" * code.count("\n") + end + + def add_stmt(src, code) + src << "\n" * code.count("\n") + end + + end + + + ## + ## get convert faster, but spaces around '<%...%>' are not trimmed. + ## + ## this is language-independent. + ## + module SimplifyEnhancer + + def self.desc # :nodoc: + "get convert faster but leave spaces around '<% %>'" + end + + #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + SIMPLE_REGEXP = /<%(=+|\#)?(.*?)-?%>/m + + def convert(input) + src = "" + add_preamble(src) + #regexp = pattern_regexp(@pattern) + pos = 0 + input.scan(SIMPLE_REGEXP) do |indicator, code| + match = Regexp.last_match + index = match.begin(0) + text = input[pos, index - pos] + pos = match.end(0) + add_text(src, text) + if !indicator # <% %> + add_stmt(src, code) + elsif indicator[0] == ?\# # <%# %> + n = code.count("\n") + add_stmt(src, "\n" * n) + else # <%= %> + add_expr(src, code, indicator) + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + add_text(src, rest) + add_postamble(src) + return src + end + + end + + + ## + ## enable to use other embedded expression pattern (default is '\[= =\]'). + ## + ## notice! this is an experimental. spec may change in the future. + ## + ## ex. + ## input = < + ## <%= item %> : <%== item %> + ## [= item =] : [== item =] + ## <% end %> + ## END + ## + ## class BiPatternEruby + ## include BiPatternEnhancer + ## end + ## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]') + ## list = ['', 'b&b', '"c"'] + ## print eruby.result(binding()) + ## + ## ## output + ## : <a> + ## : <a> + ## b&b : b&b + ## b&b : b&b + ## "c" : "c" + ## "c" : "c" + ## + ## this is language independent. + ## + module BiPatternEnhancer + + def self.desc # :nodoc: + "another embedded expression pattern (default '\[= =\]')." + end + + def initialize(input, properties={}) + self.bipattern = properties[:bipattern] # or '\$\{ \}' + super + end + + ## when pat is nil then '\[= =\]' is used + def bipattern=(pat) # :nodoc: + @bipattern = pat || '\[= =\]' + pre, post = @bipattern.split() + @bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m + end + + def add_text(src, text) + return unless text + m = nil + text.scan(@bipattern_regexp) do |txt, indicator, code| + m = Regexp.last_match + super(src, txt) + add_expr(src, code, '=' + indicator) + end + #rest = $' || text # ruby1.8 + rest = m ? text[m.end(0)..-1] : text # ruby1.9 + super(src, rest) + end + + end + + + ## + ## regards lines starting with '%' as program code + ## + ## this is for compatibility to eruby and ERB. + ## + ## this is language-independent. + ## + module PercentLineEnhancer + + def self.desc # :nodoc: + "regard lines starting with '%' as program code" + end + + def add_text(src, text) + pos = 0 + text2 = '' + text.scan(/^\%(.*?\r?\n)/) do + line = $1 + match = Regexp.last_match + len = match.begin(0) - pos + str = text[pos, len] + pos = match.end(0) + if text2.empty? + text2 = str + else + text2 << str + end + if line[0] == ?% + text2 << line + else + super(src, text2) + text2 = '' + add_stmt(src, line) + end + end + #rest = pos == 0 ? text : $' # ruby1.8 + rest = pos == 0 ? text : text[pos..-1] # ruby1.9 + unless text2.empty? + text2 << rest if rest + rest = text2 + end + super(src, rest) + end + + end + + + ## + ## [experimental] allow header and footer in eRuby script + ## + ## ex. + ## ==================== + ## ## without header and footer + ## $ cat ex1.eruby + ## <% def list_items(list) %> + ## <% for item in list %> + ##
  • <%= item %>
  • + ## <% end %> + ## <% end %> + ## + ## $ erubis -s ex1.eruby + ## _buf = []; def list_items(list) + ## ; for item in list + ## ; _buf << '
  • '; _buf << ( item ).to_s; _buf << '
  • + ## '; end + ## ; end + ## ; + ## _buf.join + ## + ## ## with header and footer + ## $ cat ex2.eruby + ## + ## <% for item in list %> + ##
  • <%= item %>
  • + ## <% end %> + ## + ## + ## $ erubis -s -c HeaderFooterEruby ex4.eruby + ## + ## def list_items(list) + ## _buf = []; _buf << ' + ## '; for item in list + ## ; _buf << '
  • '; _buf << ( item ).to_s; _buf << '
  • + ## '; end + ## ; _buf << ' + ## '; + ## _buf.join + ## end + ## + ## ==================== + ## + ## this is language-independent. + ## + module HeaderFooterEnhancer + + def self.desc # :nodoc: + "allow header/footer in document (ex. '')" + end + + HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?([ \t]*\r?\n)?/m + + def add_text(src, text) + m = nil + text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace| + m = Regexp.last_match + flag_trim = @trim && lspace && rspace + super(src, txt) + content = "#{lspace}#{content}#{rspace}" if flag_trim + super(src, lspace) if !flag_trim && lspace + instance_variable_set("@#{word}", content) + super(src, rspace) if !flag_trim && rspace + end + #rest = $' || text # ruby1.8 + rest = m ? text[m.end(0)..-1] : text # ruby1.9 + super(src, rest) + end + + attr_accessor :header, :footer + + def convert(input) + source = super + return @src = "#{@header}#{source}#{@footer}" + end + + end + + + ## + ## delete indentation of HTML. + ## + ## this is language-independent. + ## + module DeleteIndentEnhancer + + def self.desc # :nodoc: + "delete indentation of HTML." + end + + def convert_input(src, input) + input = input.gsub(/^[ \t]+<%=title%>" into "_buf << %Q`

    #{title}

    `" + ## + ## this is only for Eruby. + ## + module InterpolationEnhancer + + def self.desc # :nodoc: + "convert '

    <%=text%>

    ' into '_buf << %Q`

    \#{text}

    `'" + end + + def convert_input(src, input) + pat = @pattern + regexp = pat.nil? || pat == '<% %>' ? Basic::Converter::DEFAULT_REGEXP : pattern_regexp(pat) + pos = 0 + is_bol = true # is beginning of line + str = '' + input.scan(regexp) do |indicator, code, tailch, rspace| + match = Regexp.last_match() + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + ch = indicator ? indicator[0] : nil + lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol) + is_bol = rspace ? true : false + _add_text_to_str(str, text) + ## * when '<%= %>', do nothing + ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>' + if ch == ?= # <%= %> + rspace = nil if tailch && !tailch.empty? + str << lspace if lspace + add_expr(str, code, indicator) + str << rspace if rspace + elsif ch == ?\# # <%# %> + n = code.count("\n") + (rspace ? 1 : 0) + if @trim && lspace && rspace + add_text(src, str) + str = '' + add_stmt(src, "\n" * n) + else + str << lspace if lspace + add_text(src, str) + str = '' + add_stmt(src, "\n" * n) + str << rspace if rspace + end + else # <% %> + if @trim && lspace && rspace + add_text(src, str) + str = '' + add_stmt(src, "#{lspace}#{code}#{rspace}") + else + str << lspace if lspace + add_text(src, str) + str = '' + add_stmt(src, code) + str << rspace if rspace + end + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + _add_text_to_str(str, rest) + add_text(src, str) + end + + def add_text(src, text) + return if !text || text.empty? + #src << " _buf << %Q`" << text << "`;" + if text[-1] == ?\n + text[-1] = "\\n" + src << " _buf << %Q`" << text << "`\n" + else + src << " _buf << %Q`" << text << "`;" + end + end + + def _add_text_to_str(str, text) + return if !text || text.empty? + text.gsub!(/['\#\\]/, '\\\\\&') + str << text + end + + def add_expr_escaped(str, code) + str << "\#{#{escaped_expr(code)}}" + end + + def add_expr_literal(str, code) + str << "\#{#{code}}" + end + + end + + +end +#--end of require 'erubis/enhancer' +#require 'erubis/tiny' +#--begin of require 'erubis/engine/eruby' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + ## + ## code generator for Ruby + ## + module RubyGenerator + include Generator + #include ArrayBufferEnhancer + include StringBufferEnhancer + + def init_generator(properties={}) + super + @escapefunc ||= "Erubis::XmlHelper.escape_xml" + end + + def self.supported_properties() # :nodoc: + return [] + end + + def escape_text(text) + text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\' + end + + def escaped_expr(code) + return "#{@escapefunc}(#{code})" + end + + #-- + #def add_preamble(src) + # src << "_buf = [];" + #end + #++ + + def add_text(src, text) + src << " _buf << '" << escape_text(text) << "';" unless text.empty? + end + + def add_stmt(src, code) + #src << code << ';' + src << code + src << ';' unless code[-1] == ?\n + end + + def add_expr_literal(src, code) + src << ' _buf << (' << code << ').to_s;' + end + + def add_expr_escaped(src, code) + src << ' _buf << ' << escaped_expr(code) << ';' + end + + def add_expr_debug(src, code) + code.strip! + s = (code.dump =~ /\A"(.*)"\z/) && $1 + src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");' + end + + #-- + #def add_postamble(src) + # src << "\n_buf.join\n" + #end + #++ + + end + + + ## + ## engine for Ruby + ## + class Eruby < Basic::Engine + include RubyEvaluator + include RubyGenerator + end + + + ## + ## fast engine for Ruby + ## + class FastEruby < Eruby + include InterpolationEnhancer + end + + + ## + ## swtich '<%= %>' to escaped and '<%== %>' to not escaped + ## + class EscapedEruby < Eruby + include EscapeEnhancer + end + + + ## + ## sanitize expression (<%= ... %>) by default + ## + ## this is equivalent to EscapedEruby and is prepared only for compatibility. + ## + class XmlEruby < Eruby + include EscapeEnhancer + end + + + class PI::Eruby < PI::Engine + include RubyEvaluator + include RubyGenerator + + def init_converter(properties={}) + @pi = 'rb' + super(properties) + end + + end + + +end +#--end of require 'erubis/engine/eruby' +#require 'erubis/engine/enhanced' # enhanced eruby engines +#require 'erubis/engine/optimized' # generates optimized ruby code +#require 'erubis/engine/ephp' +#require 'erubis/engine/ec' +#require 'erubis/engine/ejava' +#require 'erubis/engine/escheme' +#require 'erubis/engine/eperl' +#require 'erubis/engine/ejavascript' + +#--begin of require 'erubis/local-setting' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +## +## you can add site-local settings here. +## this files is required by erubis.rb +## +#--end of require 'erubis/local-setting' +#--end of require 'erubis' +#--begin of require 'erubis/tiny' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +module Erubis + + ## + ## tiny and the simplest implementation of eRuby + ## + ## ex. + ## eruby = TinyEruby.new(File.read('example.rhtml')) + ## print eruby.src # print ruby code + ## print eruby.result(binding()) # eval ruby code with Binding object + ## print eruby.evalute(context) # eval ruby code with context object + ## + class TinyEruby + + def initialize(input=nil) + @src = convert(input) if input + end + attr_reader :src + + EMBEDDED_PATTERN = /<%(=+|\#)?(.*?)-?%>/m + + def convert(input) + src = "_buf = '';" # preamble + pos = 0 + input.scan(EMBEDDED_PATTERN) do |indicator, code| + m = Regexp.last_match + text = input[pos...m.begin(0)] + pos = m.end(0) + #src << " _buf << '" << escape_text(text) << "';" + text.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << text << "';" unless text.empty? + if !indicator # <% %> + src << code << ";" + elsif indicator == '#' # <%# %> + src << ("\n" * code.count("\n")) + else # <%= %> + src << " _buf << (" << code << ").to_s;" + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + #src << " _buf << '" << escape_text(rest) << "';" + rest.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << rest << "';" unless rest.empty? + src << "\n_buf.to_s\n" # postamble + return src + end + + #def escape_text(text) + # return text.gsub!(/['\\]/, '\\\\\&') || text + #end + + def result(_binding=TOPLEVEL_BINDING) + eval @src, _binding + end + + def evaluate(_context=Object.new) + if _context.is_a?(Hash) + _obj = Object.new + _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end + _context = _obj + end + _context.instance_eval @src + end + + end + + + + module PI + end + + class PI::TinyEruby + + def initialize(input=nil, options={}) + @escape = options[:escape] || 'Erubis::XmlHelper.escape_xml' + @src = convert(input) if input + end + + attr_reader :src + + EMBEDDED_PATTERN = /(^[ \t]*)?<\?rb(\s.*?)\?>([ \t]*\r?\n)?|@(!+)?\{(.*?)\}@/m + + def convert(input) + src = "_buf = '';" # preamble + pos = 0 + input.scan(EMBEDDED_PATTERN) do |lspace, stmt, rspace, indicator, expr| + match = Regexp.last_match + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + #src << " _buf << '" << escape_text(text) << "';" + text.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << text << "';" unless text.empty? + if stmt # + if lspace && rspace + src << "#{lspace}#{stmt}#{rspace}" + else + src << " _buf << '" << lspace << "';" if lspace + src << stmt << ";" + src << " _buf << '" << rspace << "';" if rspace + end + else # ${...}, $!{...} + if !indicator + src << " _buf << " << @escape << "(" << expr << ");" + elsif indicator == '!' + src << " _buf << (" << expr << ").to_s;" + end + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + #src << " _buf << '" << escape_text(rest) << "';" + rest.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << rest << "';" unless rest.empty? + src << "\n_buf.to_s\n" # postamble + return src + end + + #def escape_text(text) + # return text.gsub!(/['\\]/, '\\\\\&') || text + #end + + def result(_binding=TOPLEVEL_BINDING) + eval @src, _binding + end + + def evaluate(_context=Object.new) + if _context.is_a?(Hash) + _obj = Object.new + _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end + _context = _obj + end + _context.instance_eval @src + end + + end + + +end +#--end of require 'erubis/tiny' +#--begin of require 'erubis/engine/enhanced' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/enhancer' +#--already included require 'erubis/engine/eruby' + + +module Erubis + + + #-- + ## moved to engine/ruby.rb + #class EscapedEruby < Eruby + # include EscapeEnhancer + #end + #++ + + + #-- + ### (obsolete) + #class FastEruby < Eruby + # include FastEnhancer + #end + #++ + + + class StdoutEruby < Eruby + include StdoutEnhancer + end + + + class PrintOutEruby < Eruby + include PrintOutEnhancer + end + + + class PrintEnabledEruby < Eruby + include PrintEnabledEnhancer + end + + + class ArrayEruby < Eruby + include ArrayEnhancer + end + + + class ArrayBufferEruby < Eruby + include ArrayBufferEnhancer + end + + + class StringBufferEruby < Eruby + include StringBufferEnhancer + end + + + class StringIOEruby < Eruby + include StringIOEnhancer + end + + + class ErboutEruby < Eruby + include ErboutEnhancer + end + + + class NoTextEruby < Eruby + include NoTextEnhancer + end + + + class NoCodeEruby < Eruby + include NoCodeEnhancer + end + + + class SimplifiedEruby < Eruby + include SimplifyEnhancer + end + + + class StdoutSimplifiedEruby < Eruby + include StdoutEnhancer + include SimplifyEnhancer + end + + + class PrintOutSimplifiedEruby < Eruby + include PrintOutEnhancer + include SimplifyEnhancer + end + + + class BiPatternEruby < Eruby + include BiPatternEnhancer + end + + + class PercentLineEruby < Eruby + include PercentLineEnhancer + end + + + class HeaderFooterEruby < Eruby + include HeaderFooterEnhancer + end + + + class DeleteIndentEruby < Eruby + include DeleteIndentEnhancer + end + + + class InterpolationEruby < Eruby + include InterpolationEnhancer + end + + +end +#--end of require 'erubis/engine/enhanced' +#--begin of require 'erubis/engine/optimized' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +#--already included require 'erubis/engine/eruby' + + +module Erubis + + + module OptimizedGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [] + end + + def init_generator(properties={}) + super + @escapefunc ||= "Erubis::XmlHelper.escape_xml" + @initialized = false + @prev_is_expr = false + end + + protected + + def escape_text(text) + text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\' + end + + def escaped_expr(code) + @escapefunc ||= 'Erubis::XmlHelper.escape_xml' + return "#{@escapefunc}(#{code})" + end + + def switch_to_expr(src) + return if @prev_is_expr + @prev_is_expr = true + src << ' _buf' + end + + def switch_to_stmt(src) + return unless @prev_is_expr + @prev_is_expr = false + src << ';' + end + + def add_preamble(src) + #@initialized = false + #@prev_is_expr = false + end + + def add_text(src, text) + return if text.empty? + if @initialized + switch_to_expr(src) + src << " << '" << escape_text(text) << "'" + else + src << "_buf = '" << escape_text(text) << "';" + @initialized = true + end + end + + def add_stmt(src, code) + switch_to_stmt(src) if @initialized + #super + src << code + src << ';' unless code[-1] == ?\n + end + + def add_expr_literal(src, code) + unless @initialized; src << "_buf = ''"; @initialized = true; end + switch_to_expr(src) + src << " << (" << code << ").to_s" + end + + def add_expr_escaped(src, code) + unless @initialized; src << "_buf = ''"; @initialized = true; end + switch_to_expr(src) + src << " << " << escaped_expr(code) + end + + def add_expr_debug(src, code) + code.strip! + s = (code.dump =~ /\A"(.*)"\z/) && $1 + src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");' + end + + def add_postamble(src) + #super if @initialized + src << "\n_buf\n" if @initialized + end + + end # end of class OptimizedEruby + + + ## + ## Eruby class which generates optimized ruby code + ## + class OptimizedEruby < Basic::Engine # Eruby + include RubyEvaluator + include OptimizedGenerator + + def init_converter(properties={}) + @pi = 'rb' + super(properties) + end + + end + + + ## + ## XmlEruby class which generates optimized ruby code + ## + class OptimizedXmlEruby < OptimizedEruby + include EscapeEnhancer + + def add_expr_debug(src, code) + switch_to_stmt(src) if indicator == '===' && !@initialized + super + end + + end # end of class OptimizedXmlEruby + +end +#--end of require 'erubis/engine/optimized' +#--already included require 'erubis/engine/eruby' +#--begin of require 'erubis/engine/ephp' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + module PhpGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'htmlspecialchars' + end + + def add_preamble(src) + # empty + end + + def escape_text(text) + return text.gsub!(/<\?xml\b/, '<?xml') || text + end + + def add_text(src, text) + src << escape_text(text) + end + + def add_expr_literal(src, code) + code.strip! + src << "" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + code.strip! + s = code.gsub(/\'/, "\\'") + src << "" + end + + def add_stmt(src, code) + src << "\n" + else + src << code << "?>" + end + end + + def add_postamble(src) + # empty + end + + end + + + ## + ## engine for PHP + ## + class Ephp < Basic::Engine + include PhpGenerator + end + + + class EscapedEphp < Ephp + include EscapeEnhancer + end + + + #class XmlEphp < Ephp + # include EscapeEnhancer + #end + + + class PI::Ephp < PI::Engine + include PhpGenerator + + def init_converter(properties={}) + @pi = 'php' + super(properties) + end + + end + + +end +#--end of require 'erubis/engine/ephp' +#--begin of require 'erubis/engine/ec' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + module CGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:indent, '', "indent spaces (ex. ' ')"], + [:out, 'stdout', "output file pointer name"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= "escape" + @indent = properties[:indent] || '' + @out = properties[:out] || 'stdout' + end + + def add_preamble(src) + src << "#line 1 \"#{self.filename}\"\n" if self.filename + end + + def escape_text(text) + @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" } + text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } + return text + end + + def escaped_expr(code) + return "#{@escapefunc}(#{code.strip}, #{@out})" + end + + def add_text(src, text) + return if text.empty? + src << (src.empty? || src[-1] == ?\n ? @indent : ' ') + src << "fputs(" + i = 0 + text.each_line do |line| + src << "\n" << @indent << ' ' if i > 0 + i += 1 + src << '"' << escape_text(line) << '"' + end + src << ", #{@out});" #<< (text[-1] == ?\n ? "\n" : "") + src << "\n" if text[-1] == ?\n + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + src << @indent if src.empty? || src[-1] == ?\n + src << " fprintf(#{@out}, " << code.strip << ');' + end + + def add_expr_escaped(src, code) + src << @indent if src.empty? || src[-1] == ?\n + src << ' ' << escaped_expr(code) << ';' + end + + def add_expr_debug(src, code) + code.strip! + s = nil + if code =~ /\A\".*?\"\s*,\s*(.*)/ + s = $1.gsub(/[%"]/, '\\\1') + '=' + end + src << @indent if src.empty? || src[-1] == ?\n + src << " fprintf(stderr, \"*** debug: #{s}\" #{code});" + end + + def add_postamble(src) + # empty + end + + end + + + ## + ## engine for C + ## + class Ec < Basic::Engine + include CGenerator + end + + + class EscapedEc < Ec + include EscapeEnhancer + end + + + #class XmlEc < Ec + # include EscapeEnhancer + #end + + class PI::Ec < PI::Engine + include CGenerator + + def init_converter(properties={}) + @pi = 'c' + super(properties) + end + + end + + +end +#--end of require 'erubis/engine/ec' +#--begin of require 'erubis/engine/ejava' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + module JavaGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:indent, '', "indent spaces (ex. ' ')"], + [:buf, '_buf', "output buffer name"], + [:bufclass, 'StringBuffer', "output buffer class (ex. 'StringBuilder')"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'escape' + @indent = properties[:indent] || '' + @buf = properties[:buf] || '_buf' + @bufclass = properties[:bufclass] || 'StringBuffer' + end + + def add_preamble(src) + src << "#{@indent}#{@bufclass} #{@buf} = new #{@bufclass}();" + end + + def escape_text(text) + @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" } + return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text + end + + def add_text(src, text) + return if text.empty? + src << (src.empty? || src[-1] == ?\n ? @indent : ' ') + src << @buf << ".append(" + i = 0 + text.each_line do |line| + src << "\n" << @indent << ' + ' if i > 0 + i += 1 + src << '"' << escape_text(line) << '"' + end + src << ");" << (text[-1] == ?\n ? "\n" : "") + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + src << @indent if src.empty? || src[-1] == ?\n + code.strip! + src << " #{@buf}.append(#{code});" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + code.strip! + src << @indent if src.empty? || src[-1] == ?\n + src << " System.err.println(\"*** debug: #{code}=\"+(#{code}));" + end + + def add_postamble(src) + src << "\n" if src[-1] == ?; + src << @indent << "return " << @buf << ".toString();\n" + #src << @indent << "System.out.print(" << @buf << ".toString());\n" + end + + end + + + ## + ## engine for Java + ## + class Ejava < Basic::Engine + include JavaGenerator + end + + + class EscapedEjava < Ejava + include EscapeEnhancer + end + + + #class XmlEjava < Ejava + # include EscapeEnhancer + #end + + class PI::Ejava < PI::Engine + include JavaGenerator + + def init_converter(properties={}) + @pi = 'java' + super(properties) + end + + end + +end +#--end of require 'erubis/engine/ejava' +#--begin of require 'erubis/engine/escheme' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + module SchemeGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:func, '_add', "function name (ex. 'display')"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'escape' + @func = properties[:func] || '_add' # or 'display' + end + + def add_preamble(src) + return unless @func == '_add' + src << "(let ((_buf '())) " + \ + "(define (_add x) (set! _buf (cons x _buf))) " + #src << "(let* ((_buf '())" + \ + # " (_add (lambda (x) (set! _buf (cons x _buf))))) " + end + + def escape_text(text) + @table_ ||= { '"'=>'\\"', '\\'=>'\\\\' } + text.gsub!(/["\\]/) { |m| @table_[m] } + return text + end + + def escaped_expr(code) + code.strip! + return "(#{@escapefunc} #{code})" + end + + def add_text(src, text) + return if text.empty? + t = escape_text(text) + if t[-1] == ?\n + t[-1, 1] = '' + src << "(#{@func} \"" << t << "\\n\")\n" + else + src << "(#{@func} \"" << t << '")' + end + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + code.strip! + src << "(#{@func} #{code})" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + s = (code.strip! || code).gsub(/\"/, '\\"') + src << "(display \"*** debug: #{s}=\")(display #{code.strip})(display \"\\n\")" + end + + def add_postamble(src) + return unless @func == '_add' + src << "\n" unless src[-1] == ?\n + src << " (reverse _buf))\n" + end + + end + + + ## + ## engine for Scheme + ## + class Escheme < Basic::Engine + include SchemeGenerator + end + + + class EscapedEscheme < Escheme + include EscapeEnhancer + end + + + #class XmlEscheme < Escheme + # include EscapeEnhancer + #end + + + class PI::Escheme < PI::Engine + include SchemeGenerator + + def init_converter(properties={}) + @pi = 'scheme' + super(properties) + end + + end + + +end +#--end of require 'erubis/engine/escheme' +#--begin of require 'erubis/engine/eperl' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + module PerlGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:func, 'print', "function name"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'encode_entities' + @func = properties[:func] || 'print' + end + + def add_preamble(src) + src << "use HTML::Entities; "; + end + + def escape_text(text) + return text.gsub!(/['\\]/, '\\\\\&') || text + end + + def add_text(src, text) + src << @func << "('" << escape_text(text) << "'); " unless text.empty? + end + + def add_expr_literal(src, code) + code.strip! + src << @func << "(" << code << "); " + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + code.strip! + s = code.gsub(/\'/, "\\'") + src << @func << "('*** debug: #{code}=', #{code}, \"\\n\");" + end + + def add_stmt(src, code) + src << code + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + end + + end + + + ## + ## engine for Perl + ## + class Eperl < Basic::Engine + include PerlGenerator + end + + + class EscapedEperl < Eperl + include EscapeEnhancer + end + + + #class XmlEperl < Eperl + # include EscapeEnhancer + #end + + + class PI::Eperl < PI::Engine + include PerlGenerator + + def init_converter(properties={}) + @pi = 'perl' + super(properties) + end + + end + + +end +#--end of require 'erubis/engine/eperl' +#--begin of require 'erubis/engine/ejavascript' +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +#--already included require 'erubis/engine' +#--already included require 'erubis/enhancer' + + +module Erubis + + + module JavascriptGenerator + include Generator + + def self.supported_properties() # :nodoc: + list = [] + #list << [:indent, '', "indent spaces (ex. ' ')"] + #list << [:buf, '_buf', "output buffer name"] + list << [:docwrite, true, "use 'document.write()' when true"] + return list + end + + def init_generator(properties={}) + super + @escapefunc ||= 'escape' + @indent = properties[:indent] || '' + @buf = properties[:out] || '_buf' + @docwrite = properties[:docwrite] != false # '!= false' will be removed in the next release + end + + def add_preamble(src) + src << "#{@indent}var #{@buf} = [];" + end + + def escape_text(text) + @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n\\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" } + return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text + end + + def add_indent(src, indent) + src << (src.empty? || src[-1] == ?\n ? indent : ' ') + end + + def add_text(src, text) + return if text.empty? + add_indent(src, @indent) + src << @buf << '.push("' + s = escape_text(text) + if s[-1] == ?\n + s[-2, 2] = '' + src << s << "\");\n" + else + src << s << "\");" + end + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + add_indent(src, @indent) + code.strip! + src << "#{@buf}.push(#{code});" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + add_indent(src, @indent) + code.strip! + src << "alert(\"*** debug: #{code}=\"+(#{code}));" + end + + def add_postamble(src) + src << "\n" if src[-1] == ?; + if @docwrite + src << @indent << 'document.write(' << @buf << ".join(\"\"));\n" + else + src << @indent << @buf << ".join(\"\");\n" + end + end + + end + + + ## + ## engine for JavaScript + ## + class Ejavascript < Basic::Engine + include JavascriptGenerator + end + + + class EscapedEjavascript < Ejavascript + include EscapeEnhancer + end + + + #class XmlEjavascript < Ejavascript + # include EscapeEnhancer + #end + + + class PI::Ejavascript < PI::Engine + include JavascriptGenerator + + def init_converter(properties={}) + @pi = 'js' + super(properties) + end + + end + + +end +#--end of require 'erubis/engine/ejavascript' + + +module Erubis + + + Ejs = Ejavascript + EscapedEjs = EscapedEjavascript + + + class CommandOptionError < ErubisError + end + + + ## + ## main class of command + ## + ## ex. + ## Main.main(ARGV) + ## + class Main + + def self.main(argv=ARGV) + status = 0 + begin + Main.new.execute(ARGV) + rescue CommandOptionError => ex + $stderr.puts ex.message + status = 1 + end + exit(status) + end + + def initialize + @single_options = "hvxztTSbeBXNUC" + @arg_options = "pcrfKIlaE" #C + @option_names = { + 'h' => :help, + 'v' => :version, + 'x' => :source, + 'z' => :syntax, + 'T' => :unexpand, + 't' => :untabify, # obsolete + 'S' => :intern, + 'b' => :bodyonly, + 'B' => :binding, + 'p' => :pattern, + 'c' => :context, + #'C' => :class, + 'e' => :escape, + 'r' => :requires, + 'f' => :datafiles, + 'K' => :kanji, + 'I' => :includes, + 'l' => :lang, + 'a' => :action, + 'E' => :enhancers, + 'X' => :notext, + 'N' => :linenum, + 'U' => :unique, + 'C' => :compact, + } + assert unless @single_options.length + @arg_options.length == @option_names.length + (@single_options + @arg_options).each_byte do |ch| + assert unless @option_names.key?(ch.chr) + end + end + + + def execute(argv=ARGV) + ## parse command-line options + options, properties = parse_argv(argv, @single_options, @arg_options) + filenames = argv + options['h'] = true if properties[:help] + opts = Object.new + arr = @option_names.collect {|ch, name| "def #{name}; @#{name}; end\n" } + opts.instance_eval arr.join + options.each do |ch, val| + name = @option_names[ch] + opts.instance_variable_set("@#{name}", val) + end + + ## help, version, enhancer list + if opts.help || opts.version + puts version() if opts.version + puts usage() if opts.help + puts show_properties() if opts.help + puts show_enhancers() if opts.help + return + end + + ## include path + opts.includes.split(/,/).each do |path| + $: << path + end if opts.includes + + ## require library + opts.requires.split(/,/).each do |library| + require library + end if opts.requires + + ## action + action = opts.action + action ||= 'syntax' if opts.syntax + action ||= 'convert' if opts.source || opts.notext + + ## lang + lang = opts.lang || 'ruby' + action ||= 'convert' if opts.lang + + ## class name of Eruby + #classname = opts.class + classname = nil + klass = get_classobj(classname, lang, properties[:pi]) + + ## kanji code + $KCODE = opts.kanji if opts.kanji + + ## read context values from yaml file + datafiles = opts.datafiles + context = load_datafiles(datafiles, opts) + + ## parse context data + if opts.context + context = parse_context_data(opts.context, opts) + end + + ## properties for engine + properties[:escape] = true if opts.escape && !properties.key?(:escape) + properties[:pattern] = opts.pattern if opts.pattern + #properties[:trim] = false if opts.notrim + properties[:preamble] = properties[:postamble] = false if opts.bodyonly + properties[:pi] = nil if properties[:pi] == true + + ## create engine and extend enhancers + engine = klass.new(nil, properties) + enhancers = get_enhancers(opts.enhancers) + #enhancers.push(Erubis::EscapeEnhancer) if opts.escape + enhancers.each do |enhancer| + engine.extend(enhancer) + engine.bipattern = properties[:bipattern] if enhancer == Erubis::BiPatternEnhancer + end + + ## no-text + engine.extend(Erubis::NoTextEnhancer) if opts.notext + + ## convert and execute + val = nil + msg = "Syntax OK\n" + if filenames && !filenames.empty? + filenames.each do |filename| + File.file?(filename) or + raise CommandOptionError.new("#{filename}: file not found.") + engine.filename = filename + engine.convert!(File.read(filename)) + val = do_action(action, engine, context, filename, opts) + msg = nil if val + end + else + engine.filename = filename = '(stdin)' + engine.convert!($stdin.read()) + val = do_action(action, engine, context, filename, opts) + msg = nil if val + end + print msg if action == 'syntax' && msg + + end + + private + + def do_action(action, engine, context, filename, opts) + case action + when 'convert' + s = manipulate_src(engine.src, opts) + when nil, 'exec', 'execute' + s = opts.binding ? engine.result(context.to_hash) : engine.evaluate(context) + when 'syntax' + s = check_syntax(filename, engine.src) + else + raise "*** internal error" + end + print s if s + return s + end + + def manipulate_src(source, opts) + flag_linenum = opts.linenum + flag_unique = opts.unique + flag_compact = opts.compact + if flag_linenum + n = 0 + source.gsub!(/^/) { n += 1; "%5d: " % n } + source.gsub!(/^ *\d+:\s+?\n/, '') if flag_compact + source.gsub!(/(^ *\d+:\s+?\n)+/, "\n") if flag_unique + else + source.gsub!(/^\s*?\n/, '') if flag_compact + source.gsub!(/(^\s*?\n)+/, "\n") if flag_unique + end + return source + end + + def usage(command=nil) + command ||= File.basename($0) + buf = [] + buf << "erubis - embedded program converter for multi-language" + buf << "Usage: #{command} [..options..] [file ...]" + buf << " -h, --help : help" + buf << " -v : version" + buf << " -x : show converted code" + buf << " -X : show converted code, only ruby code and no text part" + buf << " -N : numbering: add line numbers (for '-x/-X')" + buf << " -U : unique: compress empty lines to a line (for '-x/-X')" + buf << " -C : compact: remove empty lines (for '-x/-X')" + buf << " -b : body only: no preamble nor postamble (for '-x/-X')" + buf << " -z : syntax checking" + buf << " -e : escape (equal to '--E Escape')" + buf << " -p pattern : embedded pattern (default '<% %>')" + buf << " -l lang : convert but no execute (ruby/php/c/java/scheme/perl/js)" + buf << " -E e1,e2,... : enhancer names (Escape, PercentLine, BiPattern, ...)" + buf << " -I path : library include path" + buf << " -K kanji : kanji code (euc/sjis/utf8) (default none)" + buf << " -c context : context data string (yaml inline style or ruby code)" + buf << " -f datafile : context data file ('*.yaml', '*.yml', or '*.rb')" + #buf << " -t : expand tab characters in YAML file" + buf << " -T : don't expand tab characters in YAML file" + buf << " -S : convert mapping key from string to symbol in YAML file" + buf << " -B : invoke 'result(binding)' instead of 'evaluate(context)'" + buf << " --pi=name : parse '' instead of '<% ... %>'" + #' + # -T : don't trim spaces around '<% %>' + # -c class : class name (XmlEruby/PercentLineEruby/...) (default Eruby) + # -r library : require library + # -a : action (convert/execute) + return buf.join("\n") + end + + def collect_supported_properties(erubis_klass) + list = [] + erubis_klass.ancestors.each do |klass| + if klass.respond_to?(:supported_properties) + list.concat(klass.supported_properties) + end + end + return list + end + + def show_properties + s = "supported properties:\n" + basic_props = collect_supported_properties(Erubis::Basic::Engine) + pi_props = collect_supported_properties(Erubis::PI::Engine) + list = [] + common_props = basic_props & pi_props + list << ['(common)', common_props] + list << ['(basic)', basic_props - common_props] + list << ['(pi)', pi_props - common_props] + %w[ruby php c java scheme perl javascript].each do |lang| + klass = Erubis.const_get("E#{lang}") + list << [lang, collect_supported_properties(klass) - basic_props] + end + list.each do |lang, props| + s << " * #{lang}\n" + props.each do |name, default_val, desc| + s << (" --%-23s : %s\n" % ["#{name}=#{default_val.inspect}", desc]) + end + end + s << "\n" + return s + end + + def show_enhancers + dict = {} + ObjectSpace.each_object(Module) do |mod| + dict[$1] = mod if mod.name =~ /\AErubis::(.*)Enhancer\z/ + end + s = "enhancers:\n" + dict.sort_by {|name, mod| name }.each do |name, mod| + s << (" %-13s : %s\n" % [name, mod.desc]) + end + return s + end + + def version + return Erubis::VERSION + end + + def parse_argv(argv, arg_none='', arg_required='', arg_optional='') + options = {} + context = {} + while argv[0] && argv[0][0] == ?- + optstr = argv.shift + optstr = optstr[1, optstr.length-1] + # + if optstr[0] == ?- # context + optstr =~ /\A\-([-\w]+)(?:=(.*))?/ or + raise CommandOptionError.new("-#{optstr}: invalid context value.") + name, value = $1, $2 + name = name.gsub(/-/, '_').intern + #value = value.nil? ? true : YAML.load(value) # error, why? + value = value.nil? ? true : YAML.load("---\n#{value}\n") + context[name] = value + # + else # options + while optstr && !optstr.empty? + optchar = optstr[0].chr + optstr = optstr[1..-1] + if arg_none.include?(optchar) + options[optchar] = true + elsif arg_required.include?(optchar) + arg = optstr.empty? ? argv.shift : optstr or + raise CommandOptionError.new("-#{optchar}: #{@option_names[optchar]} required.") + options[optchar] = arg + optstr = nil + elsif arg_optional.include?(optchar) + arg = optstr.empty? ? true : optstr + options[optchar] = arg + optstr = nil + else + raise CommandOptionError.new("-#{optchar}: unknown option.") + end + end + end + # + end # end of while + + return options, context + end + + + def untabify(str, width=8) + list = str.split(/\t/) + last = list.pop + sb = '' + list.each do |s| + column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length + n = width - (column % width) + sb << s << (' ' * n) + end + sb << last + return sb + end + #-- + #def untabify(str, width=8) + # sb = '' + # str.scan(/(.*?)\t/m) do |s, | + # len = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length + # sb << s << (" " * (width - len % width)) + # end + # return $' ? (sb << $') : str + #end + #++ + + + def get_classobj(classname, lang, pi) + classname ||= "E#{lang}" + base_module = pi ? Erubis::PI : Erubis + begin + klass = base_module.const_get(classname) + rescue NameError + klass = nil + end + unless klass + if lang + msg = "-l #{lang}: invalid language name (class #{base_module.name}::#{classname} not found)." + else + msg = "-c #{classname}: invalid class name." + end + raise CommandOptionError.new(msg) + end + return klass + end + + def get_enhancers(enhancer_names) + return [] unless enhancer_names + enhancers = [] + shortname = nil + begin + enhancer_names.split(/,/).each do |name| + shortname = name + enhancers << Erubis.const_get("#{shortname}Enhancer") + end + rescue NameError + raise CommandOptionError.new("#{shortname}: no such Enhancer (try '-h' to show all enhancers).") + end + return enhancers + end + + def load_datafiles(filenames, opts) + context = Erubis::Context.new + return context unless filenames + filenames.split(/,/).each do |filename| + filename.strip! + test(?f, filename) or raise CommandOptionError.new("#{filename}: file not found.") + if filename =~ /\.ya?ml$/ + if opts.unexpand + ydoc = YAML.load_file(filename) + else + ydoc = YAML.load(untabify(File.read(filename))) + end + ydoc.is_a?(Hash) or raise CommandOptionError.new("#{filename}: root object is not a mapping.") + intern_hash_keys(ydoc) if opts.intern + context.update(ydoc) + elsif filename =~ /\.rb$/ + str = File.read(filename) + context2 = Erubis::Context.new + _instance_eval(context2, str) + context.update(context2) + else + CommandOptionError.new("#{filename}: '*.yaml', '*.yml', or '*.rb' required.") + end + end + return context + end + + def _instance_eval(_context, _str) + _context.instance_eval(_str) + end + + def parse_context_data(context_str, opts) + if context_str[0] == ?{ + require 'yaml' + ydoc = YAML.load(context_str) + unless ydoc.is_a?(Hash) + raise CommandOptionError.new("-c: root object is not a mapping.") + end + intern_hash_keys(ydoc) if opts.intern + return ydoc + else + context = Erubis::Context.new + context.instance_eval(context_str, '-c') + return context + end + end + + def intern_hash_keys(obj, done={}) + return if done.key?(obj.__id__) + case obj + when Hash + done[obj.__id__] = obj + obj.keys.each do |key| + obj[key.intern] = obj.delete(key) if key.is_a?(String) + end + obj.values.each do |val| + intern_hash_keys(val, done) if val.is_a?(Hash) || val.is_a?(Array) + end + when Array + done[obj.__id__] = obj + obj.each do |val| + intern_hash_keys(val, done) if val.is_a?(Hash) || val.is_a?(Array) + end + end + end + + def check_syntax(filename, src) + require 'open3' + #command = (ENV['_'] || 'ruby') + ' -wc' # ENV['_'] stores command name + bin = ENV['_'] && File.basename(ENV['_']) =~ /^ruby/ ? ENV['_'] : 'ruby' + command = bin + ' -wc' + stdin, stdout, stderr = Open3.popen3(command) + stdin.write(src) + stdin.close + result = stdout.read() + stdout.close() + errmsg = stderr.read() + stderr.close() + return nil unless errmsg && !errmsg.empty? + errmsg =~ /\A-:(\d+): / + linenum, message = $1, $' + return "#{filename}:#{linenum}: #{message}" + end + + end + +end +#--end of require 'erubis/main' + +Erubis::Main.main(ARGV) diff --git a/vendor/gems/erubis-2.6.5/contrib/erubis-run.rb b/vendor/gems/erubis-2.6.5/contrib/erubis-run.rb new file mode 100644 index 0000000..44be6d4 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/contrib/erubis-run.rb @@ -0,0 +1,132 @@ +=begin + += apache/erubis-run.rb + +Copyright (C) 2007 Andrew R Jackson + +Built from original by Shugo Maeda: +Copyright (C) 2001 Shugo Maeda + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WAreqANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WAreqANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTEreqUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +== Overview + +Apache::ErubisRun handles eRuby files with erubis + +== Example of httpd.conf + + RubyRequire apache/erubis-run + + SetHandler ruby-object + RubyHandler Apache::ErubisRun.instance + + +=end + +require "singleton" +require "tempfile" +require "eruby" # Still needed to bring in a couple useful helper methods +require "erubis" + +module Erubis + @@cgi = nil + + def self.cgi + return @@cgi + end + + def self.cgi=(cgi) + @@cgi = cgi + end +end + +module Apache + class ErubisRun + include Singleton + + def handler(req) + status = check_request(req) + return status if(status != OK) + + filename = req.filename.dup + filename.untaint + erubis = compile(filename) + prerun(req) + begin + run(erubis, filename) + ensure + postrun(req) + end + + return OK + end + + private + + def initialize + @compiler = nil + end + + def check_request(req) + if(req.method_number == M_OPTIONS) + req.allowed |= (1 << M_GET) + req.allowed |= (1 << M_POST) + return DECLINED + end + if(req.finfo.mode == 0) + return NOT_FOUND + end + return OK + end + + def compile(filename) + @compiler = Erubis::Eruby.load_file(filename) # use caching version as much as possible + return @compiler + end + + def prerun(req) + Erubis.cgi = nil + req.setup_cgi_env + Apache.chdir_file(req.filename) + end + + def run(erubis, filename) + binding = eval_string_wrap("binding") + puts erubis.result(binding) # eval the code in the context of the same binding ERuby uses + end + + def postrun(req) + if(cgi = Erubis.cgi) + # TODO: pull the content type header from the cgi object, if set there? + elsif(req.sync_output or req.sync_header) + # Do nothing: header has already been sent + else + unless(req.content_type) + req.content_type = format("text/html;") + end + req.send_http_header + end + end + end +end diff --git a/vendor/gems/erubis-2.6.5/contrib/inline-require b/vendor/gems/erubis-2.6.5/contrib/inline-require new file mode 100755 index 0000000..e173760 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/contrib/inline-require @@ -0,0 +1,179 @@ +#!/usr/bin/env ruby + +### +### inline-require - expand 'require "foo"' into inline code +### +### usage: inline-require [-h] [-I path[,path2,..]] script +### +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### 2.6.5 +### $Rev: 10 $ +### + + +class InlineRequire + + def initialize(opts={}) + @opts = opts.dup + end + attr_accessor :opts + + def expand(filename) + sbuf = '' + inlined = [] + level = 0 + expand_require(filename, sbuf, inlined, level) + return sbuf + end + + private + + def expand_require(filename, sbuf, inlined, level) + raise "*** assertion error" if inlined.include?(filename) + remove_comment = @opts[:remove_comment] + expand_indented = @opts[:expand_indented] + keep_filename = @opts[:keep_filename] + loaded_features = @opts[:loaded_features] + inlined << filename + prog = File.read(filename) + n = 0 + flag_if_file = false + prog.each_line do |line| + n += 1 + + ## comment out from 'if __FILE__ == $0' to 'end' + if level > 0 + if flag_if_file + sbuf << "#" << line + flag_if_file = false if line =~ /^end$/ + next + end + if line =~ /^if\s+__FILE__\s*==\s*\$0(\s+then)?$/ || line =~ /^if\s+\$0\s*==\s*__FILE__(\s+then)?$/ + flag_if_file = true + sbuf << "#" << line + next + end + end + + ## find 'require "foo"' and expand it to inline code + flag_inline = false + pattern = expand_indented ? /^[ \t]*require ['"](.*)["']\s*$/ \ + : /^require ['"](.*)["']\s*$/ + if line =~ pattern + libname = $1 + libpath = find_library(libname) + $stderr.puts "*** debug: libpath=#{libpath.inspect}" if $debug_mode + unless libpath + #raise "file '#{filename}'(line #{n}): library '#{libname}' not found." + warn "file '#{filename}'(line #{n}): library '#{libname}' not found." + else + flag_inline = true if libpath =~ /\.rb$/ && local_library?(libpath) + end + end + if !flag_inline + sbuf << line unless remove_comment && line =~ /^[ \t]*\#/ + elsif inlined.include?(libpath) + sbuf << "#--already included #{line}" unless remove_comment + else + if keep_filename + @n ||= 0; @n += 1; n = @n + end + sbuf << "#--begin of #{line}" unless remove_comment + sbuf << "$LOADED_FEATURES << '#{libname}.rb'\n" if loaded_features + sbuf << "eval <<'END_OF_SCRIPT__#{n}', TOPLEVEL_BINDING, '#{libpath}', 1\n" if keep_filename + expand_require(libpath, sbuf, inlined, level+1) + sbuf << "END_OF_SCRIPT__#{n}\n" if keep_filename + sbuf << "#--end of #{line}" unless remove_comment + end + end + #sbuf << "\n" if sbuf[-1] != ?\n + end + + def local_library?(libpath) + return libpath !~ /^\// + end + + def find_library(libname) + if libname =~ /^\.rb$/ + libname_rb = libname + libname_so = nil + elsif libname =~ /^\.so$/ + libname_rb = nil + libname_so = libname + else + libname_rb = libname + ".rb" + libname_so = libname + ".so" + end + $LOAD_PATH.each do |path| + if libname_rb + libpath = path + "/" + libname_rb + return libpath if test(?f, libpath) + end + if libname_so + libpath = path + "/" + libname_so + return libpath if test(?f, libpath) + end + end + return nil + end + +end + +if __FILE__ == $0 + + begin + require "optparse" + op = OptionParser.new + options = {} + op.on("-h", "--help") {|v| options[:help] = v } + op.on("-I libpath") {|v| options[:libpath] = v } + op.on("-i") {|v| options[:expand_indented] = v } + op.on("-c") {|v| options[:remove_comment] = v } + op.on("-k") {|v| options[:keep_filename] = v } + op.on("-l") {|v| options[:loaded_features] = v } + op.on("-D") {|v| options[:debug] = v } + op.parse!() + + $debug_mode = options[:debug] + + if options[:help] + command = File.basename($0) + puts "Usage: #{command} [-h] [-I path[,path2,..]] script" + puts " -h : help" + puts " -i : expand indented require(), too" + puts " -c : remove comment lines start with '#'" + puts " -k : keep filename (for debugging)" + puts " -l : append libs to $LOADED_FEATURES" + puts " -I path[,path2,...] : ruby library path" + exit(0) + end + + if options[:libpath] + rubylib_paths = options[:libpath].split(/,/) + else + rubylib_paths = [] + end + $stderr.puts "*** debug: rubylib_paths=#{rubylib_paths.inspect}" if $debug_mode + $LOAD_PATH.concat(rubylib_paths) + + filenames = ARGV + + opts = { :expand_indented => options[:expand_indented], + :remove_comment => options[:remove_comment], + :keep_filename => options[:keep_filename], + :loaded_features => options[:loaded_features] } + inline_require = InlineRequire.new(opts) + filenames.each do |filename| + print inline_require.expand(filename) + end + + rescue => ex + if $debug_mode + raise ex + else + $stderr.puts ex.message + end + + end + +end diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/ActionView.html b/vendor/gems/erubis-2.6.5/doc-api/classes/ActionView.html new file mode 100644 index 0000000..2f9e153 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/ActionView.html @@ -0,0 +1,105 @@ + + + + + + Module: ActionView + + + + + + + + + + +
    +
    #symbolnamepricechangeratio
    <%= n %> + <%= item['symbol'] %> + + <%= item['name'] %> + + <%= item['price'] %> + <%= item['change'] %><%= item['ratio'] %><%= item['change'] %><%= item['ratio'] %>
    <%= n %> + <%= item['symbol'] %> + + <%= item['name'] %> + + <%= item['price'] %> + <%= item['change'] %><%= item['ratio'] %><%= item['change'] %><%= item['ratio'] %>
    <%= n %> + <%= item['symbol'] %> + + <%= item['name'] %> + + <%= item['price'] %> + <%= item['change'] %><%= item['ratio'] %><%= item['change'] %><%= item['ratio'] %>
    + + + + + + + + + +
    ModuleActionView
    In: + + erubis/helpers/rails_helper.rb + +
    +
    + + + +
    + + + +
    + + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + +
    + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/ActionView/TemplateHandlers/ErubisHandler.html b/vendor/gems/erubis-2.6.5/doc-api/classes/ActionView/TemplateHandlers/ErubisHandler.html new file mode 100644 index 0000000..66b3c9b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/ActionView/TemplateHandlers/ErubisHandler.html @@ -0,0 +1,209 @@ + + + + + + Class: ActionView::TemplateHandlers::ErubisHandler + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassActionView::TemplateHandlers::ErubisHandler
    In: + + erubis/helpers/rails_helper.rb + +
    +
    Parent: + TemplateHandler +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + +
    + compile   + compile   + compile   +
    +
    + +
    + + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 153
    +          def compile(template)
    +            #src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src
    +            return _convert_template("<% __in_erb_template=true %>#{template.source}")
    +          end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 179
    +          def compile(template)
    +            return _convert_template(template.source)   # template.is_a?(ActionView::Template)
    +          end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 209
    +          def compile(template)
    +            return _convert_template(template)     # template.is_a?(String)
    +          end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/ERB.html b/vendor/gems/erubis-2.6.5/doc-api/classes/ERB.html new file mode 100644 index 0000000..93ade5a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/ERB.html @@ -0,0 +1,101 @@ + + + + + + Module: ERB + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleERB
    In: +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis.html new file mode 100644 index 0000000..7d26709 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis.html @@ -0,0 +1,353 @@ + + + + + + Module: Erubis + + + + + + + + + + + + + +
    + + + +
    + +
    +

    +an implementation of eRuby +

    +

    +ex. +

    +
    +  input = <<'END'
    +   <ul>
    +    <% for item in @list %>
    +     <li><%= item %>
    +         <%== item %></li>
    +    <% end %>
    +   </ul>
    +  END
    +  list = ['<aaa>', 'b&b', '"ccc"']
    +  eruby = Erubis::Eruby.new(input)
    +  puts "--- code ---"
    +  puts eruby.src
    +  puts "--- result ---"
    +  context = Erubis::Context.new()   # or new(:list=>list)
    +  context[:list] = list
    +  puts eruby.evaluate(context)
    +
    +

    +result: +

    +
    +  --- source ---
    +  _buf = ''; _buf << '<ul>
    +  ';  for item in @list
    +   _buf << '  <li>'; _buf << ( item ).to_s; _buf << '
    +  '; _buf << '      '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</li>
    +  ';  end
    +   _buf << '</ul>
    +  ';
    +  _buf.to_s
    +  --- result ---
    +   <ul>
    +     <li><aaa>
    +         &lt;aaa&gt;</li>
    +     <li>b&b
    +         b&amp;b</li>
    +     <li>"ccc"
    +         &quot;ccc&quot;</li>
    +   </ul>
    +
    + +
    + + +
    + + +
    + + + + +
    + +
    +

    Classes and Modules

    + + Module Erubis::ArrayBufferEnhancer
    +Module Erubis::ArrayEnhancer
    +Module Erubis::Basic
    +Module Erubis::BiPatternEnhancer
    +Module Erubis::CGenerator
    +Module Erubis::Converter
    +Module Erubis::DeleteIndentEnhancer
    +Module Erubis::ErboutEnhancer
    +Module Erubis::EscapeEnhancer
    +Module Erubis::Evaluator
    +Module Erubis::Generator
    +Module Erubis::HeaderFooterEnhancer
    +Module Erubis::Helpers
    +Module Erubis::InterpolationEnhancer
    +Module Erubis::JavaGenerator
    +Module Erubis::JavascriptGenerator
    +Module Erubis::NoCodeEnhancer
    +Module Erubis::NoTextEnhancer
    +Module Erubis::OptimizedGenerator
    +Module Erubis::PI
    +Module Erubis::PercentLineEnhancer
    +Module Erubis::PerlGenerator
    +Module Erubis::PhpGenerator
    +Module Erubis::PreprocessingHelper
    +Module Erubis::PrintEnabledEnhancer
    +Module Erubis::PrintOutEnhancer
    +Module Erubis::RubyEvaluator
    +Module Erubis::RubyGenerator
    +Module Erubis::SchemeGenerator
    +Module Erubis::SimplifyEnhancer
    +Module Erubis::StdoutEnhancer
    +Module Erubis::StringBufferEnhancer
    +Module Erubis::XmlHelper
    +Class Erubis::ArrayBufferEruby
    +Class Erubis::ArrayEruby
    +Class Erubis::BiPatternEruby
    +Class Erubis::CommandOptionError
    +Class Erubis::Context
    +Class Erubis::DeleteIndentEruby
    +Class Erubis::Ec
    +Class Erubis::Ejava
    +Class Erubis::Ejavascript
    +Class Erubis::Engine
    +Class Erubis::Eperl
    +Class Erubis::Ephp
    +Class Erubis::ErboutEruby
    +Class Erubis::ErubisError
    +Class Erubis::Eruby
    +Class Erubis::EscapedEc
    +Class Erubis::EscapedEjava
    +Class Erubis::EscapedEjavascript
    +Class Erubis::EscapedEperl
    +Class Erubis::EscapedEphp
    +Class Erubis::EscapedEruby
    +Class Erubis::EscapedEscheme
    +Class Erubis::Escheme
    +Class Erubis::FastEruby
    +Class Erubis::HeaderFooterEruby
    +Class Erubis::InterpolationEruby
    +Class Erubis::Main
    +Class Erubis::NoCodeEruby
    +Class Erubis::NoTextEruby
    +Class Erubis::NotSupportedError
    +Class Erubis::OptimizedEruby
    +Class Erubis::OptimizedXmlEruby
    +Class Erubis::PercentLineEruby
    +Class Erubis::PreprocessingEruby
    +Class Erubis::PrintEnabledEruby
    +Class Erubis::PrintOutEruby
    +Class Erubis::PrintOutSimplifiedEruby
    +Class Erubis::SimplifiedEruby
    +Class Erubis::StdoutEruby
    +Class Erubis::StdoutSimplifiedEruby
    +Class Erubis::StringBufferEruby
    +Class Erubis::StringIOEruby
    +Class Erubis::TinyEruby
    +Class Erubis::XmlEruby
    + +
    + +
    +

    Constants

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    EMPTY_BINDING=binding()
    Ejs=Ejavascript
    EscapedEjs=EscapedEjavascript
    VERSION=('$Release: 2.6.5 $' =~ /([.\d]+)/) && $1
    +
    +
    + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayBufferEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayBufferEnhancer.html new file mode 100644 index 0000000..3931ed6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayBufferEnhancer.html @@ -0,0 +1,175 @@ + + + + + + Module: Erubis::ArrayBufferEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::ArrayBufferEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +use an Array object as buffer (included in Eruby +by default) +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_postamble   + add_preamble   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 191
    +    def add_postamble(src)
    +      src << "\n" unless src[-1] == ?\n
    +      src << "_buf.join\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 187
    +    def add_preamble(src)
    +      src << "_buf = [];"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayBufferEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayBufferEruby.html new file mode 100644 index 0000000..e4ee23a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayBufferEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::ArrayBufferEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::ArrayBufferEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayEnhancer.html new file mode 100644 index 0000000..bd4d1e5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayEnhancer.html @@ -0,0 +1,174 @@ + + + + + + Module: Erubis::ArrayEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::ArrayEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +return array instead of string +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_postamble   + add_preamble   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 168
    +    def add_postamble(src)
    +      src << "\n" unless src[-1] == ?\n
    +      src << "_buf\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 164
    +    def add_preamble(src)
    +      src << "_buf = [];"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayEruby.html new file mode 100644 index 0000000..6d0c5d7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ArrayEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::ArrayEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::ArrayEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic.html new file mode 100644 index 0000000..068332e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic.html @@ -0,0 +1,112 @@ + + + + + + Module: Erubis::Basic + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Basic
    In: + + erubis/converter.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + + +
    + +
    +

    Classes and Modules

    + + Module Erubis::Basic::Converter
    +Class Erubis::Basic::Engine
    + +
    + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic/Converter.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic/Converter.html new file mode 100644 index 0000000..2d329b8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic/Converter.html @@ -0,0 +1,327 @@ + + + + + + Module: Erubis::Basic::Converter + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Basic::Converter
    In: + + erubis/converter.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +basic converter which supports ’<% … %>’ notation. +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + +
    +

    Constants

    + +
    + + + + + + + + +
    DEFAULT_REGEXP=pattern_regexp('<% %>')  +DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m +DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m +DEFAULT_REGEXP = /<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + +
    +
    +
    + + + +
    +

    Attributes

    + +
    + + + + + + + + + + + +
    pattern [RW] 
    trim [RW] 
    +
    +
    + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    +add expression code to src +

    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 176
    +    def add_expr(src, code, indicator)
    +      case indicator
    +      when '='
    +        @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
    +      when '=='
    +        @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
    +      when '==='
    +        add_expr_debug(src, code)
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 127
    +    def convert_input(src, input)
    +      pat = @pattern
    +      regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat)
    +      pos = 0
    +      is_bol = true     # is beginning of line
    +      input.scan(regexp) do |indicator, code, tailch, rspace|
    +        match = Regexp.last_match()
    +        len  = match.begin(0) - pos
    +        text = input[pos, len]
    +        pos  = match.end(0)
    +        ch   = indicator ? indicator[0] : nil
    +        lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
    +        is_bol = rspace ? true : false
    +        add_text(src, text) if text && !text.empty?
    +        ## * when '<%= %>', do nothing
    +        ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
    +        if ch == ?=              # <%= %>
    +          rspace = nil if tailch && !tailch.empty?
    +          add_text(src, lspace) if lspace
    +          add_expr(src, code, indicator)
    +          add_text(src, rspace) if rspace
    +        elsif ch == ?\#          # <%# %>
    +          n = code.count("\n") + (rspace ? 1 : 0)
    +          if @trim && lspace && rspace
    +            add_stmt(src, "\n" * n)
    +          else
    +            add_text(src, lspace) if lspace
    +            add_stmt(src, "\n" * n)
    +            add_text(src, rspace) if rspace
    +          end
    +        elsif ch == ?%           # <%% %>
    +          s = "#{lspace}#{@prefix||='<%'}#{code}#{tailch}#{@postfix||='%>'}#{rspace}"
    +          add_text(src, s)
    +        else                     # <% %>
    +          if @trim && lspace && rspace
    +            add_stmt(src, "#{lspace}#{code}#{rspace}")
    +          else
    +            add_text(src, lspace) if lspace
    +            add_stmt(src, code)
    +            add_text(src, rspace) if rspace
    +          end
    +        end
    +      end
    +      #rest = $' || input                        # ruby1.8
    +      rest = pos == 0 ? input : input[pos..-1]   # ruby1.9
    +      add_text(src, rest)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 103
    +    def init_converter(properties={})
    +      super(properties)
    +      @pattern = properties[:pattern]
    +      @trim    = properties[:trim] != false
    +    end
    +
    +
    +
    +
    + +

    Protected Instance methods

    + +
    + + + + +
    +

    +return regexp of pattern to parse eRuby script +

    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 112
    +    def pattern_regexp(pattern)
    +      @prefix, @postfix = pattern.split()   # '<% %>' => '<%', '%>'
    +      #return /(.*?)(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m
    +      #return /(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m
    +      return /#{@prefix}(=+|-|\#|%)?(.*?)([-=])?#{@postfix}([ \t]*\r?\n)?/m
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic/Engine.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic/Engine.html new file mode 100644 index 0000000..3562b6f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Basic/Engine.html @@ -0,0 +1,130 @@ + + + + + + Class: Erubis::Basic::Engine + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Basic::Engine
    In: + + erubis/engine.rb + +
    +
    Parent: + + Engine + +
    +
    + + +
    + + + +
    + +
    +

    +(abstract) base engine class for Eruby, Eperl, Ejava, and so +on. subclass must include generator. +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/BiPatternEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/BiPatternEnhancer.html new file mode 100644 index 0000000..4f14a0c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/BiPatternEnhancer.html @@ -0,0 +1,215 @@ + + + + + + Module: Erubis::BiPatternEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::BiPatternEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +enable to use other embedded expression pattern (default is ’\[= +=\]’). +

    +

    +notice! this is an experimental. spec may change in the future. +

    +

    +ex. +

    +
    +  input = <<END
    +  <% for item in list %>
    +    <%= item %> : <%== item %>
    +    [= item =] : [== item =]
    +  <% end %>
    +  END
    +
    +  class BiPatternEruby
    +    include BiPatternEnhancer
    +  end
    +  eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]')
    +  list = ['<a>', 'b&b', '"c"']
    +  print eruby.result(binding())
    +
    +  ## output
    +    <a> : &lt;a&gt;
    +    <a> : &lt;a&gt;
    +    b&b : b&amp;b
    +    b&b : b&amp;b
    +    "c" : &quot;c&quot;
    +    "c" : &quot;c&quot;
    +
    +

    +this is language independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_text   + new   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 408
    +    def initialize(input, properties={})
    +      self.bipattern = properties[:bipattern]    # or '\$\{ \}'
    +      super
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 420
    +    def add_text(src, text)
    +      return unless text
    +      m = nil
    +      text.scan(@bipattern_regexp) do |txt, indicator, code|
    +        m = Regexp.last_match
    +        super(src, txt)
    +        add_expr(src, code, '=' + indicator)
    +      end
    +      #rest = $' || text                    # ruby1.8
    +      rest = m ? text[m.end(0)..-1] : text  # ruby1.9
    +      super(src, rest)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/BiPatternEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/BiPatternEruby.html new file mode 100644 index 0000000..802420e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/BiPatternEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::BiPatternEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::BiPatternEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/CGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/CGenerator.html new file mode 100644 index 0000000..c882eb2 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/CGenerator.html @@ -0,0 +1,386 @@ + + + + + + Module: Erubis::CGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::CGenerator
    In: + + erubis/engine/ec.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 72
    +    def add_expr_debug(src, code)
    +      code.strip!
    +      s = nil
    +      if code =~ /\A\".*?\"\s*,\s*(.*)/
    +        s = $1.gsub(/[%"]/, '\\\1') + '='
    +      end
    +      src << @indent if src.empty? || src[-1] == ?\n
    +      src << " fprintf(stderr, \"*** debug: #{s}\" #{code});"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 67
    +    def add_expr_escaped(src, code)
    +      src << @indent if src.empty? || src[-1] == ?\n
    +      src << ' ' << escaped_expr(code) << ';'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 62
    +    def add_expr_literal(src, code)
    +      src << @indent if src.empty? || src[-1] == ?\n
    +      src << " fprintf(#{@out}, " << code.strip << ');'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 82
    +    def add_postamble(src)
    +      # empty
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 30
    +    def add_preamble(src)
    +      src << "#line 1 \"#{self.filename}\"\n" if self.filename
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 58
    +    def add_stmt(src, code)
    +      src << code
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 44
    +    def add_text(src, text)
    +      return if text.empty?
    +      src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
    +      src << "fputs("
    +      i = 0
    +      text.each_line do |line|
    +        src << "\n" << @indent << '      ' if i > 0
    +        i += 1
    +        src << '"' << escape_text(line) << '"'
    +      end
    +      src << ", #{@out});"   #<< (text[-1] == ?\n ? "\n" : "")
    +      src << "\n" if text[-1] == ?\n
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 34
    +    def escape_text(text)
    +      @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
    +      text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] }
    +      return text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 40
    +    def escaped_expr(code)
    +      return "#{@escapefunc}(#{code.strip}, #{@out})"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 23
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= "escape"
    +      @indent = properties[:indent] || ''
    +      @out = properties[:out] || 'stdout'
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/CommandOptionError.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/CommandOptionError.html new file mode 100644 index 0000000..e5d32a9 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/CommandOptionError.html @@ -0,0 +1,113 @@ + + + + + + Class: Erubis::CommandOptionError + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::CommandOptionError
    In: + + erubis/main.rb + +
    +
    Parent: + + ErubisError + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Context.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Context.html new file mode 100644 index 0000000..085e75a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Context.html @@ -0,0 +1,344 @@ + + + + + + Class: Erubis::Context + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Context
    In: + + erubis/context.rb + +
    +
    Parent: + Object +
    +
    + + +
    + + + +
    + +
    +

    +context object for Engine#evaluate +

    +

    +ex. +

    +
    +  template = <<'END'
    +  Hello <%= @user %>!
    +  <% for item in @list %>
    +   - <%= item %>
    +  <% end %>
    +  END
    +
    +  context = Erubis::Context.new(:user=>'World', :list=>['a','b','c'])
    +  # or
    +  # context = Erubis::Context.new
    +  # context[:user] = 'World'
    +  # context[:list] = ['a', 'b', 'c']
    +
    +  eruby = Erubis::Eruby.new(template)
    +  print eruby.evaluate(context)
    +
    + +
    + + +
    + +
    +

    Methods

    + +
    + []   + []=   + each   + keys   + new   + to_hash   + update   +
    +
    + +
    + + + +
    +

    Included Modules

    + +
    + Enumerable +
    +
    + +
    + + + + + + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 33
    +    def initialize(hash=nil)
    +      hash.each do |name, value|
    +        self[name] = value
    +      end if hash
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 39
    +    def [](key)
    +      return instance_variable_get("@#{key}")
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 43
    +    def []=(key, value)
    +      return instance_variable_set("@#{key}", value)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 51
    +    def each
    +      instance_variables.each do |name|
    +        key = name[1..-1]
    +        value = instance_variable_get(name)
    +        yield(key, value)
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 47
    +    def keys
    +      return instance_variables.collect { |name| name[1..-1] }
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 59
    +    def to_hash
    +      hash = {}
    +      self.keys.each { |key| hash[key] = self[key] }
    +      return hash
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/context.rb, line 65
    +    def update(context_or_hash)
    +      arg = context_or_hash
    +      if arg.is_a?(Hash)
    +        arg.each do |key, val|
    +          self[key] = val
    +        end
    +      else
    +        arg.instance_variables.each do |varname|
    +          key = varname[1..-1]
    +          val = arg.instance_variable_get(varname)
    +          self[key] = val
    +        end
    +      end
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Converter.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Converter.html new file mode 100644 index 0000000..9895f6d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Converter.html @@ -0,0 +1,283 @@ + + + + + + Module: Erubis::Converter + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Converter
    In: + + erubis/converter.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +convert +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + + +
    + + + + + +
    +

    Attributes

    + +
    + + + + + + + + + + + + + + + + +
    escape [RW] 
    postamble [RW] 
    preamble [RW] 
    +
    +
    + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    +convert input string into target +language +

    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 33
    +    def convert(input)
    +      codebuf = ""    # or []
    +      @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble))
    +      convert_input(codebuf, input)
    +      @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble))
    +      @_proc = nil    # clear cached proc object
    +      return codebuf  # or codebuf.join()
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 26
    +    def init_converter(properties={})
    +      @preamble  = properties[:preamble]
    +      @postamble = properties[:postamble]
    +      @escape    = properties[:escape]
    +    end
    +
    +
    +
    +
    + +

    Protected Instance methods

    + +
    + + + + +
    +

    +(abstract) convert input to code +

    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 77
    +    def convert_input(codebuf, input)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +detect spaces at beginning of line +

    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 47
    +    def detect_spaces_at_bol(text, is_bol)
    +      lspace = nil
    +      if text.empty?
    +        lspace = "" if is_bol
    +      elsif text[-1] == ?\n
    +        lspace = ""
    +      else
    +        rindex = text.rindex(?\n)
    +        if rindex
    +          s = text[rindex+1..-1]
    +          if s =~ /\A[ \t]*\z/
    +            lspace = s
    +            #text = text[0..rindex]
    +            text[rindex+1..-1] = ''
    +          end
    +        else
    +          if is_bol && text =~ /\A[ \t]*\z/
    +            #lspace = text
    +            #text = nil
    +            lspace = text.dup
    +            text[0..-1] = ''
    +          end
    +        end
    +      end
    +      return lspace
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/DeleteIndentEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/DeleteIndentEnhancer.html new file mode 100644 index 0000000..7f4ac7f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/DeleteIndentEnhancer.html @@ -0,0 +1,150 @@ + + + + + + Module: Erubis::DeleteIndentEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::DeleteIndentEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +delete indentation of HTML. +

    +

    +this is language-independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + convert_input   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 578
    +    def convert_input(src, input)
    +      input = input.gsub(/^[ \t]+</, '<')
    +      super(src, input)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/DeleteIndentEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/DeleteIndentEruby.html new file mode 100644 index 0000000..80720b9 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/DeleteIndentEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::DeleteIndentEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::DeleteIndentEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ec.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ec.html new file mode 100644 index 0000000..9e880ba --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ec.html @@ -0,0 +1,126 @@ + + + + + + Class: Erubis::Ec + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Ec
    In: + + erubis/engine/ec.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for C +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ejava.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ejava.html new file mode 100644 index 0000000..6e9e2b3 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ejava.html @@ -0,0 +1,126 @@ + + + + + + Class: Erubis::Ejava + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Ejava
    In: + + erubis/engine/ejava.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for Java +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ejavascript.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ejavascript.html new file mode 100644 index 0000000..e065ab6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ejavascript.html @@ -0,0 +1,126 @@ + + + + + + Class: Erubis::Ejavascript + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Ejavascript
    In: + + erubis/engine/ejavascript.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for JavaScript +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Engine.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Engine.html new file mode 100644 index 0000000..6eca666 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Engine.html @@ -0,0 +1,305 @@ + + + + + + Class: Erubis::Engine + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Engine
    In: + + erubis/engine.rb + +
    +
    Parent: + Object +
    +
    + + +
    + + + +
    + +
    +

    +(abstract) abstract engine class. subclass must include evaluator and +converter module. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + convert!   + load_file   + new   + process   + process_proc   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    +load file, write cache file, and return engine object. this method create +code cache file automatically. cachefile name can be specified with +properties[:cachename], or filname + ‘cache’ is used as +default. +

    +

    [Source]

    +
    +
    +# File erubis/engine.rb, line 48
    +    def self.load_file(filename, properties={})
    +      cachename = properties[:cachename] || (filename + '.cache')
    +      properties[:filename] = filename
    +      if test(?f, cachename) && File.mtime(filename) <= File.mtime(cachename)
    +        engine = self.new(nil, properties)
    +        engine.src = File.read(cachename)
    +      else
    +        input = File.open(filename, 'rb') {|f| f.read }
    +        engine = self.new(input, properties)
    +        File.open(cachename, 'wb') do |f|
    +          f.flock(File::LOCK_EX)
    +          f.write(engine.src)
    +          f.flush()
    +        end
    +      end
    +      engine.src.untaint   # ok?
    +      return engine
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +include Evaluator include Converter include Generator +

    +

    [Source]

    +
    +
    +# File erubis/engine.rb, line 25
    +    def initialize(input=nil, properties={})
    +      #@input = input
    +      init_generator(properties)
    +      init_converter(properties)
    +      init_evaluator(properties)
    +      @src    = convert(input) if input
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    +convert input string and set it to @src +

    +

    [Source]

    +
    +
    +# File erubis/engine.rb, line 37
    +    def convert!(input)
    +      @src = convert(input)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +helper method to convert and evaluate input text with context object. +context may be Binding, Hash, or Object. +

    +

    [Source]

    +
    +
    +# File erubis/engine.rb, line 72
    +    def process(input, context=nil, filename=nil)
    +      code = convert(input)
    +      filename ||= '(erubis)'
    +      if context.is_a?(Binding)
    +        return eval(code, context, filename)
    +      else
    +        context = Context.new(context) if context.is_a?(Hash)
    +        return context.instance_eval(code, filename)
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +helper method evaluate Proc object with contect object. context may be +Binding, Hash, or Object. +

    +

    [Source]

    +
    +
    +# File erubis/engine.rb, line 88
    +    def process_proc(proc_obj, context=nil, filename=nil)
    +      if context.is_a?(Binding)
    +        filename ||= '(erubis)'
    +        return eval(proc_obj, context, filename)
    +      else
    +        context = Context.new(context) if context.is_a?(Hash)
    +        return context.instance_eval(&proc_obj)
    +      end
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Eperl.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Eperl.html new file mode 100644 index 0000000..60c491c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Eperl.html @@ -0,0 +1,126 @@ + + + + + + Class: Erubis::Eperl + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Eperl
    In: + + erubis/engine/eperl.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for Perl +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ephp.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ephp.html new file mode 100644 index 0000000..8486dd6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Ephp.html @@ -0,0 +1,126 @@ + + + + + + Class: Erubis::Ephp + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Ephp
    In: + + erubis/engine/ephp.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for PHP +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErboutEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErboutEnhancer.html new file mode 100644 index 0000000..a50c944 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErboutEnhancer.html @@ -0,0 +1,175 @@ + + + + + + Module: Erubis::ErboutEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::ErboutEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +set buffer variable name to ‘_erbout’ as well as +‘_buf‘ +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_postamble   + add_preamble   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 260
    +    def add_postamble(src)
    +      src << "\n" unless src[-1] == ?\n
    +      src << "_buf.to_s\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 256
    +    def add_preamble(src)
    +      src << "_erbout = _buf = '';"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErboutEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErboutEruby.html new file mode 100644 index 0000000..662e9f1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErboutEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::ErboutEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::ErboutEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErubisError.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErubisError.html new file mode 100644 index 0000000..5e7732b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/ErubisError.html @@ -0,0 +1,117 @@ + + + + + + Class: Erubis::ErubisError + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::ErubisError
    In: + + erubis/error.rb + +
    +
    Parent: + StandardError +
    +
    + + +
    + + + +
    + +
    +

    +base error class +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Eruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Eruby.html new file mode 100644 index 0000000..c5da50d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Eruby.html @@ -0,0 +1,132 @@ + + + + + + Class: Erubis::Eruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Eruby
    In: + + erubis/engine/eruby.rb + +
    + + erubis/helpers/rails_helper.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for Ruby +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapeEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapeEnhancer.html new file mode 100644 index 0000000..30cb2a6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapeEnhancer.html @@ -0,0 +1,165 @@ + + + + + + Module: Erubis::EscapeEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::EscapeEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +switch ’<%= … %>’ to escaped and ’<%== +… %>’ to unescaped +

    +

    +ex. +

    +
    +  class XmlEruby < Eruby
    +    include EscapeEnhancer
    +  end
    +
    +

    +this is language-indenedent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_expr   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 37
    +    def add_expr(src, code, indicator)
    +      case indicator
    +      when '='
    +        @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
    +      when '=='
    +        @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
    +      when '==='
    +        add_expr_debug(src, code)
    +      end
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEc.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEc.html new file mode 100644 index 0000000..b83d688 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEc.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::EscapedEc + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEc
    In: + + erubis/engine/ec.rb + +
    +
    Parent: + + Ec + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEjava.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEjava.html new file mode 100644 index 0000000..1a59c7e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEjava.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::EscapedEjava + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEjava
    In: + + erubis/engine/ejava.rb + +
    +
    Parent: + + Ejava + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEjavascript.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEjavascript.html new file mode 100644 index 0000000..d376314 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEjavascript.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::EscapedEjavascript + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEjavascript
    In: + + erubis/engine/ejavascript.rb + +
    +
    Parent: + + Ejavascript + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEperl.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEperl.html new file mode 100644 index 0000000..10bdb71 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEperl.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::EscapedEperl + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEperl
    In: + + erubis/engine/eperl.rb + +
    +
    Parent: + + Eperl + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEphp.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEphp.html new file mode 100644 index 0000000..e58b86d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEphp.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::EscapedEphp + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEphp
    In: + + erubis/engine/ephp.rb + +
    +
    Parent: + + Ephp + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEruby.html new file mode 100644 index 0000000..f9362d6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEruby.html @@ -0,0 +1,127 @@ + + + + + + Class: Erubis::EscapedEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEruby
    In: + + erubis/engine/eruby.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + +
    +

    +swtich ’<%= %>’ to escaped and ’<%== +%>’ to not escaped +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEscheme.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEscheme.html new file mode 100644 index 0000000..8c5e970 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/EscapedEscheme.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::EscapedEscheme + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::EscapedEscheme
    In: + + erubis/engine/escheme.rb + +
    +
    Parent: + + Escheme + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Escheme.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Escheme.html new file mode 100644 index 0000000..53424ba --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Escheme.html @@ -0,0 +1,126 @@ + + + + + + Class: Erubis::Escheme + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Escheme
    In: + + erubis/engine/escheme.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +engine for Scheme +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Evaluator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Evaluator.html new file mode 100644 index 0000000..4314148 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Evaluator.html @@ -0,0 +1,212 @@ + + + + + + Module: Erubis::Evaluator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Evaluator
    In: + + erubis/evaluator.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +evaluate code +

    + +
    + + +
    + +
    +

    Methods

    + +
    + evaluate   + init_evaluator   + result   +
    +
    + +
    + + + + +
    + + + + + +
    +

    Attributes

    + +
    + + + + + + + + + + + +
    filename [RW] 
    src [RW] 
    +
    +
    + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/evaluator.rb, line 34
    +    def evaluate(*args)
    +      raise NotSupportedError.new("evaluation of code except Ruby is not supported.")
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/evaluator.rb, line 26
    +    def init_evaluator(properties)
    +      @filename = properties[:filename]
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/evaluator.rb, line 30
    +    def result(*args)
    +      raise NotSupportedError.new("evaluation of code except Ruby is not supported.")
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/FastEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/FastEruby.html new file mode 100644 index 0000000..2585291 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/FastEruby.html @@ -0,0 +1,131 @@ + + + + + + Class: Erubis::FastEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::FastEruby
    In: + + erubis/engine/eruby.rb + +
    + + erubis/helpers/rails_helper.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + +
    +

    +fast engine for Ruby +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Generator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Generator.html new file mode 100644 index 0000000..0a8c19a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Generator.html @@ -0,0 +1,416 @@ + + + + + + Module: Erubis::Generator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Generator
    In: + + erubis/generator.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +code generator, called by Converter module +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + + +
    + + + + + +
    +

    Attributes

    + +
    + + + + + + +
    escapefunc [RW] 
    +
    +
    + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    +(abstract) add expression code to src for debug. this is called by +add_expr(). +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 72
    +    def add_expr_debug(src, code)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) add escaped expression code to src. this is called by +add_expr(). +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 67
    +    def add_expr_escaped(src, code)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) add expression literal code to src. this is called by +add_expr(). +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 62
    +    def add_expr_literal(src, code)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) add @postamble to src +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 77
    +    def add_postamble(src)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) add @preamble to src +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 47
    +    def add_preamble(src)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) add statement code to src +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 57
    +    def add_stmt(src, code)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) add text string to src +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 52
    +    def add_text(src, text)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +(abstract) escape text string +

    +

    +ex. +

    +
    +  def escape_text(text)
    +    return text.dump
    +    # or return "'" + text.gsub(/['\\]/, '\\\\\&') + "'"
    +  end
    +
    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 36
    +    def escape_text(text)
    +      not_implemented
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +return escaped expression code (ex. ‘h(…)’ or +‘htmlspecialchars(…)’) +

    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 41
    +    def escaped_expr(code)
    +      code.strip!
    +      return "#{@escapefunc}(#{code})"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/generator.rb, line 24
    +    def init_generator(properties={})
    +      @escapefunc = properties[:escapefunc]
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/HeaderFooterEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/HeaderFooterEnhancer.html new file mode 100644 index 0000000..5e491db --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/HeaderFooterEnhancer.html @@ -0,0 +1,267 @@ + + + + + + Module: Erubis::HeaderFooterEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::HeaderFooterEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +
    +
    experimental
    allow header and footer in eRuby script + +
    +
    +

    +ex. +

    +
    +  ====================
    +  ## without header and footer
    +  $ cat ex1.eruby
    +  <% def list_items(list) %>
    +  <%   for item in list %>
    +  <li><%= item %></li>
    +  <%   end %>
    +  <% end %>
    +
    +  $ erubis -s ex1.eruby
    +  _buf = []; def list_items(list)
    +  ;   for item in list
    +  ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
    +  ';   end
    +  ; end
    +  ;
    +  _buf.join
    +
    +  ## with header and footer
    +  $ cat ex2.eruby
    +  <!--#header:
    +  def list_items(list)
    +   #-->
    +  <%  for item in list %>
    +  <li><%= item %></li>
    +  <%  end %>
    +  <!--#footer:
    +  end
    +   #-->
    +
    +  $ erubis -s -c HeaderFooterEruby ex4.eruby
    +
    +  def list_items(list)
    +   _buf = []; _buf << '
    +  ';  for item in list
    +  ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
    +  ';  end
    +  ; _buf << '
    +  ';
    +  _buf.join
    +  end
    +
    +  ====================
    +
    +

    +this is language-independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_text   + convert   +
    +
    + +
    + + + + +
    + + +
    +

    Constants

    + +
    + + + + + + +
    HEADER_FOOTER_PATTERN=/(.*?)(^[ \t]*)?<!--\#(\w+):(.*?)\#-->([ \t]*\r?\n)?/m
    +
    +
    + + + +
    +

    Attributes

    + +
    + + + + + + + + + + + +
    footer [RW] 
    header [RW] 
    +
    +
    + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 541
    +    def add_text(src, text)
    +      m = nil
    +      text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace|
    +        m = Regexp.last_match
    +        flag_trim = @trim && lspace && rspace
    +        super(src, txt)
    +        content = "#{lspace}#{content}#{rspace}" if flag_trim
    +        super(src, lspace) if !flag_trim && lspace
    +        instance_variable_set("@#{word}", content)
    +        super(src, rspace) if !flag_trim && rspace
    +      end
    +      #rest = $' || text                    # ruby1.8
    +      rest = m ? text[m.end(0)..-1] : text  # ruby1.9
    +      super(src, rest)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 559
    +    def convert(input)
    +      source = super
    +      return @src = "#{@header}#{source}#{@footer}"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/HeaderFooterEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/HeaderFooterEruby.html new file mode 100644 index 0000000..465ac8b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/HeaderFooterEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::HeaderFooterEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::HeaderFooterEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers.html new file mode 100644 index 0000000..8079c6b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers.html @@ -0,0 +1,116 @@ + + + + + + Module: Erubis::Helpers + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Helpers
    In: + + erubis/helpers/rails_form_helper.rb + +
    + + erubis/helpers/rails_helper.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + + +
    + +
    +

    Classes and Modules

    + + Module Erubis::Helpers::RailsFormHelper
    +Module Erubis::Helpers::RailsHelper
    + +
    + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsFormHelper.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsFormHelper.html new file mode 100644 index 0000000..f173a41 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsFormHelper.html @@ -0,0 +1,787 @@ + + + + + + Module: Erubis::Helpers::RailsFormHelper + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Helpers::RailsFormHelper
    In: + + erubis/helpers/rails_form_helper.rb + +
    +
    +
    + + + + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 106
    +  def _pp_check_box_checked?(value, checked_value)
    +    return ActionView::Helpers::InstanceTag::check_box_checked?(value, checked_value)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 46
    +  def _pp_error_tags(value)
    +    return value ? ['<div class="fieldWithErrors">', '</div>'] : ['', '']
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 117
    +  def _pp_radio_button_checked?(value, tag_value)
    +    return ActionView::Helpers::InstanceTag::radio_button_checked?(value, tag_value)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 50
    +  def _pp_remove_error_div(s)
    +    s.sub!(/\A<div class="fieldWithErrors">(.*)<\/div>\z/, '\1')
    +    return s
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 121
    +  def _pp_select(object, method, collection, priority_collection, options={}, html_options={})
    +    return pp_error_on(object, method) do
    +      s = ""
    +      ## start tag
    +      s << "<select id=\"#{object}_#{method}\" name=\"#{object}[#{method}]\""
    +      for key, val in html_options:
    +          s << " #{key}=\"#{val}\""
    +      end
    +      s << ">\n"
    +      ## selected table
    +      key = options.key?(:value) ? :value : (options.key?('value') ? 'value' : nil)
    +      if    key.nil?                ;  selected = "@#{object}.#{method}"
    +      elsif (val=options[key]).nil? ;  selected = nil
    +      elsif val =~ /\A<%=(.*)%>\z/  ;  selected = $1
    +      else                          ;  selected = val.inspect
    +      end
    +      s << "<% _table = {#{selected}=>' selected=\"selected\"'} %>\n" if selected
    +      ## <option> tags
    +      if options[:include_blank] || options['include_blank']
    +        s << "<option value=\"\"></option>\n"
    +      end
    +      unless priority_collection.blank?
    +        _pp_select_options(s, priority_collection, selected, 'delete')
    +        s << "<option value=\"\">-------------</option>\n"
    +      end
    +      _pp_select_options(s, collection, selected, '[]')
    +      ## end tag
    +      s << "</select>"
    +      s
    +    end
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 153
    +  def _pp_select_options(s, collection, selected, operator)
    +    for item in collection
    +      value, text = item.is_a?(Array) ? item : [item, item]
    +      if !selected
    +        t = ''
    +      elsif operator == 'delete'
    +        t = "<%= _table.delete(#{value.inspect}) %>"
    +      else
    +        t = "<%= _table[#{value.inspect}] %>"
    +      end
    +      s << "<option value=\"#{h value}\"#{t}>#{h text}</option>\n"
    +    end
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 99
    +  def pp_check_box(object_name, method, options={}, checked_value="1", unchecked_value="0")
    +    s = check_box(object_name, method, options, checked_value, unchecked_value)
    +    s.sub!(/\schecked=\"checked\"/, '')
    +    s.sub!(/type="checkbox"/, "\\&<%= _pp_check_box_checked?(@#{object_name}.#{method}, #{checked_value.inspect}) ? ' checked=\"checked\"' : '' %>")
    +    return pp_error_on(object_name, method) { _pp_remove_error_div(s) }
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 171
    +  def pp_collection_select(object, method, collection, value_method, text_method, options={}, html_options={})
    +    collection2 = collection.collect { |e|
    +      [e.__send__(value_method), e.__send__(text_method)]
    +    }
    +    return _pp_select(object, method, collection2, nil, options, html_options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 178
    +  def pp_country_select(object, method, priority_countries=nil, options={}, html_options={})
    +    collection = ActionView::Helpers::FormOptionsHelper::COUNTRIES
    +    return _pp_select(object, method, collection, priority_countries, options, html_options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 37
    +  def pp_error_on(object_name, method)
    +    s = ''
    +    s << "<% _stag, _etag = _pp_error_tags(@#{object_name}.errors.on('#{method}')) %>"
    +    s << "<%= _stag %>"
    +    s << yield(object_name, method)
    +    s << "<%= _etag %>"
    +    return s
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 91
    +  def pp_file_field(object_name, method, options={})
    +    return pp_tag_helper(:file_field, object_name, method, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 69
    +  def pp_form_tag(url_for_options={}, options={}, *parameters_for_url, &block)
    +    return form_tag(url_for_options, options, *parameters_for_url, &block)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 87
    +  def pp_hidden_field(object_name, method, options={})
    +    return pp_tag_helper(:hidden_field, object_name, method, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 193
    +  def pp_image_submit_tag(source, options={})
    +    return image_submit_tag(source, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 83
    +  def pp_password_field(object_name, method, options={})
    +    return pp_tag_helper(:password_field, object_name, method, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 110
    +  def pp_radio_button(object_name, method, tag_value, options={})
    +    s = radio_button(object_name, method, tag_value, options)
    +    s.sub!(/\schecked=\"checked\"/, '')
    +    s.sub!(/type="radio"/, "\\&<%= _pp_radio_button_checked?(@#{object_name}.#{method}, #{tag_value.inspect}) ? ' checked=\"checked\"' : '' %>")
    +    return pp_error_on(object_name, method) { _pp_remove_error_div(s) }
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 30
    +  def pp_render_partial(basename)
    +    basename = "_#{basename}" unless basename[0] == ?_
    +    filename = pp_template_filename(basename)
    +    preprocessor = _create_preprocessor(File.read(filename))
    +    return preprocessor.evaluate(_preprocessing_context_object())
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 167
    +  def pp_select(object, method, collection, options={}, html_options={})
    +    return _pp_select(object, method, collection, nil, options, html_options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 189
    +  def pp_submit_tag(value="Save changes", options={})
    +    return submit_tag(value, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 55
    +  def pp_tag_helper(helper, object_name, method, options={})
    +    if object_name.is_a?(ActionView::Helpers::FormHelper)
    +      object_name = object_name.object_name
    +    end
    +    unless options.key?(:value) || options.key?('value')
    +      options['value'] = _?("h @#{object_name}.#{method}")
    +    end
    +    #$stderr.puts "*** debug: pp_tag_helper(): options=#{options.inspect}"
    +    return pp_error_on(object_name, method) {
    +      s = __send__(helper, object_name, method, options)
    +      _pp_remove_error_div(s)
    +    }
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 23
    +  def pp_template_filename(basename)
    +    fname = "#{RAILS_ROOT}/app/views/#{controller.controller_name}/#{basename}.html.erb"
    +    return fname if test(?f, fname)
    +    return  "#{RAILS_ROOT}/app/views/#{controller.controller_name}/#{basename}.rhtml"
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 19
    +  def pp_template_filename(basename)
    +    return "#{RAILS_ROOT}/app/views/#{controller.controller_name}/#{basename}.rhtml"
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 95
    +  def pp_text_area(object_name, method, options={})
    +    return pp_tag_helper(:text_area, object_name, method, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 79
    +  def pp_text_field(object_name, method, options={})
    +    return pp_tag_helper(:text_field, object_name, method, options)
    +  end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_form_helper.rb, line 183
    +  def pp_time_zone_select(object, method, priority_zones=nil, options={}, html_options={})
    +    model = options[:model] || options['model'] || TimeZone
    +    collection = model.all.collect { |e| [e.name, e.to_s] }
    +    return _pp_select(object, method, collection, priority_zones, options, html_options)
    +  end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsHelper.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsHelper.html new file mode 100644 index 0000000..a36f0c7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsHelper.html @@ -0,0 +1,349 @@ + + + + + + Module: Erubis::Helpers::RailsHelper + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Helpers::RailsHelper
    In: + + erubis/helpers/rails_helper.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +helper module for Ruby on Rails +

    +

    +howto: +

    +
      +
    1. add the folliwng code in your ‘config/environment.rb‘ + +
      +  require 'erubis/helpers/rails_helper'
      +  #Erubis::Helpers::RailsHelper.engine_class = Erubis::Eruby # or Erubis::FastEruby
      +  #Erubis::Helpers::RailsHelper.init_properties = {}
      +  #Erubis::Helpers::RailsHelper.show_src = false       # set true for debugging
      +  #Erubis::Helpers::RailsHelper.preprocessing = true   # set true to enable preprocessing
      +
      +
    2. +
    3. restart web server. + +
    4. +
    +

    +if Erubis::Helper::Rails.show_src is true, Erubis prints converted Ruby code into log +file (‘log/development.log’ or so). if false, it doesn‘t. +if nil, Erubis prints converted Ruby code +if ENV[‘RAILS_ENV’] == ‘development’. +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + + +
    + +
    +

    Classes and Modules

    + + Module Erubis::Helpers::RailsHelper::TemplateConverter
    + +
    + + + + + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    +@@engine_class = ::Erubis::FastEruby +

    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 47
    +      def self.engine_class
    +        @@engine_class
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 50
    +      def self.engine_class=(klass)
    +        @@engine_class = klass
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 56
    +      def self.init_properties
    +        @@init_properties
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 59
    +      def self.init_properties=(hash)
    +        @@init_properties = hash
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 74
    +      def self.preprocessing
    +        @@preprocessing
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 77
    +      def self.preprocessing=(flag)
    +        @@preprocessing = flag
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 65
    +      def self.show_src
    +        @@show_src
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 68
    +      def self.show_src=(flag)
    +        @@show_src = flag
    +      end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsHelper/TemplateConverter.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsHelper/TemplateConverter.html new file mode 100644 index 0000000..95f43de --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Helpers/RailsHelper/TemplateConverter.html @@ -0,0 +1,213 @@ + + + + + + Module: Erubis::Helpers::RailsHelper::TemplateConverter + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::Helpers::RailsHelper::TemplateConverter
    In: + + erubis/helpers/rails_helper.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + + + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 107
    +        def _create_preprocessor(template)
    +          return PreprocessingEruby.new(template, :escape=>true)
    +        end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 113
    +        def _logger_info(message)
    +          logger.info message
    +        end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 164
    +      def _logger_info(message)
    +        #logger.info message   # logger.info seems not available in Rails 2.2
    +        ActionController::Base.new.logger.info message
    +      end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helpers/rails_helper.rb, line 110
    +        def _preprocessing_context_object
    +          return self
    +        end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/InterpolationEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/InterpolationEnhancer.html new file mode 100644 index 0000000..d644af7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/InterpolationEnhancer.html @@ -0,0 +1,306 @@ + + + + + + Module: Erubis::InterpolationEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::InterpolationEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +convert "<h1><%=title%></h1>" into "_buf +<< %Q`<h1>#{title}</h1>`" +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 663
    +    def _add_text_to_str(str, text)
    +      return if !text || text.empty?
    +      text.gsub!(/['\#\\]/, '\\\\\&')
    +      str << text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 669
    +    def add_expr_escaped(str, code)
    +      str << "\#{#{escaped_expr(code)}}"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 673
    +    def add_expr_literal(str, code)
    +      str << "\#{#{code}}"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 652
    +    def add_text(src, text)
    +      return if !text || text.empty?
    +      #src << " _buf << %Q`" << text << "`;"
    +      if text[-1] == ?\n
    +        text[-1] = "\\n"
    +        src << " _buf << %Q`" << text << "`\n"
    +      else
    +        src << " _buf << %Q`" << text << "`;"
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 597
    +    def convert_input(src, input)
    +      pat = @pattern
    +      regexp = pat.nil? || pat == '<% %>' ? Basic::Converter::DEFAULT_REGEXP : pattern_regexp(pat)
    +      pos = 0
    +      is_bol = true     # is beginning of line
    +      str = ''
    +      input.scan(regexp) do |indicator, code, tailch, rspace|
    +        match = Regexp.last_match()
    +        len  = match.begin(0) - pos
    +        text = input[pos, len]
    +        pos  = match.end(0)
    +        ch   = indicator ? indicator[0] : nil
    +        lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
    +        is_bol = rspace ? true : false
    +        _add_text_to_str(str, text)
    +        ## * when '<%= %>', do nothing
    +        ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
    +        if ch == ?=              # <%= %>
    +          rspace = nil if tailch && !tailch.empty?
    +          str << lspace if lspace
    +          add_expr(str, code, indicator)
    +          str << rspace if rspace
    +        elsif ch == ?\#          # <%# %>
    +          n = code.count("\n") + (rspace ? 1 : 0)
    +          if @trim && lspace && rspace
    +            add_text(src, str)
    +            str = ''
    +            add_stmt(src, "\n" * n)
    +          else
    +            str << lspace if lspace
    +            add_text(src, str)
    +            str = ''
    +            add_stmt(src, "\n" * n)
    +            str << rspace if rspace
    +          end
    +        else                     # <% %>
    +          if @trim && lspace && rspace
    +            add_text(src, str)
    +            str = ''
    +            add_stmt(src, "#{lspace}#{code}#{rspace}")
    +          else
    +            str << lspace if lspace
    +            add_text(src, str)
    +            str = ''
    +            add_stmt(src, code)
    +            str << rspace if rspace
    +          end
    +        end
    +      end
    +      #rest = $' || input                       # ruby1.8
    +      rest = pos == 0 ? input : input[pos..-1]  # ruby1.9
    +      _add_text_to_str(str, rest)
    +      add_text(src, str)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/InterpolationEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/InterpolationEruby.html new file mode 100644 index 0000000..8716d80 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/InterpolationEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::InterpolationEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::InterpolationEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/JavaGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/JavaGenerator.html new file mode 100644 index 0000000..0e3e39a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/JavaGenerator.html @@ -0,0 +1,359 @@ + + + + + + Module: Erubis::JavaGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::JavaGenerator
    In: + + erubis/engine/ejava.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 68
    +    def add_expr_debug(src, code)
    +      code.strip!
    +      src << @indent if src.empty? || src[-1] == ?\n
    +      src << " System.err.println(\"*** debug: #{code}=\"+(#{code}));"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 64
    +    def add_expr_escaped(src, code)
    +      add_expr_literal(src, escaped_expr(code))
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 58
    +    def add_expr_literal(src, code)
    +      src << @indent if src.empty? || src[-1] == ?\n
    +      code.strip!
    +      src << " #{@buf}.append(#{code});"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 74
    +    def add_postamble(src)
    +      src << "\n" if src[-1] == ?;
    +      src << @indent << "return " << @buf << ".toString();\n"
    +      #src << @indent << "System.out.print(" << @buf << ".toString());\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 32
    +    def add_preamble(src)
    +      src << "#{@indent}#{@bufclass} #{@buf} = new #{@bufclass}();"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 54
    +    def add_stmt(src, code)
    +      src << code
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 41
    +    def add_text(src, text)
    +      return if text.empty?
    +      src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
    +      src << @buf << ".append("
    +      i = 0
    +      text.each_line do |line|
    +        src << "\n" << @indent << '          + ' if i > 0
    +        i += 1
    +        src << '"' << escape_text(line) << '"'
    +      end
    +      src << ");" << (text[-1] == ?\n ? "\n" : "")
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 36
    +    def escape_text(text)
    +      @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
    +      return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 24
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= 'escape'
    +      @indent = properties[:indent] || ''
    +      @buf = properties[:buf] || '_buf'
    +      @bufclass = properties[:bufclass] || 'StringBuffer'
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/JavascriptGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/JavascriptGenerator.html new file mode 100644 index 0000000..c7b5bd7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/JavascriptGenerator.html @@ -0,0 +1,386 @@ + + + + + + Module: Erubis::JavascriptGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::JavascriptGenerator
    In: + + erubis/engine/ejavascript.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 72
    +    def add_expr_debug(src, code)
    +      add_indent(src, @indent)
    +      code.strip!
    +      src << "alert(\"*** debug: #{code}=\"+(#{code}));"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 68
    +    def add_expr_escaped(src, code)
    +      add_expr_literal(src, escaped_expr(code))
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 62
    +    def add_expr_literal(src, code)
    +      add_indent(src, @indent)
    +      code.strip!
    +      src << "#{@buf}.push(#{code});"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 41
    +    def add_indent(src, indent)
    +      src << (src.empty? || src[-1] == ?\n ? indent : ' ')
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 78
    +    def add_postamble(src)
    +      src << "\n" if src[-1] == ?;
    +      if @docwrite
    +        src << @indent << 'document.write(' << @buf << ".join(\"\"));\n"
    +      else
    +        src << @indent << @buf << ".join(\"\");\n"
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 32
    +    def add_preamble(src)
    +      src << "#{@indent}var #{@buf} = [];"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 58
    +    def add_stmt(src, code)
    +      src << code
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 45
    +    def add_text(src, text)
    +      return if text.empty?
    +      add_indent(src, @indent)
    +      src << @buf << '.push("'
    +      s = escape_text(text)
    +      if s[-1] == ?\n
    +        s[-2, 2] = ''
    +        src << s << "\");\n"
    +      else
    +        src << s << "\");"
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 36
    +    def escape_text(text)
    +      @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n\\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
    +      return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 24
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= 'escape'
    +      @indent = properties[:indent] || ''
    +      @buf = properties[:out] || '_buf'
    +      @docwrite = properties[:docwrite] != false  # '!= false' will be removed in the next release
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Main.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Main.html new file mode 100644 index 0000000..e71c516 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/Main.html @@ -0,0 +1,341 @@ + + + + + + Class: Erubis::Main + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::Main
    In: + + erubis/main.rb + +
    +
    Parent: + Object +
    +
    + + +
    + + + +
    + +
    +

    +main class of command +

    +

    +ex. +

    +
    +  Main.main(ARGV)
    +
    + +
    + + +
    + +
    +

    Methods

    + +
    + execute   + main   + new   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/main.rb, line 39
    +    def self.main(argv=ARGV)
    +      status = 0
    +      begin
    +        Main.new.execute(ARGV)
    +      rescue CommandOptionError => ex
    +        $stderr.puts ex.message
    +        status = 1
    +      end
    +      exit(status)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/main.rb, line 50
    +    def initialize
    +      @single_options = "hvxztTSbeBXNUC"
    +      @arg_options    = "pcrfKIlaE" #C
    +      @option_names   = {
    +        'h' => :help,
    +        'v' => :version,
    +        'x' => :source,
    +        'z' => :syntax,
    +        'T' => :unexpand,
    +        't' => :untabify,      # obsolete
    +        'S' => :intern,
    +        'b' => :bodyonly,
    +        'B' => :binding,
    +        'p' => :pattern,
    +        'c' => :context,
    +        #'C' => :class,
    +        'e' => :escape,
    +        'r' => :requires,
    +        'f' => :datafiles,
    +        'K' => :kanji,
    +        'I' => :includes,
    +        'l' => :lang,
    +        'a' => :action,
    +        'E' => :enhancers,
    +        'X' => :notext,
    +        'N' => :linenum,
    +        'U' => :unique,
    +        'C' => :compact,
    +      }
    +      assert unless @single_options.length + @arg_options.length == @option_names.length
    +      (@single_options + @arg_options).each_byte do |ch|
    +        assert unless @option_names.key?(ch.chr)
    +      end
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/main.rb, line 86
    +    def execute(argv=ARGV)
    +      ## parse command-line options
    +      options, properties = parse_argv(argv, @single_options, @arg_options)
    +      filenames = argv
    +      options['h'] = true if properties[:help]
    +      opts = Object.new
    +      arr = @option_names.collect {|ch, name| "def #{name}; @#{name}; end\n" }
    +      opts.instance_eval arr.join
    +      options.each do |ch, val|
    +        name = @option_names[ch]
    +        opts.instance_variable_set("@#{name}", val)
    +      end
    +
    +      ## help, version, enhancer list
    +      if opts.help || opts.version
    +        puts version()         if opts.version
    +        puts usage()           if opts.help
    +        puts show_properties() if opts.help
    +        puts show_enhancers()  if opts.help
    +        return
    +      end
    +
    +      ## include path
    +      opts.includes.split(/,/).each do |path|
    +        $: << path
    +      end if opts.includes
    +
    +      ## require library
    +      opts.requires.split(/,/).each do |library|
    +        require library
    +      end if opts.requires
    +
    +      ## action
    +      action = opts.action
    +      action ||= 'syntax'  if opts.syntax
    +      action ||= 'convert' if opts.source || opts.notext
    +
    +      ## lang
    +      lang = opts.lang || 'ruby'
    +      action ||= 'convert' if opts.lang
    +
    +      ## class name of Eruby
    +      #classname = opts.class
    +      classname = nil
    +      klass = get_classobj(classname, lang, properties[:pi])
    +
    +      ## kanji code
    +      $KCODE = opts.kanji if opts.kanji
    +
    +      ## read context values from yaml file
    +      datafiles = opts.datafiles
    +      context = load_datafiles(datafiles, opts)
    +
    +      ## parse context data
    +      if opts.context
    +        context = parse_context_data(opts.context, opts)
    +      end
    +
    +      ## properties for engine
    +      properties[:escape]   = true         if opts.escape && !properties.key?(:escape)
    +      properties[:pattern]  = opts.pattern if opts.pattern
    +      #properties[:trim]     = false        if opts.notrim
    +      properties[:preamble] = properties[:postamble] = false if opts.bodyonly
    +      properties[:pi]       = nil          if properties[:pi] == true
    +
    +      ## create engine and extend enhancers
    +      engine = klass.new(nil, properties)
    +      enhancers = get_enhancers(opts.enhancers)
    +      #enhancers.push(Erubis::EscapeEnhancer) if opts.escape
    +      enhancers.each do |enhancer|
    +        engine.extend(enhancer)
    +        engine.bipattern = properties[:bipattern] if enhancer == Erubis::BiPatternEnhancer
    +      end
    +
    +      ## no-text
    +      engine.extend(Erubis::NoTextEnhancer) if opts.notext
    +
    +      ## convert and execute
    +      val = nil
    +      msg = "Syntax OK\n"
    +      if filenames && !filenames.empty?
    +        filenames.each do |filename|
    +          File.file?(filename)  or
    +            raise CommandOptionError.new("#{filename}: file not found.")
    +          engine.filename = filename
    +          engine.convert!(File.read(filename))
    +          val = do_action(action, engine, context, filename, opts)
    +          msg = nil if val
    +        end
    +      else
    +        engine.filename = filename = '(stdin)'
    +        engine.convert!($stdin.read())
    +        val = do_action(action, engine, context, filename, opts)
    +        msg = nil if val
    +      end
    +      print msg if action == 'syntax' && msg
    +
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoCodeEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoCodeEnhancer.html new file mode 100644 index 0000000..f5c41cd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoCodeEnhancer.html @@ -0,0 +1,249 @@ + + + + + + Module: Erubis::NoCodeEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::NoCodeEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +remove code and leave text, especially useful when validating HTML tags. +

    +

    +ex. +

    +
    +  $ erubis -s -E NoCode file.eruby | tidy -errors
    +
    +

    +this is language independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_expr   + add_postamble   + add_preamble   + add_stmt   + add_text   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 317
    +    def add_expr(src, code, indicator)
    +      src << "\n" * code.count("\n")
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 310
    +    def add_postamble(src)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 307
    +    def add_preamble(src)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 321
    +    def add_stmt(src, code)
    +      src << "\n" * code.count("\n")
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 313
    +    def add_text(src, text)
    +      src << text
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoCodeEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoCodeEruby.html new file mode 100644 index 0000000..f52b4d0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoCodeEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::NoCodeEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::NoCodeEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoTextEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoTextEnhancer.html new file mode 100644 index 0000000..6724667 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoTextEnhancer.html @@ -0,0 +1,159 @@ + + + + + + Module: Erubis::NoTextEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::NoTextEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +remove text and leave code, especially useful when debugging. +

    +

    +ex. +

    +
    +  $ erubis -s -E NoText file.eruby | more
    +
    +

    +this is language independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_text   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 282
    +    def add_text(src, text)
    +      src << ("\n" * text.count("\n"))
    +      if text[-1] != ?\n
    +        text =~ /^(.*?)\z/
    +        src << (' ' * $1.length)
    +      end
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoTextEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoTextEruby.html new file mode 100644 index 0000000..c6094c0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NoTextEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::NoTextEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::NoTextEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NotSupportedError.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NotSupportedError.html new file mode 100644 index 0000000..c3c75b7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/NotSupportedError.html @@ -0,0 +1,119 @@ + + + + + + Class: Erubis::NotSupportedError + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::NotSupportedError
    In: + + erubis/error.rb + +
    +
    Parent: + + ErubisError + +
    +
    + + +
    + + + +
    + +
    +

    +raised when method or function is not supported +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedEruby.html new file mode 100644 index 0000000..6e9a24d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedEruby.html @@ -0,0 +1,163 @@ + + + + + + Class: Erubis::OptimizedEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::OptimizedEruby
    In: + + erubis/engine/optimized.rb + +
    +
    Parent: + + Basic::Engine + +
    +
    + + +
    + + + +
    + +
    +

    +Eruby class which generates optimized ruby code +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 106
    +    def init_converter(properties={})
    +      @pi = 'rb'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedGenerator.html new file mode 100644 index 0000000..42ecd44 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedGenerator.html @@ -0,0 +1,439 @@ + + + + + + Module: Erubis::OptimizedGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::OptimizedGenerator
    In: + + erubis/engine/optimized.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 20
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= "Erubis::XmlHelper.escape_xml"
    +      @initialized = false
    +      @prev_is_expr = false
    +    end
    +
    +
    +
    +
    + +

    Protected Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 85
    +    def add_expr_debug(src, code)
    +      code.strip!
    +      s = (code.dump =~ /\A"(.*)"\z/) && $1
    +      src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 79
    +    def add_expr_escaped(src, code)
    +      unless @initialized; src << "_buf = ''"; @initialized = true; end
    +      switch_to_expr(src)
    +      src << " << " << escaped_expr(code)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 73
    +    def add_expr_literal(src, code)
    +      unless @initialized; src << "_buf = ''"; @initialized = true; end
    +      switch_to_expr(src)
    +      src << " << (" << code << ").to_s"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 91
    +    def add_postamble(src)
    +      #super if @initialized
    +      src << "\n_buf\n" if @initialized
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 50
    +    def add_preamble(src)
    +      #@initialized = false
    +      #@prev_is_expr = false
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 66
    +    def add_stmt(src, code)
    +      switch_to_stmt(src) if @initialized
    +      #super
    +      src << code
    +      src << ';' unless code[-1] == ?\n
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 55
    +    def add_text(src, text)
    +      return if text.empty?
    +      if @initialized
    +        switch_to_expr(src)
    +        src << " << '" << escape_text(text) << "'"
    +      else
    +        src << "_buf = '" << escape_text(text) << "';"
    +        @initialized = true
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 29
    +    def escape_text(text)
    +      text.gsub(/['\\]/, '\\\\\&')   # "'" => "\\'",  '\\' => '\\\\'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 33
    +    def escaped_expr(code)
    +      @escapefunc ||= 'Erubis::XmlHelper.escape_xml'
    +      return "#{@escapefunc}(#{code})"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 38
    +    def switch_to_expr(src)
    +      return if @prev_is_expr
    +      @prev_is_expr = true
    +      src << ' _buf'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 44
    +    def switch_to_stmt(src)
    +      return unless @prev_is_expr
    +      @prev_is_expr = false
    +      src << ';'
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedXmlEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedXmlEruby.html new file mode 100644 index 0000000..a0cdec6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/OptimizedXmlEruby.html @@ -0,0 +1,163 @@ + + + + + + Class: Erubis::OptimizedXmlEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::OptimizedXmlEruby
    In: + + erubis/engine/optimized.rb + +
    +
    Parent: + + OptimizedEruby + +
    +
    + + +
    + + + +
    + +
    +

    +XmlEruby class which generates optimized ruby +code +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_expr_debug   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/optimized.rb, line 120
    +    def add_expr_debug(src, code)
    +      switch_to_stmt(src) if indicator == '===' && !@initialized
    +      super
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI.html new file mode 100644 index 0000000..c9b3af1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI.html @@ -0,0 +1,124 @@ + + + + + + Module: Erubis::PI + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PI
    In: + + erubis/converter.rb + +
    + + erubis/tiny.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + + +
    + + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Converter.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Converter.html new file mode 100644 index 0000000..73fe22e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Converter.html @@ -0,0 +1,266 @@ + + + + + + Module: Erubis::PI::Converter + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PI::Converter
    In: + + erubis/converter.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +Processing Instructions (PI) converter for XML. +this class converts ’<?rb … ?>’ and +’${…}’ notation. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + convert   + convert_input   + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + +
    +

    Attributes

    + +
    + + + + + + + + + + + +
    pi [RW] 
    prefix [RW] 
    +
    +
    + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 224
    +    def convert(input)
    +      code = super(input)
    +      return @header || @footer ? "#{@header}#{code}#{@footer}" : code
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 215
    +    def init_converter(properties={})
    +      super(properties)
    +      @trim    = properties.fetch(:trim, true)
    +      @pi      = properties[:pi] if properties[:pi]
    +      @embchar = properties[:embchar] || '@'
    +      @pattern = properties[:pattern]
    +      @pattern = '<% %>' if @pattern.nil?  #|| @pattern == true
    +    end
    +
    +
    +
    +
    + +

    Protected Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/converter.rb, line 231
    +    def convert_input(codebuf, input)
    +      unless @regexp
    +        @pi ||= 'e'
    +        ch = Regexp.escape(@embchar)
    +        if @pattern
    +          left, right = @pattern.split(' ')
    +          @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/m
    +        else
    +          @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}/m
    +        end
    +      end
    +      #
    +      is_bol = true
    +      pos = 0
    +      input.scan(@regexp) do |pi_arg, stmt, rspace,
    +                              indicator1, expr1, indicator2, expr2|
    +        match = Regexp.last_match
    +        len = match.begin(0) - pos
    +        text = input[pos, len]
    +        pos = match.end(0)
    +        lspace = stmt ? detect_spaces_at_bol(text, is_bol) : nil
    +        is_bol = stmt && rspace ? true : false
    +        add_text(codebuf, text) # unless text.empty?
    +        #
    +        if stmt
    +          if @trim && lspace && rspace
    +            add_pi_stmt(codebuf, "#{lspace}#{stmt}#{rspace}", pi_arg)
    +          else
    +            add_text(codebuf, lspace) if lspace
    +            add_pi_stmt(codebuf, stmt, pi_arg)
    +            add_text(codebuf, rspace) if rspace
    +          end
    +        else
    +          add_pi_expr(codebuf, expr1 || expr2, indicator1 || indicator2)
    +        end
    +      end
    +      #rest = $' || input                        # ruby1.8
    +      rest = pos == 0 ? input : input[pos..-1]   # ruby1.9
    +      add_text(codebuf, rest)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ec.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ec.html new file mode 100644 index 0000000..fb110f7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ec.html @@ -0,0 +1,166 @@ + + + + + + Class: Erubis::PI::Ec + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Ec
    In: + + erubis/engine/ec.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + +
    +

    +class XmlEc < Ec +

    +
    +  include EscapeEnhancer
    +
    +

    +end +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ec.rb, line 109
    +    def init_converter(properties={})
    +      @pi = 'c'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ejava.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ejava.html new file mode 100644 index 0000000..73935ef --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ejava.html @@ -0,0 +1,166 @@ + + + + + + Class: Erubis::PI::Ejava + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Ejava
    In: + + erubis/engine/ejava.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + +
    +

    +class XmlEjava < Ejava +

    +
    +  include EscapeEnhancer
    +
    +

    +end +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejava.rb, line 103
    +    def init_converter(properties={})
    +      @pi = 'java'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ejavascript.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ejavascript.html new file mode 100644 index 0000000..5efccf1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ejavascript.html @@ -0,0 +1,166 @@ + + + + + + Class: Erubis::PI::Ejavascript + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Ejavascript
    In: + + erubis/engine/ejavascript.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + +
    +

    +class XmlEjavascript < Ejavascript +

    +
    +  include EscapeEnhancer
    +
    +

    +end +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ejavascript.rb, line 111
    +    def init_converter(properties={})
    +      @pi = 'js'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Engine.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Engine.html new file mode 100644 index 0000000..beb659a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Engine.html @@ -0,0 +1,122 @@ + + + + + + Class: Erubis::PI::Engine + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Engine
    In: + + erubis/engine.rb + +
    +
    Parent: + + Engine + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Eperl.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Eperl.html new file mode 100644 index 0000000..d6b2c7a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Eperl.html @@ -0,0 +1,166 @@ + + + + + + Class: Erubis::PI::Eperl + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Eperl
    In: + + erubis/engine/eperl.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + +
    +

    +class XmlEperl < Eperl +

    +
    +  include EscapeEnhancer
    +
    +

    +end +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 87
    +    def init_converter(properties={})
    +      @pi = 'perl'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ephp.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ephp.html new file mode 100644 index 0000000..81b37f0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Ephp.html @@ -0,0 +1,166 @@ + + + + + + Class: Erubis::PI::Ephp + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Ephp
    In: + + erubis/engine/ephp.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + +
    +

    +class XmlEphp < Ephp +

    +
    +  include EscapeEnhancer
    +
    +

    +end +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 91
    +    def init_converter(properties={})
    +      @pi = 'php'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Eruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Eruby.html new file mode 100644 index 0000000..adc262b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Eruby.html @@ -0,0 +1,155 @@ + + + + + + Class: Erubis::PI::Eruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Eruby
    In: + + erubis/engine/eruby.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 116
    +    def init_converter(properties={})
    +      @pi = 'rb'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Escheme.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Escheme.html new file mode 100644 index 0000000..d0594fd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/Escheme.html @@ -0,0 +1,166 @@ + + + + + + Class: Erubis::PI::Escheme + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::Escheme
    In: + + erubis/engine/escheme.rb + +
    +
    Parent: + PI::Engine +
    +
    + + +
    + + + +
    + +
    +

    +class XmlEscheme < Escheme +

    +
    +  include EscapeEnhancer
    +
    +

    +end +

    + +
    + + +
    + +
    +

    Methods

    + +
    + init_converter   +
    +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 106
    +    def init_converter(properties={})
    +      @pi = 'scheme'
    +      super(properties)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/TinyEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/TinyEruby.html new file mode 100644 index 0000000..c88cf9f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PI/TinyEruby.html @@ -0,0 +1,293 @@ + + + + + + Class: Erubis::PI::TinyEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PI::TinyEruby
    In: + + erubis/tiny.rb + +
    +
    Parent: + Object +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + +
    + convert   + evaluate   + new   + result   +
    +
    + +
    + + + + +
    + + +
    +

    Constants

    + +
    + + + + + + +
    EMBEDDED_PATTERN=/(^[ \t]*)?<\?rb(\s.*?)\?>([ \t]*\r?\n)?|@(!+)?\{(.*?)\}@/m
    +
    +
    + + + +
    +

    Attributes

    + +
    + + + + + + +
    src [R] 
    +
    +
    + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 79
    +    def initialize(input=nil, options={})
    +      @escape  = options[:escape] || 'Erubis::XmlHelper.escape_xml'
    +      @src = convert(input) if input
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 88
    +    def convert(input)
    +      src = "_buf = '';"           # preamble
    +      pos = 0
    +      input.scan(EMBEDDED_PATTERN) do |lspace, stmt, rspace, indicator, expr|
    +        match = Regexp.last_match
    +        len   = match.begin(0) - pos
    +        text  = input[pos, len]
    +        pos   = match.end(0)
    +        #src << " _buf << '" << escape_text(text) << "';"
    +        text.gsub!(/['\\]/, '\\\\\&')
    +        src << " _buf << '" << text << "';" unless text.empty?
    +        if stmt                # <?rb ... ?>
    +          if lspace && rspace
    +            src << "#{lspace}#{stmt}#{rspace}"
    +          else
    +            src << " _buf << '" << lspace << "';" if lspace
    +            src << stmt << ";"
    +            src << " _buf << '" << rspace << "';" if rspace
    +          end
    +        else                       # ${...}, $!{...}
    +          if !indicator
    +            src << " _buf << " << @escape << "(" << expr << ");"
    +          elsif indicator == '!'
    +            src << " _buf << (" << expr << ").to_s;"
    +          end
    +        end
    +      end
    +      #rest = $' || input                        # ruby1.8
    +      rest = pos == 0 ? input : input[pos..-1]   # ruby1.9
    +      #src << " _buf << '" << escape_text(rest) << "';"
    +      rest.gsub!(/['\\]/, '\\\\\&')
    +      src << " _buf << '" << rest << "';" unless rest.empty?
    +      src << "\n_buf.to_s\n"       # postamble
    +      return src
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 132
    +    def evaluate(_context=Object.new)
    +      if _context.is_a?(Hash)
    +        _obj = Object.new
    +        _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end
    +        _context = _obj
    +      end
    +      _context.instance_eval @src
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +def escape_text(text) +

    +
    +  return text.gsub!(/['\\]/, '\\\\\&') || text
    +
    +

    +end +

    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 128
    +    def result(_binding=TOPLEVEL_BINDING)
    +      eval @src, _binding
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PercentLineEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PercentLineEnhancer.html new file mode 100644 index 0000000..0413d5a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PercentLineEnhancer.html @@ -0,0 +1,179 @@ + + + + + + Module: Erubis::PercentLineEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PercentLineEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +regards lines starting with ’%’ as program code +

    +

    +this is for compatibility to eruby and ERB. +

    +

    +this is language-independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_text   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 449
    +    def add_text(src, text)
    +      pos = 0
    +      text2 = ''
    +      text.scan(/^\%(.*?\r?\n)/) do
    +        line  = $1
    +        match = Regexp.last_match
    +        len   = match.begin(0) - pos
    +        str   = text[pos, len]
    +        pos   = match.end(0)
    +        if text2.empty?
    +          text2 = str
    +        else
    +          text2 << str
    +        end
    +        if line[0] == ?%
    +          text2 << line
    +        else
    +          super(src, text2)
    +          text2 = ''
    +          add_stmt(src, line)
    +        end
    +      end
    +      #rest = pos == 0 ? text : $'             # ruby1.8
    +      rest = pos == 0 ? text : text[pos..-1]   # ruby1.9
    +      unless text2.empty?
    +        text2 << rest if rest
    +        rest = text2
    +      end
    +      super(src, rest)
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PercentLineEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PercentLineEruby.html new file mode 100644 index 0000000..8621292 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PercentLineEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::PercentLineEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PercentLineEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PerlGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PerlGenerator.html new file mode 100644 index 0000000..3769676 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PerlGenerator.html @@ -0,0 +1,344 @@ + + + + + + Module: Erubis::PerlGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PerlGenerator
    In: + + erubis/engine/eperl.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 49
    +    def add_expr_debug(src, code)
    +      code.strip!
    +      s = code.gsub(/\'/, "\\'")
    +      src << @func << "('*** debug: #{code}=', #{code}, \"\\n\");"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 45
    +    def add_expr_escaped(src, code)
    +      add_expr_literal(src, escaped_expr(code))
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 40
    +    def add_expr_literal(src, code)
    +      code.strip!
    +      src << @func << "(" << code << "); "
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 59
    +    def add_postamble(src)
    +      src << "\n" unless src[-1] == ?\n
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 28
    +    def add_preamble(src)
    +      src << "use HTML::Entities; ";
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 55
    +    def add_stmt(src, code)
    +      src << code
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 36
    +    def add_text(src, text)
    +      src << @func << "('" << escape_text(text) << "'); " unless text.empty?
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 32
    +    def escape_text(text)
    +      return text.gsub!(/['\\]/, '\\\\\&') || text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eperl.rb, line 22
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= 'encode_entities'
    +      @func = properties[:func] || 'print'
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PhpGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PhpGenerator.html new file mode 100644 index 0000000..7219814 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PhpGenerator.html @@ -0,0 +1,350 @@ + + + + + + Module: Erubis::PhpGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PhpGenerator
    In: + + erubis/engine/ephp.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 46
    +    def add_expr_debug(src, code)
    +      code.strip!
    +      s = code.gsub(/\'/, "\\'")
    +      src << "<?php error_log('*** debug: #{s}='.(#{code}), 0); ?>"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 42
    +    def add_expr_escaped(src, code)
    +      add_expr_literal(src, escaped_expr(code))
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 37
    +    def add_expr_literal(src, code)
    +      code.strip!
    +      src << "<?php echo #{code}; ?>"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 63
    +    def add_postamble(src)
    +      # empty
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 25
    +    def add_preamble(src)
    +      # empty
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 52
    +    def add_stmt(src, code)
    +      src << "<?php"
    +      src << " " if code[0] != ?\ #
    +      if code[-1] == ?\n
    +        code.chomp!
    +        src << code << "?>\n"
    +      else
    +        src << code << "?>"
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 33
    +    def add_text(src, text)
    +      src << escape_text(text)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 29
    +    def escape_text(text)
    +      return text.gsub!(/<\?xml\b/, '<<?php ?>?xml') || text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/ephp.rb, line 20
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= 'htmlspecialchars'
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PreprocessingEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PreprocessingEruby.html new file mode 100644 index 0000000..dbb1a6c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PreprocessingEruby.html @@ -0,0 +1,183 @@ + + + + + + Class: Erubis::PreprocessingEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PreprocessingEruby
    In: + + erubis/preprocessing.rb + +
    +
    Parent: + + Erubis::Eruby + +
    +
    + + +
    + + + +
    + +
    +

    +for preprocessing +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_expr_escaped   + new   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/preprocessing.rb, line 17
    +    def initialize(input, params={})
    +      params = params.dup
    +      params[:pattern] ||= '\[% %\]'    # use '[%= %]' instead of '<%= %>'
    +      #params[:escape] = true            # transport '[%= %]' and '[%== %]'
    +      super
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/preprocessing.rb, line 24
    +    def add_expr_escaped(src, code)
    +      add_expr_literal(src, "_decode((#{code}))")
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PreprocessingHelper.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PreprocessingHelper.html new file mode 100644 index 0000000..071035b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PreprocessingHelper.html @@ -0,0 +1,212 @@ + + + + + + Module: Erubis::PreprocessingHelper + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PreprocessingHelper
    In: + + erubis/preprocessing.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +helper methods for preprocessing +

    + +
    + + +
    + +
    +

    Methods

    + +
    + _?   + _P   + _decode   + _p   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + +
    + _?(arg) +
    + +
    +

    +Alias for _p +

    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/preprocessing.rb, line 42
    +    def _P(arg)
    +      return "<%=h(#{arg})%>"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/preprocessing.rb, line 48
    +    def _decode(arg)
    +      arg = arg.to_s
    +      arg.gsub!(/%3C%25(?:=|%3D)(.*?)%25%3E/) { "<%=#{CGI.unescape($1)}%>" }
    +      arg.gsub!(/&lt;%=(.*?)%&gt;/) { "<%=#{CGI.unescapeHTML($1)}%>" }
    +      return arg
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/preprocessing.rb, line 38
    +    def _p(arg)
    +      return "<%=#{arg}%>"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintEnabledEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintEnabledEnhancer.html new file mode 100644 index 0000000..27d3b4e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintEnabledEnhancer.html @@ -0,0 +1,212 @@ + + + + + + Module: Erubis::PrintEnabledEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PrintEnabledEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +enable print function +

    +

    +Notice: use Eruby#evaluate() and don‘t use Eruby#result() to be +enable print function. +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_preamble   + evaluate   + print   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 127
    +    def add_preamble(src)
    +      src << "@_buf = "
    +      super
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 138
    +    def evaluate(context=nil)
    +      _src = @src
    +      if context.is_a?(Hash)
    +        context.each do |key, val| instance_variable_set("@#{key}", val) end
    +      elsif context
    +        context.instance_variables.each do |name|
    +          instance_variable_set(name, context.instance_variable_get(name))
    +        end
    +      end
    +      return instance_eval(_src, (@filename || '(erubis)'))
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 132
    +    def print(*args)
    +      args.each do |arg|
    +        @_buf << arg.to_s
    +      end
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintEnabledEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintEnabledEruby.html new file mode 100644 index 0000000..c4efc94 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintEnabledEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::PrintEnabledEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PrintEnabledEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutEnhancer.html new file mode 100644 index 0000000..f1852aa --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutEnhancer.html @@ -0,0 +1,244 @@ + + + + + + Module: Erubis::PrintOutEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::PrintOutEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +use print statement instead of ‘_buf << …’ +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 102
    +    def add_expr_escaped(src, code)
    +      src << ' print ' << escaped_expr(code) << ';'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 98
    +    def add_expr_literal(src, code)
    +      src << ' print((' << code << ').to_s);'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 106
    +    def add_postamble(src)
    +      src << "\n" unless src[-1] == ?\n
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 91
    +    def add_preamble(src)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 94
    +    def add_text(src, text)
    +      src << " print '" << escape_text(text) << "';" unless text.empty?
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutEruby.html new file mode 100644 index 0000000..b3a9b22 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::PrintOutEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PrintOutEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutSimplifiedEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutSimplifiedEruby.html new file mode 100644 index 0000000..8800630 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/PrintOutSimplifiedEruby.html @@ -0,0 +1,121 @@ + + + + + + Class: Erubis::PrintOutSimplifiedEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::PrintOutSimplifiedEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/RubyEvaluator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/RubyEvaluator.html new file mode 100644 index 0000000..b471161 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/RubyEvaluator.html @@ -0,0 +1,227 @@ + + + + + + Module: Erubis::RubyEvaluator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::RubyEvaluator
    In: + + erubis/evaluator.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +evaluator for Ruby +

    + +
    + + +
    + +
    +

    Methods

    + +
    + def_method   + evaluate   + result   +
    +
    + +
    + + + +
    +

    Included Modules

    + +
    + Evaluator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    +if object is an Class or Module then define instance method to it, else +define singleton method to it. +

    +

    [Source]

    +
    +
    +# File erubis/evaluator.rb, line 79
    +    def def_method(object, method_name, filename=nil)
    +      m = object.is_a?(Module) ? :module_eval : :instance_eval
    +      object.__send__(m, "def #{method_name}; #{@src}; end", filename || @filename || '(erubis)')
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +invoke context.instance_eval(@src) +

    +

    [Source]

    +
    +
    +# File erubis/evaluator.rb, line 69
    +    def evaluate(_context=Context.new)
    +      _context = Context.new(_context) if _context.is_a?(Hash)
    +      #return _context.instance_eval(@src, @filename || '(erubis)')
    +      #@_proc ||= eval("proc { #{@src} }", Erubis::EMPTY_BINDING, @filename || '(erubis)')
    +      @_proc ||= eval("proc { #{@src} }", binding(), @filename || '(erubis)')
    +      return _context.instance_eval(&@_proc)
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +eval(@src) with binding object +

    +

    [Source]

    +
    +
    +# File erubis/evaluator.rb, line 53
    +    def result(_binding_or_hash=TOPLEVEL_BINDING)
    +      _arg = _binding_or_hash
    +      if _arg.is_a?(Hash)
    +        _b = binding()
    +        eval _arg.collect{|k,v| "#{k} = _arg[#{k.inspect}]; "}.join, _b
    +      elsif _arg.is_a?(Binding)
    +        _b = _arg
    +      elsif _arg.nil?
    +        _b = binding()
    +      else
    +        raise ArgumentError.new("#{self.class.name}#result(): argument should be Binding or Hash but passed #{_arg.class.name} object.")
    +      end
    +      return eval(@src, _b, (@filename || '(erubis'))
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/RubyGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/RubyGenerator.html new file mode 100644 index 0000000..3e515f8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/RubyGenerator.html @@ -0,0 +1,327 @@ + + + + + + Module: Erubis::RubyGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::RubyGenerator
    In: + + erubis/engine/eruby.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +code generator for Ruby +

    + +
    + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 62
    +    def add_expr_debug(src, code)
    +      code.strip!
    +      s = (code.dump =~ /\A"(.*)"\z/) && $1
    +      src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 58
    +    def add_expr_escaped(src, code)
    +      src << ' _buf << ' << escaped_expr(code) << ';'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 54
    +    def add_expr_literal(src, code)
    +      src << ' _buf << (' << code << ').to_s;'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 48
    +    def add_stmt(src, code)
    +      #src << code << ';'
    +      src << code
    +      src << ';' unless code[-1] == ?\n
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 44
    +    def add_text(src, text)
    +      src << " _buf << '" << escape_text(text) << "';" unless text.empty?
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 30
    +    def escape_text(text)
    +      text.gsub(/['\\]/, '\\\\\&')   # "'" => "\\'",  '\\' => '\\\\'
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 34
    +    def escaped_expr(code)
    +      return "#{@escapefunc}(#{code})"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/eruby.rb, line 21
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= "Erubis::XmlHelper.escape_xml"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SchemeGenerator.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SchemeGenerator.html new file mode 100644 index 0000000..5b6b299 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SchemeGenerator.html @@ -0,0 +1,382 @@ + + + + + + Module: Erubis::SchemeGenerator + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::SchemeGenerator
    In: + + erubis/engine/escheme.rb + +
    +
    +
    + + +
    + + + +
    + + + +
    + +
    +

    Methods

    + + +
    + +
    + + + +
    +

    Included Modules

    + +
    + Generator +
    +
    + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 71
    +    def add_expr_debug(src, code)
    +      s = (code.strip! || code).gsub(/\"/, '\\"')
    +      src << "(display \"*** debug: #{s}=\")(display #{code.strip})(display \"\\n\")"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 67
    +    def add_expr_escaped(src, code)
    +      add_expr_literal(src, escaped_expr(code))
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 62
    +    def add_expr_literal(src, code)
    +      code.strip!
    +      src << "(#{@func} #{code})"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 76
    +    def add_postamble(src)
    +      return unless @func == '_add'
    +      src << "\n" unless src[-1] == ?\n
    +      src << "  (reverse _buf))\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 28
    +    def add_preamble(src)
    +      return unless @func == '_add'
    +      src << "(let ((_buf '())) " + \
    +               "(define (_add x) (set! _buf (cons x _buf))) "
    +      #src << "(let* ((_buf '())" +        #             " (_add (lambda (x) (set! _buf (cons x _buf))))) "
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 58
    +    def add_stmt(src, code)
    +      src << code
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 47
    +    def add_text(src, text)
    +      return if text.empty?
    +      t = escape_text(text)
    +      if t[-1] == ?\n
    +        t[-1, 1] = ''
    +        src << "(#{@func} \"" << t << "\\n\")\n"
    +      else
    +        src << "(#{@func} \"" << t << '")'
    +      end
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 36
    +    def escape_text(text)
    +      @table_ ||= { '"'=>'\\"', '\\'=>'\\\\' }
    +      text.gsub!(/["\\]/) { |m| @table_[m] }
    +      return text
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 42
    +    def escaped_expr(code)
    +      code.strip!
    +      return "(#{@escapefunc} #{code})"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/engine/escheme.rb, line 22
    +    def init_generator(properties={})
    +      super
    +      @escapefunc ||= 'escape'
    +      @func = properties[:func] || '_add'   # or 'display'
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SimplifiedEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SimplifiedEruby.html new file mode 100644 index 0000000..01adfea --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SimplifiedEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::SimplifiedEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::SimplifiedEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SimplifyEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SimplifyEnhancer.html new file mode 100644 index 0000000..8d81804 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/SimplifyEnhancer.html @@ -0,0 +1,191 @@ + + + + + + Module: Erubis::SimplifyEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::SimplifyEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +get convert faster, but spaces +around ’<%…%>’ are not trimmed. +

    +

    +this is language-independent. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + convert   +
    +
    + +
    + + + + +
    + + +
    +

    Constants

    + +
    + + + + + + + + +
    SIMPLE_REGEXP=/<%(=+|\#)?(.*?)-?%>/m  +DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + +
    +
    +
    + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 342
    +    def convert(input)
    +      src = ""
    +      add_preamble(src)
    +      #regexp = pattern_regexp(@pattern)
    +      pos = 0
    +      input.scan(SIMPLE_REGEXP) do |indicator, code|
    +        match = Regexp.last_match
    +        index = match.begin(0)
    +        text  = input[pos, index - pos]
    +        pos   = match.end(0)
    +        add_text(src, text)
    +        if !indicator              # <% %>
    +          add_stmt(src, code)
    +        elsif indicator[0] == ?\#  # <%# %>
    +          n = code.count("\n")
    +          add_stmt(src, "\n" * n)
    +        else                       # <%= %>
    +          add_expr(src, code, indicator)
    +        end
    +      end
    +      #rest = $' || input                      # ruby1.8
    +      rest = pos == 0 ? input : input[pos..-1]  # ruby1.9
    +      add_text(src, rest)
    +      add_postamble(src)
    +      return src
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutEnhancer.html new file mode 100644 index 0000000..4490254 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutEnhancer.html @@ -0,0 +1,173 @@ + + + + + + Module: Erubis::StdoutEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::StdoutEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +use $stdout instead of string +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_postamble   + add_preamble   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 73
    +    def add_postamble(src)
    +      src << "\n''\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 69
    +    def add_preamble(src)
    +      src << "_buf = $stdout;"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutEruby.html new file mode 100644 index 0000000..bd6eadb --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::StdoutEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::StdoutEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutSimplifiedEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutSimplifiedEruby.html new file mode 100644 index 0000000..e6ec46d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StdoutSimplifiedEruby.html @@ -0,0 +1,121 @@ + + + + + + Class: Erubis::StdoutSimplifiedEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::StdoutSimplifiedEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringBufferEnhancer.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringBufferEnhancer.html new file mode 100644 index 0000000..2438197 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringBufferEnhancer.html @@ -0,0 +1,174 @@ + + + + + + Module: Erubis::StringBufferEnhancer + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::StringBufferEnhancer
    In: + + erubis/enhancer.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +use String class for buffering +

    +

    +this is only for Eruby. +

    + +
    + + +
    + +
    +

    Methods

    + +
    + add_postamble   + add_preamble   +
    +
    + +
    + + + + +
    + + + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 214
    +    def add_postamble(src)
    +      src << "\n" unless src[-1] == ?\n
    +      src << "_buf.to_s\n"
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/enhancer.rb, line 210
    +    def add_preamble(src)
    +      src << "_buf = '';"
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringBufferEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringBufferEruby.html new file mode 100644 index 0000000..1e39331 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringBufferEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::StringBufferEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::StringBufferEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringIOEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringIOEruby.html new file mode 100644 index 0000000..c1bcb98 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/StringIOEruby.html @@ -0,0 +1,120 @@ + + + + + + Class: Erubis::StringIOEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::StringIOEruby
    In: + + erubis/engine/enhanced.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + + + +
    + + +
    + + + +
    +

    Included Modules

    + +
    + StringIOEnhancer +
    +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/TinyEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/TinyEruby.html new file mode 100644 index 0000000..0058e2d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/TinyEruby.html @@ -0,0 +1,298 @@ + + + + + + Class: Erubis::TinyEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::TinyEruby
    In: + + erubis/tiny.rb + +
    +
    Parent: + Object +
    +
    + + +
    + + + +
    + +
    +

    +tiny and the simplest implementation of eRuby +

    +

    +ex. +

    +
    +  eruby = TinyEruby.new(File.read('example.rhtml'))
    +  print eruby.src                 # print ruby code
    +  print eruby.result(binding())   # eval ruby code with Binding object
    +  print eruby.evalute(context)    # eval ruby code with context object
    +
    + +
    + + +
    + +
    +

    Methods

    + +
    + convert   + evaluate   + new   + result   +
    +
    + +
    + + + + +
    + + +
    +

    Constants

    + +
    + + + + + + +
    EMBEDDED_PATTERN=/<%(=+|\#)?(.*?)-?%>/m
    +
    +
    + + + +
    +

    Attributes

    + +
    + + + + + + +
    src [R] 
    +
    +
    + + + + +
    +

    Public Class methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 19
    +    def initialize(input=nil)
    +      @src = convert(input) if input
    +    end
    +
    +
    +
    +
    + +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 26
    +    def convert(input)
    +      src = "_buf = '';"           # preamble
    +      pos = 0
    +      input.scan(EMBEDDED_PATTERN) do |indicator, code|
    +        m = Regexp.last_match
    +        text = input[pos...m.begin(0)]
    +        pos  = m.end(0)
    +        #src << " _buf << '" << escape_text(text) << "';"
    +        text.gsub!(/['\\]/, '\\\\\&')
    +        src << " _buf << '" << text << "';" unless text.empty?
    +        if !indicator              # <% %>
    +          src << code << ";"
    +        elsif indicator == '#'     # <%# %>
    +          src << ("\n" * code.count("\n"))
    +        else                       # <%= %>
    +          src << " _buf << (" << code << ").to_s;"
    +        end
    +      end
    +      #rest = $' || input                        # ruby1.8
    +      rest = pos == 0 ? input : input[pos..-1]   # ruby1.9
    +      #src << " _buf << '" << escape_text(rest) << "';"
    +      rest.gsub!(/['\\]/, '\\\\\&')
    +      src << " _buf << '" << rest << "';" unless rest.empty?
    +      src << "\n_buf.to_s\n"       # postamble
    +      return src
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 61
    +    def evaluate(_context=Object.new)
    +      if _context.is_a?(Hash)
    +        _obj = Object.new
    +        _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end
    +        _context = _obj
    +      end
    +      _context.instance_eval @src
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    +def escape_text(text) +

    +
    +  return text.gsub!(/['\\]/, '\\\\\&') || text
    +
    +

    +end +

    +

    [Source]

    +
    +
    +# File erubis/tiny.rb, line 57
    +    def result(_binding=TOPLEVEL_BINDING)
    +      eval @src, _binding
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/XmlEruby.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/XmlEruby.html new file mode 100644 index 0000000..45a769a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/XmlEruby.html @@ -0,0 +1,130 @@ + + + + + + Class: Erubis::XmlEruby + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    ClassErubis::XmlEruby
    In: + + erubis/engine/eruby.rb + +
    +
    Parent: + + Eruby + +
    +
    + + +
    + + + +
    + +
    +

    +sanitize expression (<%= … %>) by default +

    +

    +this is equivalent to EscapedEruby and is +prepared only for compatibility. +

    + +
    + + +
    + + +
    + + + +
    +

    Included Modules

    + + +
    + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/XmlHelper.html b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/XmlHelper.html new file mode 100644 index 0000000..af4480c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/classes/Erubis/XmlHelper.html @@ -0,0 +1,255 @@ + + + + + + Module: Erubis::XmlHelper + + + + + + + + + + +
    + + + + + + + + + + +
    ModuleErubis::XmlHelper
    In: + + erubis/helper.rb + +
    +
    +
    + + +
    + + + +
    + +
    +

    +helper for xml +

    + +
    + + +
    + +
    +

    Methods

    + +
    + escape_xml   + escape_xml2   + h   + html_escape   + u   + url_encode   +
    +
    + +
    + + + + +
    + + +
    +

    Constants

    + +
    + + + + + + +
    ESCAPE_TABLE={ '&' => '&amp;', '<' => '&lt;', '>' => '&gt;', '"' => '&quot;', "'" => '&#039;', }
    +
    +
    + + + + + + + +
    +

    Public Instance methods

    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helper.rb, line 24
    +    def escape_xml(value)
    +      value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] }   # or /[&<>"']/
    +      #value.to_s.gsub(/[&<>"]/) { ESCAPE_TABLE[$&] }
    +    end
    +
    +
    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helper.rb, line 29
    +    def escape_xml2(value)
    +      return value.to_s.gsub(/\&/,'&amp;').gsub(/</,'&lt;').gsub(/>/,'&gt;').gsub(/"/,'&quot;')
    +    end
    +
    +
    +
    +
    + +
    + + +
    + h(value) +
    + +
    +

    +Alias for escape_xml +

    +
    +
    + +
    + + +
    + html_escape(value) +
    + +
    +

    +Alias for escape_xml +

    +
    +
    + +
    + + +
    + u(str) +
    + +
    +

    +Alias for url_encode +

    +
    +
    + +
    + + + + +
    +

    [Source]

    +
    +
    +# File erubis/helper.rb, line 36
    +    def url_encode(str)
    +      return str.gsub(/[^-_.a-zA-Z0-9]+/) { |s|
    +        s.unpack('C*').collect { |i| "%%%02X" % i }.join
    +      }
    +    end
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/created.rid b/vendor/gems/erubis-2.6.5/doc-api/created.rid new file mode 100644 index 0000000..e17f978 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/created.rid @@ -0,0 +1 @@ +Mon, 20 Jul 2009 19:09:24 +0900 diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/README_txt.html b/vendor/gems/erubis-2.6.5/doc-api/files/README_txt.html new file mode 100644 index 0000000..0cc1ab7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/README_txt.html @@ -0,0 +1,247 @@ + + + + + + File: README.txt + + + + + + + + + + +
    +

    README.txt

    + + + + + + + + + +
    Path:README.txt +
    Last Update:Mon Jul 20 19:09:23 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    README

    + + + +
    release:2.6.5 + +
    copyright:copyright(c) 2006-2009 kuwata-lab.com all rights reserved. + +
    +

    About Erubis

    +

    +Erubis is an implementation of eRuby. +It has the following features. +

    +
      +
    • Very fast, almost three times faster than ERB and even 10% faster than eruby + +
    • +
    • Multi-language support (Ruby/PHP/C/Java/Scheme/Perl/Javascript) + +
    • +
    • Auto escaping support + +
    • +
    • Auto trimming spaces around ’<% %>’ + +
    • +
    • Embedded pattern changeable (default ’<% %>’) + +
    • +
    • Enable to handle Processing Instructions (PI) as embedded pattern (ex. +’<?rb … ?>’) + +
    • +
    • Context object available and easy to combine eRuby template with YAML +datafile + +
    • +
    • Print statement available + +
    • +
    • Easy to extend and customize in subclass + +
    • +
    • Ruby on Rails support + +
    • +
    +

    +Erubis is implemented in pure Ruby. It +requires Ruby 1.8 or higher. Erubis +now supports Ruby 1.9. +

    +

    +See doc/users-guide.html for details. +

    +

    Installation

    +
      +
    • If you have installed RubyGems, just type gem install erubis. + +
      +  $ sudo gem install erubis
      +
      +
    • +
    • Else install abstract +at first, and download erubis_X.X.X.tar.bz2 and install it by setup.rb. + +
      +  $ tar xjf abstract_X.X.X.tar.bz2
      +  $ cd abstract_X.X.X/
      +  $ sudo ruby setup.rb
      +  $ cd ..
      +  $ tar xjf erubis_X.X.X.tar.bz2
      +  $ cd erubis_X.X.X/
      +  $ sudo ruby setup.rb
      +
      +
    • +
    • (Optional) It is able to merge ‘lib/**/*.rb’ into +‘bin/erubis’ by ‘contrib/inline-require’ script. + +
      +  $ tar xjf erubis_X.X.X.tar.bz2
      +  $ cd erubis_X.X.X/
      +  $ cp /tmp/abstract_X.X.X/lib/abstract.rb lib
      +  $ unset RUBYLIB
      +  $ contrib/inline-require -I lib bin/erubis > contrib/erubis
      +
      +
    • +
    +

    Ruby on Rails Support

    +

    +Erubis supports Ruby on Rails. All you +have to do is to add the following code into your +‘config/environment.rb’ and restart web server. +

    +
    +     require 'erubis/helpers/rails_helper'
    +     #Erubis::Helpers::RailsHelper.engine_class = Erubis::Eruby
    +     #Erubis::Helpers::RailsHelper.init_properties = {}
    +     #Erubis::Helpers::RailsHelper.show_src = nil
    +
    +

    +If Erubis::Helpers::RailsHelper.show_src is ture, Erubis prints converted Ruby code into +log file (‘log/development.log’ or so). It is useful for debug. +

    +

    Exploring Guide

    +

    +If you are exploring Eruby, see the following class at first. +

    +
      +
    • Erubis::TinyEruby +(erubis/tiny.rb) — the most simple eRuby implementation. + +
    • +
    • Erubis::Engine +(erubis/engine.rb) — base class of Eruby, Ephp, Ejava, and so on. + +
    • +
    • Erubis::Eruby +(erubis/engine/eruby.rb) — engine class for eRuby. + +
    • +
    • Erubis::Converter +(erubis/converter.rb) — convert eRuby script into Ruby code. + +
    • +
    +

    Benchmark

    +

    +‘benchmark/erubybenchmark.rb’ is a benchmark script of Erubis. Try ‘ruby +erubybenchmark.rb’ in benchmark directory. +

    +

    License

    +

    +MIT License +

    +

    Author

    +

    +makoto kuwata <kwa(at)kuwata-lab.com> +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/context_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/context_rb.html new file mode 100644 index 0000000..49a52f5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/context_rb.html @@ -0,0 +1,107 @@ + + + + + + File: context.rb + + + + + + + + + + +
    +

    context.rb

    + + + + + + + + + +
    Path:erubis/context.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/converter_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/converter_rb.html new file mode 100644 index 0000000..1eb9c83 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/converter_rb.html @@ -0,0 +1,114 @@ + + + + + + File: converter.rb + + + + + + + + + + +
    +

    converter.rb

    + + + + + + + + + +
    Path:erubis/converter.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + +
    + abstract   +
    +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ec_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ec_rb.html new file mode 100644 index 0000000..b3610f0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ec_rb.html @@ -0,0 +1,115 @@ + + + + + + File: ec.rb + + + + + + + + + + +
    +

    ec.rb

    + + + + + + + + + +
    Path:erubis/engine/ec.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ejava_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ejava_rb.html new file mode 100644 index 0000000..6106fbb --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ejava_rb.html @@ -0,0 +1,115 @@ + + + + + + File: ejava.rb + + + + + + + + + + +
    +

    ejava.rb

    + + + + + + + + + +
    Path:erubis/engine/ejava.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ejavascript_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ejavascript_rb.html new file mode 100644 index 0000000..a45df50 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ejavascript_rb.html @@ -0,0 +1,115 @@ + + + + + + File: ejavascript.rb + + + + + + + + + + +
    +

    ejavascript.rb

    + + + + + + + + + +
    Path:erubis/engine/ejavascript.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/enhanced_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/enhanced_rb.html new file mode 100644 index 0000000..948c15b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/enhanced_rb.html @@ -0,0 +1,115 @@ + + + + + + File: enhanced.rb + + + + + + + + + + +
    +

    enhanced.rb

    + + + + + + + + + +
    Path:erubis/engine/enhanced.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/eperl_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/eperl_rb.html new file mode 100644 index 0000000..5d6a070 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/eperl_rb.html @@ -0,0 +1,115 @@ + + + + + + File: eperl.rb + + + + + + + + + + +
    +

    eperl.rb

    + + + + + + + + + +
    Path:erubis/engine/eperl.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ephp_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ephp_rb.html new file mode 100644 index 0000000..d8775e1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/ephp_rb.html @@ -0,0 +1,115 @@ + + + + + + File: ephp.rb + + + + + + + + + + +
    +

    ephp.rb

    + + + + + + + + + +
    Path:erubis/engine/ephp.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/eruby_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/eruby_rb.html new file mode 100644 index 0000000..6d33661 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/eruby_rb.html @@ -0,0 +1,115 @@ + + + + + + File: eruby.rb + + + + + + + + + + +
    +

    eruby.rb

    + + + + + + + + + +
    Path:erubis/engine/eruby.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/escheme_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/escheme_rb.html new file mode 100644 index 0000000..8828b51 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/escheme_rb.html @@ -0,0 +1,115 @@ + + + + + + File: escheme.rb + + + + + + + + + + +
    +

    escheme.rb

    + + + + + + + + + +
    Path:erubis/engine/escheme.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/optimized_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/optimized_rb.html new file mode 100644 index 0000000..e5da00b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine/optimized_rb.html @@ -0,0 +1,114 @@ + + + + + + File: optimized.rb + + + + + + + + + + +
    +

    optimized.rb

    + + + + + + + + + +
    Path:erubis/engine/optimized.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine_rb.html new file mode 100644 index 0000000..0529fa3 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/engine_rb.html @@ -0,0 +1,117 @@ + + + + + + File: engine.rb + + + + + + + + + + +
    +

    engine.rb

    + + + + + + + + + +
    Path:erubis/engine.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/enhancer_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/enhancer_rb.html new file mode 100644 index 0000000..f418704 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/enhancer_rb.html @@ -0,0 +1,107 @@ + + + + + + File: enhancer.rb + + + + + + + + + + +
    +

    enhancer.rb

    + + + + + + + + + +
    Path:erubis/enhancer.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/error_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/error_rb.html new file mode 100644 index 0000000..f55b178 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/error_rb.html @@ -0,0 +1,107 @@ + + + + + + File: error.rb + + + + + + + + + + +
    +

    error.rb

    + + + + + + + + + +
    Path:erubis/error.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/evaluator_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/evaluator_rb.html new file mode 100644 index 0000000..2bf431f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/evaluator_rb.html @@ -0,0 +1,115 @@ + + + + + + File: evaluator.rb + + + + + + + + + + +
    +

    evaluator.rb

    + + + + + + + + + +
    Path:erubis/evaluator.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/generator_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/generator_rb.html new file mode 100644 index 0000000..5925c04 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/generator_rb.html @@ -0,0 +1,114 @@ + + + + + + File: generator.rb + + + + + + + + + + +
    +

    generator.rb

    + + + + + + + + + +
    Path:erubis/generator.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + +
    + abstract   +
    +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helper_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helper_rb.html new file mode 100644 index 0000000..e6b4c96 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helper_rb.html @@ -0,0 +1,107 @@ + + + + + + File: helper.rb + + + + + + + + + + +
    +

    helper.rb

    + + + + + + + + + +
    Path:erubis/helper.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helpers/rails_form_helper_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helpers/rails_form_helper_rb.html new file mode 100644 index 0000000..52b7f25 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helpers/rails_form_helper_rb.html @@ -0,0 +1,107 @@ + + + + + + File: rails_form_helper.rb + + + + + + + + + + +
    +

    rails_form_helper.rb

    + + + + + + + + + +
    Path:erubis/helpers/rails_form_helper.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helpers/rails_helper_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helpers/rails_helper_rb.html new file mode 100644 index 0000000..1a01fa96 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/helpers/rails_helper_rb.html @@ -0,0 +1,116 @@ + + + + + + File: rails_helper.rb + + + + + + + + + + +
    +

    rails_helper.rb

    + + + + + + + + + +
    Path:erubis/helpers/rails_helper.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + +
    + erubis   + erubis/preprocessing   + action_pack/version   +
    +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/local-setting_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/local-setting_rb.html new file mode 100644 index 0000000..1e99596 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/local-setting_rb.html @@ -0,0 +1,107 @@ + + + + + + File: local-setting.rb + + + + + + + + + + +
    +

    local-setting.rb

    + + + + + + + + + +
    Path:erubis/local-setting.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/main_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/main_rb.html new file mode 100644 index 0000000..8037464 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/main_rb.html @@ -0,0 +1,127 @@ + + + + + + File: main.rb + + + + + + + + + + +
    +

    main.rb

    + + + + + + + + + +
    Path:erubis/main.rb +
    Last Update:Wed Jul 15 18:44:09 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/preprocessing_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/preprocessing_rb.html new file mode 100644 index 0000000..3cfbb41 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/preprocessing_rb.html @@ -0,0 +1,114 @@ + + + + + + File: preprocessing.rb + + + + + + + + + + +
    +

    preprocessing.rb

    + + + + + + + + + +
    Path:erubis/preprocessing.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + +
    + cgi   +
    +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis/tiny_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/tiny_rb.html new file mode 100644 index 0000000..932b1d6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis/tiny_rb.html @@ -0,0 +1,107 @@ + + + + + + File: tiny.rb + + + + + + + + + + +
    +

    tiny.rb

    + + + + + + + + + +
    Path:erubis/tiny.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/files/erubis_rb.html b/vendor/gems/erubis-2.6.5/doc-api/files/erubis_rb.html new file mode 100644 index 0000000..7c6668f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/files/erubis_rb.html @@ -0,0 +1,118 @@ + + + + + + File: erubis.rb + + + + + + + + + + +
    +

    erubis.rb

    + + + + + + + + + +
    Path:erubis.rb +
    Last Update:Tue Jul 14 09:47:22 +0900 2009
    +
    + + +
    + + + +
    + +
    +

    +$Release: 2.6.5 $ copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +

    + +
    + +
    +

    Required files

    + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/fr_class_index.html b/vendor/gems/erubis-2.6.5/doc-api/fr_class_index.html new file mode 100644 index 0000000..5a2159f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/fr_class_index.html @@ -0,0 +1,122 @@ + + + + + + + + Classes + + + + + +
    +

    Classes

    +
    + ActionView
    + ActionView::TemplateHandlers::ErubisHandler
    + ERB
    + Erubis
    + Erubis::ArrayBufferEnhancer
    + Erubis::ArrayBufferEruby
    + Erubis::ArrayEnhancer
    + Erubis::ArrayEruby
    + Erubis::Basic
    + Erubis::Basic::Converter
    + Erubis::Basic::Engine
    + Erubis::BiPatternEnhancer
    + Erubis::BiPatternEruby
    + Erubis::CGenerator
    + Erubis::CommandOptionError
    + Erubis::Context
    + Erubis::Converter
    + Erubis::DeleteIndentEnhancer
    + Erubis::DeleteIndentEruby
    + Erubis::Ec
    + Erubis::Ejava
    + Erubis::Ejavascript
    + Erubis::Engine
    + Erubis::Eperl
    + Erubis::Ephp
    + Erubis::ErboutEnhancer
    + Erubis::ErboutEruby
    + Erubis::ErubisError
    + Erubis::Eruby
    + Erubis::EscapeEnhancer
    + Erubis::EscapedEc
    + Erubis::EscapedEjava
    + Erubis::EscapedEjavascript
    + Erubis::EscapedEperl
    + Erubis::EscapedEphp
    + Erubis::EscapedEruby
    + Erubis::EscapedEscheme
    + Erubis::Escheme
    + Erubis::Evaluator
    + Erubis::FastEruby
    + Erubis::Generator
    + Erubis::HeaderFooterEnhancer
    + Erubis::HeaderFooterEruby
    + Erubis::Helpers
    + Erubis::Helpers::RailsFormHelper
    + Erubis::Helpers::RailsHelper
    + Erubis::Helpers::RailsHelper::TemplateConverter
    + Erubis::InterpolationEnhancer
    + Erubis::InterpolationEruby
    + Erubis::JavaGenerator
    + Erubis::JavascriptGenerator
    + Erubis::Main
    + Erubis::NoCodeEnhancer
    + Erubis::NoCodeEruby
    + Erubis::NoTextEnhancer
    + Erubis::NoTextEruby
    + Erubis::NotSupportedError
    + Erubis::OptimizedEruby
    + Erubis::OptimizedGenerator
    + Erubis::OptimizedXmlEruby
    + Erubis::PI
    + Erubis::PI::Converter
    + Erubis::PI::Ec
    + Erubis::PI::Ejava
    + Erubis::PI::Ejavascript
    + Erubis::PI::Engine
    + Erubis::PI::Eperl
    + Erubis::PI::Ephp
    + Erubis::PI::Eruby
    + Erubis::PI::Escheme
    + Erubis::PI::TinyEruby
    + Erubis::PercentLineEnhancer
    + Erubis::PercentLineEruby
    + Erubis::PerlGenerator
    + Erubis::PhpGenerator
    + Erubis::PreprocessingEruby
    + Erubis::PreprocessingHelper
    + Erubis::PrintEnabledEnhancer
    + Erubis::PrintEnabledEruby
    + Erubis::PrintOutEnhancer
    + Erubis::PrintOutEruby
    + Erubis::PrintOutSimplifiedEruby
    + Erubis::RubyEvaluator
    + Erubis::RubyGenerator
    + Erubis::SchemeGenerator
    + Erubis::SimplifiedEruby
    + Erubis::SimplifyEnhancer
    + Erubis::StdoutEnhancer
    + Erubis::StdoutEruby
    + Erubis::StdoutSimplifiedEruby
    + Erubis::StringBufferEnhancer
    + Erubis::StringBufferEruby
    + Erubis::StringIOEruby
    + Erubis::TinyEruby
    + Erubis::XmlEruby
    + Erubis::XmlHelper
    +
    +
    + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/fr_file_index.html b/vendor/gems/erubis-2.6.5/doc-api/fr_file_index.html new file mode 100644 index 0000000..50c8b4f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/fr_file_index.html @@ -0,0 +1,51 @@ + + + + + + + + Files + + + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/fr_method_index.html b/vendor/gems/erubis-2.6.5/doc-api/fr_method_index.html new file mode 100644 index 0000000..6df8a8c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/fr_method_index.html @@ -0,0 +1,251 @@ + + + + + + + + Methods + + + + + +
    +

    Methods

    +
    + [] (Erubis::Context)
    + []= (Erubis::Context)
    + _? (Erubis::PreprocessingHelper)
    + _P (Erubis::PreprocessingHelper)
    + _add_text_to_str (Erubis::InterpolationEnhancer)
    + _create_preprocessor (Erubis::Helpers::RailsHelper::TemplateConverter)
    + _decode (Erubis::PreprocessingHelper)
    + _logger_info (Erubis::Helpers::RailsHelper::TemplateConverter)
    + _logger_info (Erubis::Helpers::RailsHelper::TemplateConverter)
    + _p (Erubis::PreprocessingHelper)
    + _pp_check_box_checked? (Erubis::Helpers::RailsFormHelper)
    + _pp_error_tags (Erubis::Helpers::RailsFormHelper)
    + _pp_radio_button_checked? (Erubis::Helpers::RailsFormHelper)
    + _pp_remove_error_div (Erubis::Helpers::RailsFormHelper)
    + _pp_select (Erubis::Helpers::RailsFormHelper)
    + _pp_select_options (Erubis::Helpers::RailsFormHelper)
    + _preprocessing_context_object (Erubis::Helpers::RailsHelper::TemplateConverter)
    + add_expr (Erubis::EscapeEnhancer)
    + add_expr (Erubis::NoCodeEnhancer)
    + add_expr (Erubis::Basic::Converter)
    + add_expr_debug (Erubis::Generator)
    + add_expr_debug (Erubis::CGenerator)
    + add_expr_debug (Erubis::JavascriptGenerator)
    + add_expr_debug (Erubis::OptimizedGenerator)
    + add_expr_debug (Erubis::PerlGenerator)
    + add_expr_debug (Erubis::PhpGenerator)
    + add_expr_debug (Erubis::SchemeGenerator)
    + add_expr_debug (Erubis::RubyGenerator)
    + add_expr_debug (Erubis::JavaGenerator)
    + add_expr_debug (Erubis::OptimizedXmlEruby)
    + add_expr_escaped (Erubis::JavascriptGenerator)
    + add_expr_escaped (Erubis::OptimizedGenerator)
    + add_expr_escaped (Erubis::PrintOutEnhancer)
    + add_expr_escaped (Erubis::RubyGenerator)
    + add_expr_escaped (Erubis::CGenerator)
    + add_expr_escaped (Erubis::PerlGenerator)
    + add_expr_escaped (Erubis::PreprocessingEruby)
    + add_expr_escaped (Erubis::Generator)
    + add_expr_escaped (Erubis::InterpolationEnhancer)
    + add_expr_escaped (Erubis::JavaGenerator)
    + add_expr_escaped (Erubis::PhpGenerator)
    + add_expr_escaped (Erubis::SchemeGenerator)
    + add_expr_literal (Erubis::SchemeGenerator)
    + add_expr_literal (Erubis::Generator)
    + add_expr_literal (Erubis::JavascriptGenerator)
    + add_expr_literal (Erubis::JavaGenerator)
    + add_expr_literal (Erubis::CGenerator)
    + add_expr_literal (Erubis::InterpolationEnhancer)
    + add_expr_literal (Erubis::PhpGenerator)
    + add_expr_literal (Erubis::PrintOutEnhancer)
    + add_expr_literal (Erubis::PerlGenerator)
    + add_expr_literal (Erubis::RubyGenerator)
    + add_expr_literal (Erubis::OptimizedGenerator)
    + add_indent (Erubis::JavascriptGenerator)
    + add_postamble (Erubis::StdoutEnhancer)
    + add_postamble (Erubis::ErboutEnhancer)
    + add_postamble (Erubis::NoCodeEnhancer)
    + add_postamble (Erubis::StringBufferEnhancer)
    + add_postamble (Erubis::ArrayBufferEnhancer)
    + add_postamble (Erubis::JavaGenerator)
    + add_postamble (Erubis::OptimizedGenerator)
    + add_postamble (Erubis::JavascriptGenerator)
    + add_postamble (Erubis::SchemeGenerator)
    + add_postamble (Erubis::ArrayEnhancer)
    + add_postamble (Erubis::PerlGenerator)
    + add_postamble (Erubis::CGenerator)
    + add_postamble (Erubis::PhpGenerator)
    + add_postamble (Erubis::PrintOutEnhancer)
    + add_postamble (Erubis::Generator)
    + add_preamble (Erubis::OptimizedGenerator)
    + add_preamble (Erubis::Generator)
    + add_preamble (Erubis::StdoutEnhancer)
    + add_preamble (Erubis::SchemeGenerator)
    + add_preamble (Erubis::JavaGenerator)
    + add_preamble (Erubis::ArrayBufferEnhancer)
    + add_preamble (Erubis::PhpGenerator)
    + add_preamble (Erubis::StringBufferEnhancer)
    + add_preamble (Erubis::ArrayEnhancer)
    + add_preamble (Erubis::NoCodeEnhancer)
    + add_preamble (Erubis::PerlGenerator)
    + add_preamble (Erubis::PrintEnabledEnhancer)
    + add_preamble (Erubis::PrintOutEnhancer)
    + add_preamble (Erubis::CGenerator)
    + add_preamble (Erubis::JavascriptGenerator)
    + add_preamble (Erubis::ErboutEnhancer)
    + add_stmt (Erubis::OptimizedGenerator)
    + add_stmt (Erubis::RubyGenerator)
    + add_stmt (Erubis::PerlGenerator)
    + add_stmt (Erubis::NoCodeEnhancer)
    + add_stmt (Erubis::JavascriptGenerator)
    + add_stmt (Erubis::Generator)
    + add_stmt (Erubis::PhpGenerator)
    + add_stmt (Erubis::CGenerator)
    + add_stmt (Erubis::SchemeGenerator)
    + add_stmt (Erubis::JavaGenerator)
    + add_text (Erubis::BiPatternEnhancer)
    + add_text (Erubis::SchemeGenerator)
    + add_text (Erubis::PrintOutEnhancer)
    + add_text (Erubis::CGenerator)
    + add_text (Erubis::JavaGenerator)
    + add_text (Erubis::OptimizedGenerator)
    + add_text (Erubis::NoTextEnhancer)
    + add_text (Erubis::InterpolationEnhancer)
    + add_text (Erubis::PercentLineEnhancer)
    + add_text (Erubis::PerlGenerator)
    + add_text (Erubis::PhpGenerator)
    + add_text (Erubis::JavascriptGenerator)
    + add_text (Erubis::NoCodeEnhancer)
    + add_text (Erubis::HeaderFooterEnhancer)
    + add_text (Erubis::RubyGenerator)
    + add_text (Erubis::Generator)
    + compile (ActionView::TemplateHandlers::ErubisHandler)
    + compile (ActionView::TemplateHandlers::ErubisHandler)
    + compile (ActionView::TemplateHandlers::ErubisHandler)
    + convert (Erubis::PI::Converter)
    + convert (Erubis::SimplifyEnhancer)
    + convert (Erubis::HeaderFooterEnhancer)
    + convert (Erubis::Converter)
    + convert (Erubis::TinyEruby)
    + convert (Erubis::PI::TinyEruby)
    + convert! (Erubis::Engine)
    + convert_input (Erubis::Converter)
    + convert_input (Erubis::DeleteIndentEnhancer)
    + convert_input (Erubis::PI::Converter)
    + convert_input (Erubis::InterpolationEnhancer)
    + convert_input (Erubis::Basic::Converter)
    + def_method (Erubis::RubyEvaluator)
    + detect_spaces_at_bol (Erubis::Converter)
    + each (Erubis::Context)
    + engine_class (Erubis::Helpers::RailsHelper)
    + engine_class= (Erubis::Helpers::RailsHelper)
    + escape_text (Erubis::RubyGenerator)
    + escape_text (Erubis::PerlGenerator)
    + escape_text (Erubis::Generator)
    + escape_text (Erubis::JavascriptGenerator)
    + escape_text (Erubis::CGenerator)
    + escape_text (Erubis::OptimizedGenerator)
    + escape_text (Erubis::JavaGenerator)
    + escape_text (Erubis::PhpGenerator)
    + escape_text (Erubis::SchemeGenerator)
    + escape_xml (Erubis::XmlHelper)
    + escape_xml2 (Erubis::XmlHelper)
    + escaped_expr (Erubis::SchemeGenerator)
    + escaped_expr (Erubis::CGenerator)
    + escaped_expr (Erubis::OptimizedGenerator)
    + escaped_expr (Erubis::Generator)
    + escaped_expr (Erubis::RubyGenerator)
    + evaluate (Erubis::Evaluator)
    + evaluate (Erubis::PrintEnabledEnhancer)
    + evaluate (Erubis::TinyEruby)
    + evaluate (Erubis::RubyEvaluator)
    + evaluate (Erubis::PI::TinyEruby)
    + execute (Erubis::Main)
    + h (Erubis::XmlHelper)
    + html_escape (Erubis::XmlHelper)
    + init_converter (Erubis::Converter)
    + init_converter (Erubis::PI::Ec)
    + init_converter (Erubis::PI::Converter)
    + init_converter (Erubis::PI::Eruby)
    + init_converter (Erubis::PI::Ejavascript)
    + init_converter (Erubis::PI::Ejava)
    + init_converter (Erubis::Basic::Converter)
    + init_converter (Erubis::PI::Ephp)
    + init_converter (Erubis::OptimizedEruby)
    + init_converter (Erubis::PI::Eperl)
    + init_converter (Erubis::PI::Escheme)
    + init_evaluator (Erubis::Evaluator)
    + init_generator (Erubis::OptimizedGenerator)
    + init_generator (Erubis::CGenerator)
    + init_generator (Erubis::PhpGenerator)
    + init_generator (Erubis::JavascriptGenerator)
    + init_generator (Erubis::Generator)
    + init_generator (Erubis::RubyGenerator)
    + init_generator (Erubis::PerlGenerator)
    + init_generator (Erubis::JavaGenerator)
    + init_generator (Erubis::SchemeGenerator)
    + init_properties (Erubis::Helpers::RailsHelper)
    + init_properties= (Erubis::Helpers::RailsHelper)
    + keys (Erubis::Context)
    + load_file (Erubis::Engine)
    + main (Erubis::Main)
    + new (Erubis::PI::TinyEruby)
    + new (Erubis::Main)
    + new (Erubis::Context)
    + new (Erubis::BiPatternEnhancer)
    + new (Erubis::TinyEruby)
    + new (Erubis::Engine)
    + new (Erubis::PreprocessingEruby)
    + pattern_regexp (Erubis::Basic::Converter)
    + pp_check_box (Erubis::Helpers::RailsFormHelper)
    + pp_collection_select (Erubis::Helpers::RailsFormHelper)
    + pp_country_select (Erubis::Helpers::RailsFormHelper)
    + pp_error_on (Erubis::Helpers::RailsFormHelper)
    + pp_file_field (Erubis::Helpers::RailsFormHelper)
    + pp_form_tag (Erubis::Helpers::RailsFormHelper)
    + pp_hidden_field (Erubis::Helpers::RailsFormHelper)
    + pp_image_submit_tag (Erubis::Helpers::RailsFormHelper)
    + pp_password_field (Erubis::Helpers::RailsFormHelper)
    + pp_radio_button (Erubis::Helpers::RailsFormHelper)
    + pp_render_partial (Erubis::Helpers::RailsFormHelper)
    + pp_select (Erubis::Helpers::RailsFormHelper)
    + pp_submit_tag (Erubis::Helpers::RailsFormHelper)
    + pp_tag_helper (Erubis::Helpers::RailsFormHelper)
    + pp_template_filename (Erubis::Helpers::RailsFormHelper)
    + pp_template_filename (Erubis::Helpers::RailsFormHelper)
    + pp_text_area (Erubis::Helpers::RailsFormHelper)
    + pp_text_field (Erubis::Helpers::RailsFormHelper)
    + pp_time_zone_select (Erubis::Helpers::RailsFormHelper)
    + preprocessing (Erubis::Helpers::RailsHelper)
    + preprocessing= (Erubis::Helpers::RailsHelper)
    + print (Erubis::PrintEnabledEnhancer)
    + process (Erubis::Engine)
    + process_proc (Erubis::Engine)
    + result (Erubis::TinyEruby)
    + result (Erubis::Evaluator)
    + result (Erubis::PI::TinyEruby)
    + result (Erubis::RubyEvaluator)
    + show_src (Erubis::Helpers::RailsHelper)
    + show_src= (Erubis::Helpers::RailsHelper)
    + switch_to_expr (Erubis::OptimizedGenerator)
    + switch_to_stmt (Erubis::OptimizedGenerator)
    + to_hash (Erubis::Context)
    + u (Erubis::XmlHelper)
    + update (Erubis::Context)
    + url_encode (Erubis::XmlHelper)
    +
    +
    + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/index.html b/vendor/gems/erubis-2.6.5/doc-api/index.html new file mode 100644 index 0000000..8603883 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/index.html @@ -0,0 +1,24 @@ + + + + + + + RDoc Documentation + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/doc-api/rdoc-style.css b/vendor/gems/erubis-2.6.5/doc-api/rdoc-style.css new file mode 100644 index 0000000..44c7b3d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/doc-api/rdoc-style.css @@ -0,0 +1,208 @@ + +body { + font-family: Verdana,Arial,Helvetica,sans-serif; + font-size: 90%; + margin: 0; + margin-left: 40px; + padding: 0; + background: white; +} + +h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; } +h1 { font-size: 150%; } +h2,h3,h4 { margin-top: 1em; } + +a { background: #eef; color: #039; text-decoration: none; } +a:hover { background: #039; color: #eef; } + +/* Override the base stylesheet's Anchor inside a table cell */ +td > a { + background: transparent; + color: #039; + text-decoration: none; +} + +/* and inside a section title */ +.section-title > a { + background: transparent; + color: #eee; + text-decoration: none; +} + +/* === Structural elements =================================== */ + +div#index { + margin: 0; + margin-left: -40px; + padding: 0; + font-size: 90%; +} + + +div#index a { + margin-left: 0.7em; +} + +div#index .section-bar { + margin-left: 0px; + padding-left: 0.7em; + background: #ccc; + font-size: small; +} + + +div#classHeader, div#fileHeader { + width: auto; + color: white; + padding: 0.5em 1.5em 0.5em 1.5em; + margin: 0; + margin-left: -40px; + border-bottom: 3px solid #006; +} + +div#classHeader a, div#fileHeader a { + background: inherit; + color: white; +} + +div#classHeader td, div#fileHeader td { + background: inherit; + color: white; +} + + +div#fileHeader { + background: #057; +} + +div#classHeader { + background: #048; +} + + +.class-name-in-header { + font-size: 180%; + font-weight: bold; +} + + +div#bodyContent { + padding: 0 1.5em 0 1.5em; +} + +div#description { + padding: 0.5em 1.5em; + background: #efefef; + border: 1px dotted #999; +} + +div#description h1,h2,h3,h4,h5,h6 { + color: #125;; + background: transparent; +} + +div#validator-badges { + text-align: center; +} +div#validator-badges img { border: 0; } + +div#copyright { + color: #333; + background: #efefef; + font: 0.75em sans-serif; + margin-top: 5em; + margin-bottom: 0; + padding: 0.5em 2em; +} + + +/* === Classes =================================== */ + +table.header-table { + color: white; + font-size: small; +} + +.type-note { + font-size: small; + color: #DEDEDE; +} + +.xxsection-bar { + background: #eee; + color: #333; + padding: 3px; +} + +.section-bar { + color: #333; + border-bottom: 1px solid #999; + margin-left: -20px; +} + + +.section-title { + background: #79a; + color: #eee; + padding: 3px; + margin-top: 2em; + margin-left: -30px; + border: 1px solid #999; +} + +.top-aligned-row { vertical-align: top } +.bottom-aligned-row { vertical-align: bottom } + +/* --- Context section classes ----------------------- */ + +.context-row { } +.context-item-name { font-family: monospace; font-weight: bold; color: black; } +.context-item-value { font-size: small; color: #448; } +.context-item-desc { color: #333; padding-left: 2em; } + +/* --- Method classes -------------------------- */ +.method-detail { + background: #efefef; + padding: 0; + margin-top: 0.5em; + margin-bottom: 1em; + border: 1px dotted #ccc; +} +.method-heading { + color: black; + background: #ccc; + border-bottom: 1px solid #666; + padding: 0.2em 0.5em 0 0.5em; +} +.method-signature { color: black; background: inherit; } +.method-name { font-weight: bold; } +.method-args { font-style: italic; } +.method-description { padding: 0 0.5em 0 0.5em; } + +/* --- Source code sections -------------------- */ + +a.source-toggle { font-size: 90%; } +div.method-source-code { + background: #262626; + color: #ffdead; + margin: 1em; + padding: 0.5em; + border: 1px dashed #999; + overflow: hidden; +} + +div.method-source-code pre { color: #ffdead; overflow: hidden; } + +/* --- Ruby keyword styles --------------------- */ + +.standalone-code { background: #221111; color: #ffdead; overflow: hidden; } + +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } +.ruby-identifier { color: #ffdead; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } \ No newline at end of file diff --git a/vendor/gems/erubis-2.6.5/examples/basic/Makefile b/vendor/gems/erubis-2.6.5/examples/basic/Makefile new file mode 100644 index 0000000..0868c96 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/Makefile @@ -0,0 +1,53 @@ +all = example.rb example.php example.c example.java example.scm example.pl example.js + +all: $(all) + +example.rb: example.eruby + erubis -l ruby example.eruby > example.rb + + +example.php: example.ephp + erubis -l php example.ephp > example.php + +example.c: example.ec + erubis -bl c example.ec > example.c + +example.java: example.ejava + erubis -bl java example.ejava > example.java + +example.scm: example.escheme + erubis -l scheme --func=display example.escheme > example.scm +# erubis -l scheme example.escheme > example.scm + +example.pl: example.eperl + erubis -l perl example.eperl > example.pl + +example.js: example.ejs + erubis -l javascript example.ejs > example.js + + +###---------- + +src = example.eruby example.ephp example.ec example.ejava example.escheme example.eperl example.ejs Makefile + +clean: + rm -f `ruby -e 'puts(Dir.glob("*.*") - %w[$(src)])'` +# rm -f $(all) + +compile: example.bin example.class + +example.bin: example.c + cc -o example.bin example.c + +example.class: example.java + jikes example.java + +output: $(all) example.bin example.class + erubis example.eruby > example.ruby.out + php example.php > example.php.out + ./example.bin '' 'b&b' '"ccc"' > example.c.out + java example > example.javexample.bin + gosh example.scm > example.scm.out +# guile example.scm > example.scm.out + perl example.pl > example.pl.out + diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.ec b/vendor/gems/erubis-2.6.5/examples/basic/example.ec new file mode 100644 index 0000000..589bdb0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.ec @@ -0,0 +1,42 @@ +<% +#include + +void escape(char *str, FILE *out); + +int main(int argc, char *argv[]) +{ + int i; + +%> +

    Hello <%== argv[0] %>!

    + + + <% for (i = 1; i < argc; i++) { %> + "> + + + + <% } %> + +
    <%= "%d", i %><%== argv[i] %>
    +<% + + return 0; +} + +void escape(char *str, FILE *out) +{ + char *pch; + for (pch = str; *pch != '\0'; pch++) { + switch (*pch) { + case '&': fputs("&", out); break; + case '>': fputs(">", out); break; + case '<': fputs("<", out); break; + case '"': fputs(""", out); break; + case '\'': fputs("'", out); break; + default: fputc(*pch, out); + } + } +} + +%> diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.ejava b/vendor/gems/erubis-2.6.5/examples/basic/example.ejava new file mode 100644 index 0000000..217295d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.ejava @@ -0,0 +1,45 @@ +<% +import java.util.*; + +public class example { + + public static void main(String[] args) { + String user = "Erubis"; + String[] list = { "", "b&b", "\"ccc\"" }; + StringBuffer _buf = new StringBuffer(); +%> +

    Hello <%== user %>!

    + + + <% for (int i = 0; i < list.length; i++) { %> + "> + + + + <% } %> + +
    <%= i + 1 %><%== list[i] %>
    +<% + System.out.print(_buf.toString()); + } + + public static String escape(String s) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch (ch) { + case '<': sb.append("<"); break; + case '>': sb.append(">"); break; + case '&': sb.append("&"); break; + case '"': sb.append("""); break; + default: sb.append(ch); + } + } + return sb.toString(); + } + + public static String escape(int i) { + return Integer.toString(i); + } +} +%> diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.ejs b/vendor/gems/erubis-2.6.5/examples/basic/example.ejs new file mode 100644 index 0000000..67b7b0c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.ejs @@ -0,0 +1,16 @@ +<% + var user = 'Erubis'; + var list = ['', 'b&b', '"ccc"']; + %> +

    Hello <%= user %>!

    + + + <% var i; %> + <% for (i = 0; i < list.length; i++) { %> + + + + + <% } %> + +
    <%= i + 1 %><%= list[i] %>
    diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.eperl b/vendor/gems/erubis-2.6.5/examples/basic/example.eperl new file mode 100644 index 0000000..f1261dd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.eperl @@ -0,0 +1,16 @@ +<% + my $user = 'Erubis'; + my @list = ('', 'b&b', '"ccc"'); +%> +

    Hello <%== $user %>!

    + + + <% $i = 0; %> + <% for $item (@list) { %> + "> + + + + <% } %> + +
    <%= $i %><%== $item %>
    diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.ephp b/vendor/gems/erubis-2.6.5/examples/basic/example.ephp new file mode 100644 index 0000000..b45d62d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.ephp @@ -0,0 +1,17 @@ +<% + $user = "World"; + $list = array('', 'b&b', '"ccc"'); +%> +

    Hello <%= $user %>!

    + + + <% $i = 0 %> + <% foreach ($list as $item) { %> + <% $i++; %> + + + + + <% } %> + +
    <%= $i %><%== $item %>
    diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.eruby b/vendor/gems/erubis-2.6.5/examples/basic/example.eruby new file mode 100644 index 0000000..ee1ed13 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.eruby @@ -0,0 +1,15 @@ +<% + user = 'Erubis' + list = ['', 'b&b', '"ccc"'] + %> +

    Hello <%= user %>!

    + + + <% list.each_with_index do |item, i| %> + + + + + <% end %> + +
    <%= i + 1 %><%== item %>
    diff --git a/vendor/gems/erubis-2.6.5/examples/basic/example.escheme b/vendor/gems/erubis-2.6.5/examples/basic/example.escheme new file mode 100644 index 0000000..419ef77 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/basic/example.escheme @@ -0,0 +1,26 @@ +<% +(let ((user "Erubis") + (items '("" "b&b" "\"ccc\"")) + (i 0)) + %> +

    Hello <%= user %>!

    + + +<% + (for-each + (lambda (item) + (set! i (+ i 1)) + %> + "> + + + +<% + ) ; lambda end + items) ; for-each end + %> + +
    <%= i %><%= item %>
    +<% +) ; let end +%> diff --git a/vendor/gems/erubis-2.6.5/examples/pi/Makefile b/vendor/gems/erubis-2.6.5/examples/pi/Makefile new file mode 100644 index 0000000..de12772 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/Makefile @@ -0,0 +1,54 @@ +all = example.rb example.php example.c example.java example.scm example.pl example.js + +all: $(all) + +example.rb: example.eruby + erubis --pi -l ruby example.eruby > example.rb + + +example.php: example.ephp + erubis --pi -l php example.ephp > example.php + +example.c: example.ec + erubis --pi -bl c example.ec > example.c + +example.java: example.ejava + erubis --pi -bl java example.ejava > example.java + +example.scm: example.escheme + erubis --pi -l scheme --func=display example.escheme > example.scm +# erubis --pi -l scheme example.escheme > example.scm + +example.pl: example.eperl + erubis --pi -l perl example.eperl > example.pl + +example.js: example.ejs + erubis --pi -l javascript example.ejs > example.js + + +###---------- + +src = example.eruby example.ephp example.ec example.ejava example.escheme example.eperl example.ejs Makefile + +clean: + rm -f `ruby -e 'puts(Dir.glob("*.*") - %w[$(src)])'` +# rm -f $(all) + +compile: example.bin example.class + +example.bin: example.c + cc -o example.bin example.c + +example.class: example.java + jikes example.java + +output: $(all) example.bin example.class + erubis --pi example.eruby > example.ruby.result + #ruby example.rb > example.ruby.result + php example.php > example.php.result + ./example.bin '' 'b&b' '"ccc"' > example.c.result + java example > example.java.result + gosh example.scm > example.scm.result + #guile example.scm > example.scm.result + perl example.pl > example.pl.result + diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.ec b/vendor/gems/erubis-2.6.5/examples/pi/example.ec new file mode 100644 index 0000000..ddec571 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.ec @@ -0,0 +1,42 @@ + + +void escape(char *str, FILE *out); + +int main(int argc, char *argv[]) +{ + int i; + +?> +

    Hello @!{argv[0]}@!

    + + + + + + + + + +
    @!{"%d", i}@@{argv[i]}@
    +': fputs(">", out); break; + case '<': fputs("<", out); break; + case '"': fputs(""", out); break; + case '\'': fputs("'", out); break; + default: fputc(*pch, out); + } + } +} + +?> diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.ejava b/vendor/gems/erubis-2.6.5/examples/pi/example.ejava new file mode 100644 index 0000000..beca150 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.ejava @@ -0,0 +1,45 @@ +", "b&b", "\"ccc\"" }; + StringBuffer _buf = new StringBuffer(); +?> +

    Hello @{user}@!

    + + + + + + + + + +
    @!{i + 1}@@{list[i]}@
    +': sb.append(">"); break; + case '&': sb.append("&"); break; + case '"': sb.append("""); break; + default: sb.append(ch); + } + } + return sb.toString(); + } + + public static String escape(int i) { + return Integer.toString(i); + } +} +?> diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.ejs b/vendor/gems/erubis-2.6.5/examples/pi/example.ejs new file mode 100644 index 0000000..f12ae42 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.ejs @@ -0,0 +1,16 @@ +', 'b&b', '"ccc"']; + ?> +

    Hello @{user}@!

    + + + + + + + + + + +
    @{i + 1}@@{list[i]}@
    diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.eperl b/vendor/gems/erubis-2.6.5/examples/pi/example.eperl new file mode 100644 index 0000000..c115ed4 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.eperl @@ -0,0 +1,16 @@ +', 'b&b', '"ccc"'); +?> +

    Hello @{$user}@!

    + + + + + + + + + + +
    @!{$i}@@{$item}@
    diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.ephp b/vendor/gems/erubis-2.6.5/examples/pi/example.ephp new file mode 100644 index 0000000..dbdd884 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.ephp @@ -0,0 +1,17 @@ +', 'b&b', '"ccc"'); +?> +

    Hello @{$user}@!

    + + + + + + + + + + + +
    @!{$i}@@{$item}@
    diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.eruby b/vendor/gems/erubis-2.6.5/examples/pi/example.eruby new file mode 100644 index 0000000..85218d1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.eruby @@ -0,0 +1,15 @@ +', 'b&b', '"ccc"'] + ?> +

    Hello @{user}@!

    + + + + + + + + + +
    @!{i + 1}@@{item}@
    diff --git a/vendor/gems/erubis-2.6.5/examples/pi/example.escheme b/vendor/gems/erubis-2.6.5/examples/pi/example.escheme new file mode 100644 index 0000000..08b1cf5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/examples/pi/example.escheme @@ -0,0 +1,26 @@ +" "b&b" "\"ccc\"")) + (i 0)) + ?> +

    Hello @!{user}@!

    + + + + + + + + + +
    @!{i}@@!{item}@
    + diff --git a/vendor/gems/erubis-2.6.5/lib/erubis.rb b/vendor/gems/erubis-2.6.5/lib/erubis.rb new file mode 100644 index 0000000..9445276 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis.rb @@ -0,0 +1,72 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +## +## an implementation of eRuby +## +## ex. +## input = <<'END' +##
      +## <% for item in @list %> +##
    • <%= item %> +## <%== item %>
    • +## <% end %> +##
    +## END +## list = ['', 'b&b', '"ccc"'] +## eruby = Erubis::Eruby.new(input) +## puts "--- code ---" +## puts eruby.src +## puts "--- result ---" +## context = Erubis::Context.new() # or new(:list=>list) +## context[:list] = list +## puts eruby.evaluate(context) +## +## result: +## --- source --- +## _buf = ''; _buf << '
      +## '; for item in @list +## _buf << '
    • '; _buf << ( item ).to_s; _buf << ' +## '; _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
    • +## '; end +## _buf << '
    +## '; +## _buf.to_s +## --- result --- +##
      +##
    • +## <aaa>
    • +##
    • b&b +## b&b
    • +##
    • "ccc" +## "ccc"
    • +##
    +## + + +module Erubis + VERSION = ('$Release: 2.6.5 $' =~ /([.\d]+)/) && $1 +end + +require 'erubis/engine' +#require 'erubis/generator' +#require 'erubis/converter' +#require 'erubis/evaluator' +#require 'erubis/error' +#require 'erubis/context' +require 'erubis/helper' +require 'erubis/enhancer' +#require 'erubis/tiny' +require 'erubis/engine/eruby' +#require 'erubis/engine/enhanced' # enhanced eruby engines +#require 'erubis/engine/optimized' # generates optimized ruby code +#require 'erubis/engine/ephp' +#require 'erubis/engine/ec' +#require 'erubis/engine/ejava' +#require 'erubis/engine/escheme' +#require 'erubis/engine/eperl' +#require 'erubis/engine/ejavascript' + +require 'erubis/local-setting' diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/context.rb b/vendor/gems/erubis-2.6.5/lib/erubis/context.rb new file mode 100644 index 0000000..31398a3 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/context.rb @@ -0,0 +1,83 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +module Erubis + + + ## + ## context object for Engine#evaluate + ## + ## ex. + ## template = <<'END' + ## Hello <%= @user %>! + ## <% for item in @list %> + ## - <%= item %> + ## <% end %> + ## END + ## + ## context = Erubis::Context.new(:user=>'World', :list=>['a','b','c']) + ## # or + ## # context = Erubis::Context.new + ## # context[:user] = 'World' + ## # context[:list] = ['a', 'b', 'c'] + ## + ## eruby = Erubis::Eruby.new(template) + ## print eruby.evaluate(context) + ## + class Context + include Enumerable + + def initialize(hash=nil) + hash.each do |name, value| + self[name] = value + end if hash + end + + def [](key) + return instance_variable_get("@#{key}") + end + + def []=(key, value) + return instance_variable_set("@#{key}", value) + end + + def keys + return instance_variables.collect { |name| name[1..-1] } + end + + def each + instance_variables.each do |name| + key = name[1..-1] + value = instance_variable_get(name) + yield(key, value) + end + end + + def to_hash + hash = {} + self.keys.each { |key| hash[key] = self[key] } + return hash + end + + def update(context_or_hash) + arg = context_or_hash + if arg.is_a?(Hash) + arg.each do |key, val| + self[key] = val + end + else + arg.instance_variables.each do |varname| + key = varname[1..-1] + val = arg.instance_variable_get(varname) + self[key] = val + end + end + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/converter.rb b/vendor/gems/erubis-2.6.5/lib/erubis/converter.rb new file mode 100644 index 0000000..46f93d6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/converter.rb @@ -0,0 +1,357 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'abstract' + +module Erubis + + + ## + ## convert + ## + module Converter + + attr_accessor :preamble, :postamble, :escape + + def self.supported_properties # :nodoc: + return [ + [:preamble, nil, "preamble (no preamble when false)"], + [:postamble, nil, "postamble (no postamble when false)"], + [:escape, nil, "escape expression or not in default"], + ] + end + + def init_converter(properties={}) + @preamble = properties[:preamble] + @postamble = properties[:postamble] + @escape = properties[:escape] + end + + ## convert input string into target language + def convert(input) + codebuf = "" # or [] + @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble)) + convert_input(codebuf, input) + @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble)) + @_proc = nil # clear cached proc object + return codebuf # or codebuf.join() + end + + protected + + ## + ## detect spaces at beginning of line + ## + def detect_spaces_at_bol(text, is_bol) + lspace = nil + if text.empty? + lspace = "" if is_bol + elsif text[-1] == ?\n + lspace = "" + else + rindex = text.rindex(?\n) + if rindex + s = text[rindex+1..-1] + if s =~ /\A[ \t]*\z/ + lspace = s + #text = text[0..rindex] + text[rindex+1..-1] = '' + end + else + if is_bol && text =~ /\A[ \t]*\z/ + #lspace = text + #text = nil + lspace = text.dup + text[0..-1] = '' + end + end + end + return lspace + end + + ## + ## (abstract) convert input to code + ## + def convert_input(codebuf, input) + not_implemented + end + + end + + + module Basic + end + + + ## + ## basic converter which supports '<% ... %>' notation. + ## + module Basic::Converter + include Erubis::Converter + + def self.supported_properties # :nodoc: + return [ + [:pattern, '<% %>', "embed pattern"], + [:trim, true, "trim spaces around <% ... %>"], + ] + end + + attr_accessor :pattern, :trim + + def init_converter(properties={}) + super(properties) + @pattern = properties[:pattern] + @trim = properties[:trim] != false + end + + protected + + ## return regexp of pattern to parse eRuby script + def pattern_regexp(pattern) + @prefix, @postfix = pattern.split() # '<% %>' => '<%', '%>' + #return /(.*?)(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m + #return /(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m + return /#{@prefix}(=+|-|\#|%)?(.*?)([-=])?#{@postfix}([ \t]*\r?\n)?/m + end + module_function :pattern_regexp + + #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + #DEFAULT_REGEXP = /<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + DEFAULT_REGEXP = pattern_regexp('<% %>') + + public + + def convert_input(src, input) + pat = @pattern + regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat) + pos = 0 + is_bol = true # is beginning of line + input.scan(regexp) do |indicator, code, tailch, rspace| + match = Regexp.last_match() + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + ch = indicator ? indicator[0] : nil + lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol) + is_bol = rspace ? true : false + add_text(src, text) if text && !text.empty? + ## * when '<%= %>', do nothing + ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>' + if ch == ?= # <%= %> + rspace = nil if tailch && !tailch.empty? + add_text(src, lspace) if lspace + add_expr(src, code, indicator) + add_text(src, rspace) if rspace + elsif ch == ?\# # <%# %> + n = code.count("\n") + (rspace ? 1 : 0) + if @trim && lspace && rspace + add_stmt(src, "\n" * n) + else + add_text(src, lspace) if lspace + add_stmt(src, "\n" * n) + add_text(src, rspace) if rspace + end + elsif ch == ?% # <%% %> + s = "#{lspace}#{@prefix||='<%'}#{code}#{tailch}#{@postfix||='%>'}#{rspace}" + add_text(src, s) + else # <% %> + if @trim && lspace && rspace + add_stmt(src, "#{lspace}#{code}#{rspace}") + else + add_text(src, lspace) if lspace + add_stmt(src, code) + add_text(src, rspace) if rspace + end + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + add_text(src, rest) + end + + ## add expression code to src + def add_expr(src, code, indicator) + case indicator + when '=' + @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code) + when '==' + @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code) + when '===' + add_expr_debug(src, code) + end + end + + end + + + module PI + end + + ## + ## Processing Instructions (PI) converter for XML. + ## this class converts '' and '${...}' notation. + ## + module PI::Converter + include Erubis::Converter + + def self.desc # :nodoc: + "use processing instructions (PI) instead of '<% %>'" + end + + def self.supported_properties # :nodoc: + return [ + [:trim, true, "trim spaces around <% ... %>"], + [:pi, 'rb', "PI (Processing Instrunctions) name"], + [:embchar, '@', "char for embedded expression pattern('@{...}@')"], + [:pattern, '<% %>', "embed pattern"], + ] + end + + attr_accessor :pi, :prefix + + def init_converter(properties={}) + super(properties) + @trim = properties.fetch(:trim, true) + @pi = properties[:pi] if properties[:pi] + @embchar = properties[:embchar] || '@' + @pattern = properties[:pattern] + @pattern = '<% %>' if @pattern.nil? #|| @pattern == true + end + + def convert(input) + code = super(input) + return @header || @footer ? "#{@header}#{code}#{@footer}" : code + end + + protected + + def convert_input(codebuf, input) + unless @regexp + @pi ||= 'e' + ch = Regexp.escape(@embchar) + if @pattern + left, right = @pattern.split(' ') + @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/m + else + @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}/m + end + end + # + is_bol = true + pos = 0 + input.scan(@regexp) do |pi_arg, stmt, rspace, + indicator1, expr1, indicator2, expr2| + match = Regexp.last_match + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + lspace = stmt ? detect_spaces_at_bol(text, is_bol) : nil + is_bol = stmt && rspace ? true : false + add_text(codebuf, text) # unless text.empty? + # + if stmt + if @trim && lspace && rspace + add_pi_stmt(codebuf, "#{lspace}#{stmt}#{rspace}", pi_arg) + else + add_text(codebuf, lspace) if lspace + add_pi_stmt(codebuf, stmt, pi_arg) + add_text(codebuf, rspace) if rspace + end + else + add_pi_expr(codebuf, expr1 || expr2, indicator1 || indicator2) + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + add_text(codebuf, rest) + end + + #-- + #def convert_input(codebuf, input) + # parse_stmts(codebuf, input) + # #parse_stmts2(codebuf, input) + #end + # + #def parse_stmts(codebuf, input) + # #regexp = pattern_regexp(@pattern) + # @pi ||= 'e' + # @stmt_pattern ||= /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?/m + # is_bol = true + # pos = 0 + # input.scan(@stmt_pattern) do |pi_arg, code, rspace| + # match = Regexp.last_match + # len = match.begin(0) - pos + # text = input[pos, len] + # pos = match.end(0) + # lspace = detect_spaces_at_bol(text, is_bol) + # is_bol = rspace ? true : false + # parse_exprs(codebuf, text) # unless text.empty? + # if @trim && lspace && rspace + # add_pi_stmt(codebuf, "#{lspace}#{code}#{rspace}", pi_arg) + # else + # add_text(codebuf, lspace) + # add_pi_stmt(codebuf, code, pi_arg) + # add_text(codebuf, rspace) + # end + # end + # rest = $' || input + # parse_exprs(codebuf, rest) + #end + # + #def parse_exprs(codebuf, input) + # unless @expr_pattern + # ch = Regexp.escape(@embchar) + # if @pattern + # left, right = @pattern.split(' ') + # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/ + # else + # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}/ + # end + # end + # pos = 0 + # input.scan(@expr_pattern) do |indicator1, code1, indicator2, code2| + # indicator = indicator1 || indicator2 + # code = code1 || code2 + # match = Regexp.last_match + # len = match.begin(0) - pos + # text = input[pos, len] + # pos = match.end(0) + # add_text(codebuf, text) # unless text.empty? + # add_pi_expr(codebuf, code, indicator) + # end + # rest = $' || input + # add_text(codebuf, rest) + #end + #++ + + def add_pi_stmt(codebuf, code, pi_arg) # :nodoc: + case pi_arg + when nil ; add_stmt(codebuf, code) + when 'header' ; @header = code + when 'footer' ; @footer = code + when 'comment'; add_stmt(codebuf, "\n" * code.count("\n")) + when 'value' ; add_expr_literal(codebuf, code) + else ; add_stmt(codebuf, code) + end + end + + def add_pi_expr(codebuf, code, indicator) # :nodoc: + case indicator + when nil, '', '==' # @{...}@ or <%== ... %> + @escape == false ? add_expr_literal(codebuf, code) : add_expr_escaped(codebuf, code) + when '!', '=' # @!{...}@ or <%= ... %> + @escape == false ? add_expr_escaped(codebuf, code) : add_expr_literal(codebuf, code) + when '!!', '===' # @!!{...}@ or <%=== ... %> + add_expr_debug(codebuf, code) + else + # ignore + end + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine.rb new file mode 100644 index 0000000..1469349 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine.rb @@ -0,0 +1,120 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +require 'erubis/generator' +require 'erubis/converter' +require 'erubis/evaluator' +require 'erubis/context' + + +module Erubis + + + ## + ## (abstract) abstract engine class. + ## subclass must include evaluator and converter module. + ## + class Engine + #include Evaluator + #include Converter + #include Generator + + def initialize(input=nil, properties={}) + #@input = input + init_generator(properties) + init_converter(properties) + init_evaluator(properties) + @src = convert(input) if input + end + + + ## + ## convert input string and set it to @src + ## + def convert!(input) + @src = convert(input) + end + + + ## + ## load file, write cache file, and return engine object. + ## this method create code cache file automatically. + ## cachefile name can be specified with properties[:cachename], + ## or filname + 'cache' is used as default. + ## + def self.load_file(filename, properties={}) + cachename = properties[:cachename] || (filename + '.cache') + properties[:filename] = filename + if test(?f, cachename) && File.mtime(filename) <= File.mtime(cachename) + engine = self.new(nil, properties) + engine.src = File.read(cachename) + else + input = File.open(filename, 'rb') {|f| f.read } + engine = self.new(input, properties) + File.open(cachename, 'wb') do |f| + f.flock(File::LOCK_EX) + f.write(engine.src) + f.flush() + end + end + engine.src.untaint # ok? + return engine + end + + + ## + ## helper method to convert and evaluate input text with context object. + ## context may be Binding, Hash, or Object. + ## + def process(input, context=nil, filename=nil) + code = convert(input) + filename ||= '(erubis)' + if context.is_a?(Binding) + return eval(code, context, filename) + else + context = Context.new(context) if context.is_a?(Hash) + return context.instance_eval(code, filename) + end + end + + + ## + ## helper method evaluate Proc object with contect object. + ## context may be Binding, Hash, or Object. + ## + def process_proc(proc_obj, context=nil, filename=nil) + if context.is_a?(Binding) + filename ||= '(erubis)' + return eval(proc_obj, context, filename) + else + context = Context.new(context) if context.is_a?(Hash) + return context.instance_eval(&proc_obj) + end + end + + + end # end of class Engine + + + ## + ## (abstract) base engine class for Eruby, Eperl, Ejava, and so on. + ## subclass must include generator. + ## + class Basic::Engine < Engine + include Evaluator + include Basic::Converter + include Generator + end + + + class PI::Engine < Engine + include Evaluator + include PI::Converter + include Generator + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/ec.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ec.rb new file mode 100644 index 0000000..c4953fd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ec.rb @@ -0,0 +1,117 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + module CGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:indent, '', "indent spaces (ex. ' ')"], + [:out, 'stdout', "output file pointer name"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= "escape" + @indent = properties[:indent] || '' + @out = properties[:out] || 'stdout' + end + + def add_preamble(src) + src << "#line 1 \"#{self.filename}\"\n" if self.filename + end + + def escape_text(text) + @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" } + text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } + return text + end + + def escaped_expr(code) + return "#{@escapefunc}(#{code.strip}, #{@out})" + end + + def add_text(src, text) + return if text.empty? + src << (src.empty? || src[-1] == ?\n ? @indent : ' ') + src << "fputs(" + i = 0 + text.each_line do |line| + src << "\n" << @indent << ' ' if i > 0 + i += 1 + src << '"' << escape_text(line) << '"' + end + src << ", #{@out});" #<< (text[-1] == ?\n ? "\n" : "") + src << "\n" if text[-1] == ?\n + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + src << @indent if src.empty? || src[-1] == ?\n + src << " fprintf(#{@out}, " << code.strip << ');' + end + + def add_expr_escaped(src, code) + src << @indent if src.empty? || src[-1] == ?\n + src << ' ' << escaped_expr(code) << ';' + end + + def add_expr_debug(src, code) + code.strip! + s = nil + if code =~ /\A\".*?\"\s*,\s*(.*)/ + s = $1.gsub(/[%"]/, '\\\1') + '=' + end + src << @indent if src.empty? || src[-1] == ?\n + src << " fprintf(stderr, \"*** debug: #{s}\" #{code});" + end + + def add_postamble(src) + # empty + end + + end + + + ## + ## engine for C + ## + class Ec < Basic::Engine + include CGenerator + end + + + class EscapedEc < Ec + include EscapeEnhancer + end + + + #class XmlEc < Ec + # include EscapeEnhancer + #end + + class PI::Ec < PI::Engine + include CGenerator + + def init_converter(properties={}) + @pi = 'c' + super(properties) + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/ejava.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ejava.rb new file mode 100644 index 0000000..17cf980 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ejava.rb @@ -0,0 +1,110 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + module JavaGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:indent, '', "indent spaces (ex. ' ')"], + [:buf, '_buf', "output buffer name"], + [:bufclass, 'StringBuffer', "output buffer class (ex. 'StringBuilder')"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'escape' + @indent = properties[:indent] || '' + @buf = properties[:buf] || '_buf' + @bufclass = properties[:bufclass] || 'StringBuffer' + end + + def add_preamble(src) + src << "#{@indent}#{@bufclass} #{@buf} = new #{@bufclass}();" + end + + def escape_text(text) + @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" } + return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text + end + + def add_text(src, text) + return if text.empty? + src << (src.empty? || src[-1] == ?\n ? @indent : ' ') + src << @buf << ".append(" + i = 0 + text.each_line do |line| + src << "\n" << @indent << ' + ' if i > 0 + i += 1 + src << '"' << escape_text(line) << '"' + end + src << ");" << (text[-1] == ?\n ? "\n" : "") + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + src << @indent if src.empty? || src[-1] == ?\n + code.strip! + src << " #{@buf}.append(#{code});" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + code.strip! + src << @indent if src.empty? || src[-1] == ?\n + src << " System.err.println(\"*** debug: #{code}=\"+(#{code}));" + end + + def add_postamble(src) + src << "\n" if src[-1] == ?; + src << @indent << "return " << @buf << ".toString();\n" + #src << @indent << "System.out.print(" << @buf << ".toString());\n" + end + + end + + + ## + ## engine for Java + ## + class Ejava < Basic::Engine + include JavaGenerator + end + + + class EscapedEjava < Ejava + include EscapeEnhancer + end + + + #class XmlEjava < Ejava + # include EscapeEnhancer + #end + + class PI::Ejava < PI::Engine + include JavaGenerator + + def init_converter(properties={}) + @pi = 'java' + super(properties) + end + + end + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/ejavascript.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ejavascript.rb new file mode 100644 index 0000000..ce45330 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ejavascript.rb @@ -0,0 +1,119 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + module JavascriptGenerator + include Generator + + def self.supported_properties() # :nodoc: + list = [] + #list << [:indent, '', "indent spaces (ex. ' ')"] + #list << [:buf, '_buf', "output buffer name"] + list << [:docwrite, true, "use 'document.write()' when true"] + return list + end + + def init_generator(properties={}) + super + @escapefunc ||= 'escape' + @indent = properties[:indent] || '' + @buf = properties[:out] || '_buf' + @docwrite = properties[:docwrite] != false # '!= false' will be removed in the next release + end + + def add_preamble(src) + src << "#{@indent}var #{@buf} = [];" + end + + def escape_text(text) + @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n\\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" } + return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text + end + + def add_indent(src, indent) + src << (src.empty? || src[-1] == ?\n ? indent : ' ') + end + + def add_text(src, text) + return if text.empty? + add_indent(src, @indent) + src << @buf << '.push("' + s = escape_text(text) + if s[-1] == ?\n + s[-2, 2] = '' + src << s << "\");\n" + else + src << s << "\");" + end + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + add_indent(src, @indent) + code.strip! + src << "#{@buf}.push(#{code});" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + add_indent(src, @indent) + code.strip! + src << "alert(\"*** debug: #{code}=\"+(#{code}));" + end + + def add_postamble(src) + src << "\n" if src[-1] == ?; + if @docwrite + src << @indent << 'document.write(' << @buf << ".join(\"\"));\n" + else + src << @indent << @buf << ".join(\"\");\n" + end + end + + end + + + ## + ## engine for JavaScript + ## + class Ejavascript < Basic::Engine + include JavascriptGenerator + end + + + class EscapedEjavascript < Ejavascript + include EscapeEnhancer + end + + + #class XmlEjavascript < Ejavascript + # include EscapeEnhancer + #end + + + class PI::Ejavascript < PI::Engine + include JavascriptGenerator + + def init_converter(properties={}) + @pi = 'js' + super(properties) + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/enhanced.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/enhanced.rb new file mode 100644 index 0000000..4e92d92 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/enhanced.rb @@ -0,0 +1,121 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/enhancer' +require 'erubis/engine/eruby' + + +module Erubis + + + #-- + ## moved to engine/ruby.rb + #class EscapedEruby < Eruby + # include EscapeEnhancer + #end + #++ + + + #-- + ### (obsolete) + #class FastEruby < Eruby + # include FastEnhancer + #end + #++ + + + class StdoutEruby < Eruby + include StdoutEnhancer + end + + + class PrintOutEruby < Eruby + include PrintOutEnhancer + end + + + class PrintEnabledEruby < Eruby + include PrintEnabledEnhancer + end + + + class ArrayEruby < Eruby + include ArrayEnhancer + end + + + class ArrayBufferEruby < Eruby + include ArrayBufferEnhancer + end + + + class StringBufferEruby < Eruby + include StringBufferEnhancer + end + + + class StringIOEruby < Eruby + include StringIOEnhancer + end + + + class ErboutEruby < Eruby + include ErboutEnhancer + end + + + class NoTextEruby < Eruby + include NoTextEnhancer + end + + + class NoCodeEruby < Eruby + include NoCodeEnhancer + end + + + class SimplifiedEruby < Eruby + include SimplifyEnhancer + end + + + class StdoutSimplifiedEruby < Eruby + include StdoutEnhancer + include SimplifyEnhancer + end + + + class PrintOutSimplifiedEruby < Eruby + include PrintOutEnhancer + include SimplifyEnhancer + end + + + class BiPatternEruby < Eruby + include BiPatternEnhancer + end + + + class PercentLineEruby < Eruby + include PercentLineEnhancer + end + + + class HeaderFooterEruby < Eruby + include HeaderFooterEnhancer + end + + + class DeleteIndentEruby < Eruby + include DeleteIndentEnhancer + end + + + class InterpolationEruby < Eruby + include InterpolationEnhancer + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/eperl.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/eperl.rb new file mode 100644 index 0000000..9696318 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/eperl.rb @@ -0,0 +1,95 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + module PerlGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:func, 'print', "function name"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'encode_entities' + @func = properties[:func] || 'print' + end + + def add_preamble(src) + src << "use HTML::Entities; "; + end + + def escape_text(text) + return text.gsub!(/['\\]/, '\\\\\&') || text + end + + def add_text(src, text) + src << @func << "('" << escape_text(text) << "'); " unless text.empty? + end + + def add_expr_literal(src, code) + code.strip! + src << @func << "(" << code << "); " + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + code.strip! + s = code.gsub(/\'/, "\\'") + src << @func << "('*** debug: #{code}=', #{code}, \"\\n\");" + end + + def add_stmt(src, code) + src << code + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + end + + end + + + ## + ## engine for Perl + ## + class Eperl < Basic::Engine + include PerlGenerator + end + + + class EscapedEperl < Eperl + include EscapeEnhancer + end + + + #class XmlEperl < Eperl + # include EscapeEnhancer + #end + + + class PI::Eperl < PI::Engine + include PerlGenerator + + def init_converter(properties={}) + @pi = 'perl' + super(properties) + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/ephp.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ephp.rb new file mode 100644 index 0000000..8d71478 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/ephp.rb @@ -0,0 +1,99 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + module PhpGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'htmlspecialchars' + end + + def add_preamble(src) + # empty + end + + def escape_text(text) + return text.gsub!(/<\?xml\b/, '<?xml') || text + end + + def add_text(src, text) + src << escape_text(text) + end + + def add_expr_literal(src, code) + code.strip! + src << "" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + code.strip! + s = code.gsub(/\'/, "\\'") + src << "" + end + + def add_stmt(src, code) + src << "\n" + else + src << code << "?>" + end + end + + def add_postamble(src) + # empty + end + + end + + + ## + ## engine for PHP + ## + class Ephp < Basic::Engine + include PhpGenerator + end + + + class EscapedEphp < Ephp + include EscapeEnhancer + end + + + #class XmlEphp < Ephp + # include EscapeEnhancer + #end + + + class PI::Ephp < PI::Engine + include PhpGenerator + + def init_converter(properties={}) + @pi = 'php' + super(properties) + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/eruby.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/eruby.rb new file mode 100644 index 0000000..46d72a5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/eruby.rb @@ -0,0 +1,124 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + ## + ## code generator for Ruby + ## + module RubyGenerator + include Generator + #include ArrayBufferEnhancer + include StringBufferEnhancer + + def init_generator(properties={}) + super + @escapefunc ||= "Erubis::XmlHelper.escape_xml" + end + + def self.supported_properties() # :nodoc: + return [] + end + + def escape_text(text) + text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\' + end + + def escaped_expr(code) + return "#{@escapefunc}(#{code})" + end + + #-- + #def add_preamble(src) + # src << "_buf = [];" + #end + #++ + + def add_text(src, text) + src << " _buf << '" << escape_text(text) << "';" unless text.empty? + end + + def add_stmt(src, code) + #src << code << ';' + src << code + src << ';' unless code[-1] == ?\n + end + + def add_expr_literal(src, code) + src << ' _buf << (' << code << ').to_s;' + end + + def add_expr_escaped(src, code) + src << ' _buf << ' << escaped_expr(code) << ';' + end + + def add_expr_debug(src, code) + code.strip! + s = (code.dump =~ /\A"(.*)"\z/) && $1 + src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");' + end + + #-- + #def add_postamble(src) + # src << "\n_buf.join\n" + #end + #++ + + end + + + ## + ## engine for Ruby + ## + class Eruby < Basic::Engine + include RubyEvaluator + include RubyGenerator + end + + + ## + ## fast engine for Ruby + ## + class FastEruby < Eruby + include InterpolationEnhancer + end + + + ## + ## swtich '<%= %>' to escaped and '<%== %>' to not escaped + ## + class EscapedEruby < Eruby + include EscapeEnhancer + end + + + ## + ## sanitize expression (<%= ... %>) by default + ## + ## this is equivalent to EscapedEruby and is prepared only for compatibility. + ## + class XmlEruby < Eruby + include EscapeEnhancer + end + + + class PI::Eruby < PI::Engine + include RubyEvaluator + include RubyGenerator + + def init_converter(properties={}) + @pi = 'rb' + super(properties) + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/escheme.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/escheme.rb new file mode 100644 index 0000000..62341c2 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/escheme.rb @@ -0,0 +1,114 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/engine' +require 'erubis/enhancer' + + +module Erubis + + + module SchemeGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [ + [:func, '_add', "function name (ex. 'display')"], + ] + end + + def init_generator(properties={}) + super + @escapefunc ||= 'escape' + @func = properties[:func] || '_add' # or 'display' + end + + def add_preamble(src) + return unless @func == '_add' + src << "(let ((_buf '())) " + \ + "(define (_add x) (set! _buf (cons x _buf))) " + #src << "(let* ((_buf '())" + \ + # " (_add (lambda (x) (set! _buf (cons x _buf))))) " + end + + def escape_text(text) + @table_ ||= { '"'=>'\\"', '\\'=>'\\\\' } + text.gsub!(/["\\]/) { |m| @table_[m] } + return text + end + + def escaped_expr(code) + code.strip! + return "(#{@escapefunc} #{code})" + end + + def add_text(src, text) + return if text.empty? + t = escape_text(text) + if t[-1] == ?\n + t[-1, 1] = '' + src << "(#{@func} \"" << t << "\\n\")\n" + else + src << "(#{@func} \"" << t << '")' + end + end + + def add_stmt(src, code) + src << code + end + + def add_expr_literal(src, code) + code.strip! + src << "(#{@func} #{code})" + end + + def add_expr_escaped(src, code) + add_expr_literal(src, escaped_expr(code)) + end + + def add_expr_debug(src, code) + s = (code.strip! || code).gsub(/\"/, '\\"') + src << "(display \"*** debug: #{s}=\")(display #{code.strip})(display \"\\n\")" + end + + def add_postamble(src) + return unless @func == '_add' + src << "\n" unless src[-1] == ?\n + src << " (reverse _buf))\n" + end + + end + + + ## + ## engine for Scheme + ## + class Escheme < Basic::Engine + include SchemeGenerator + end + + + class EscapedEscheme < Escheme + include EscapeEnhancer + end + + + #class XmlEscheme < Escheme + # include EscapeEnhancer + #end + + + class PI::Escheme < PI::Engine + include SchemeGenerator + + def init_converter(properties={}) + @pi = 'scheme' + super(properties) + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/engine/optimized.rb b/vendor/gems/erubis-2.6.5/lib/erubis/engine/optimized.rb new file mode 100644 index 0000000..d2165f1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/engine/optimized.rb @@ -0,0 +1,127 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +require 'erubis/engine/eruby' + + +module Erubis + + + module OptimizedGenerator + include Generator + + def self.supported_properties() # :nodoc: + return [] + end + + def init_generator(properties={}) + super + @escapefunc ||= "Erubis::XmlHelper.escape_xml" + @initialized = false + @prev_is_expr = false + end + + protected + + def escape_text(text) + text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\' + end + + def escaped_expr(code) + @escapefunc ||= 'Erubis::XmlHelper.escape_xml' + return "#{@escapefunc}(#{code})" + end + + def switch_to_expr(src) + return if @prev_is_expr + @prev_is_expr = true + src << ' _buf' + end + + def switch_to_stmt(src) + return unless @prev_is_expr + @prev_is_expr = false + src << ';' + end + + def add_preamble(src) + #@initialized = false + #@prev_is_expr = false + end + + def add_text(src, text) + return if text.empty? + if @initialized + switch_to_expr(src) + src << " << '" << escape_text(text) << "'" + else + src << "_buf = '" << escape_text(text) << "';" + @initialized = true + end + end + + def add_stmt(src, code) + switch_to_stmt(src) if @initialized + #super + src << code + src << ';' unless code[-1] == ?\n + end + + def add_expr_literal(src, code) + unless @initialized; src << "_buf = ''"; @initialized = true; end + switch_to_expr(src) + src << " << (" << code << ").to_s" + end + + def add_expr_escaped(src, code) + unless @initialized; src << "_buf = ''"; @initialized = true; end + switch_to_expr(src) + src << " << " << escaped_expr(code) + end + + def add_expr_debug(src, code) + code.strip! + s = (code.dump =~ /\A"(.*)"\z/) && $1 + src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");' + end + + def add_postamble(src) + #super if @initialized + src << "\n_buf\n" if @initialized + end + + end # end of class OptimizedEruby + + + ## + ## Eruby class which generates optimized ruby code + ## + class OptimizedEruby < Basic::Engine # Eruby + include RubyEvaluator + include OptimizedGenerator + + def init_converter(properties={}) + @pi = 'rb' + super(properties) + end + + end + + + ## + ## XmlEruby class which generates optimized ruby code + ## + class OptimizedXmlEruby < OptimizedEruby + include EscapeEnhancer + + def add_expr_debug(src, code) + switch_to_stmt(src) if indicator == '===' && !@initialized + super + end + + end # end of class OptimizedXmlEruby + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/enhancer.rb b/vendor/gems/erubis-2.6.5/lib/erubis/enhancer.rb new file mode 100644 index 0000000..3ff74bc --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/enhancer.rb @@ -0,0 +1,680 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +module Erubis + + + ## + ## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped + ## + ## ex. + ## class XmlEruby < Eruby + ## include EscapeEnhancer + ## end + ## + ## this is language-indenedent. + ## + module EscapeEnhancer + + def self.desc # :nodoc: + "switch '<%= %>' to escaped and '<%== %>' to unescaped" + end + + #-- + #def self.included(klass) + # klass.class_eval <<-END + # alias _add_expr_literal add_expr_literal + # alias _add_expr_escaped add_expr_escaped + # alias add_expr_literal _add_expr_escaped + # alias add_expr_escaped _add_expr_literal + # END + #end + #++ + + def add_expr(src, code, indicator) + case indicator + when '=' + @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code) + when '==' + @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code) + when '===' + add_expr_debug(src, code) + end + end + + end + + + #-- + ## (obsolete) + #module FastEnhancer + #end + #++ + + + ## + ## use $stdout instead of string + ## + ## this is only for Eruby. + ## + module StdoutEnhancer + + def self.desc # :nodoc: + "use $stdout instead of array buffer or string buffer" + end + + def add_preamble(src) + src << "_buf = $stdout;" + end + + def add_postamble(src) + src << "\n''\n" + end + + end + + + ## + ## use print statement instead of '_buf << ...' + ## + ## this is only for Eruby. + ## + module PrintOutEnhancer + + def self.desc # :nodoc: + "use print statement instead of '_buf << ...'" + end + + def add_preamble(src) + end + + def add_text(src, text) + src << " print '" << escape_text(text) << "';" unless text.empty? + end + + def add_expr_literal(src, code) + src << ' print((' << code << ').to_s);' + end + + def add_expr_escaped(src, code) + src << ' print ' << escaped_expr(code) << ';' + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + end + + end + + + ## + ## enable print function + ## + ## Notice: use Eruby#evaluate() and don't use Eruby#result() + ## to be enable print function. + ## + ## this is only for Eruby. + ## + module PrintEnabledEnhancer + + def self.desc # :nodoc: + "enable to use print function in '<% %>'" + end + + def add_preamble(src) + src << "@_buf = " + super + end + + def print(*args) + args.each do |arg| + @_buf << arg.to_s + end + end + + def evaluate(context=nil) + _src = @src + if context.is_a?(Hash) + context.each do |key, val| instance_variable_set("@#{key}", val) end + elsif context + context.instance_variables.each do |name| + instance_variable_set(name, context.instance_variable_get(name)) + end + end + return instance_eval(_src, (@filename || '(erubis)')) + end + + end + + + ## + ## return array instead of string + ## + ## this is only for Eruby. + ## + module ArrayEnhancer + + def self.desc # :nodoc: + "return array instead of string" + end + + def add_preamble(src) + src << "_buf = [];" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf\n" + end + + end + + + ## + ## use an Array object as buffer (included in Eruby by default) + ## + ## this is only for Eruby. + ## + module ArrayBufferEnhancer + + def self.desc # :nodoc: + "use an Array object for buffering (included in Eruby class)" + end + + def add_preamble(src) + src << "_buf = [];" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.join\n" + end + + end + + + ## + ## use String class for buffering + ## + ## this is only for Eruby. + ## + module StringBufferEnhancer + + def self.desc # :nodoc: + "use a String object for buffering" + end + + def add_preamble(src) + src << "_buf = '';" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.to_s\n" + end + + end + + + ## + ## use StringIO class for buffering + ## + ## this is only for Eruby. + ## + module StringIOEnhancer # :nodoc: + + def self.desc # :nodoc: + "use a StringIO object for buffering" + end + + def add_preamble(src) + src << "_buf = StringIO.new;" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.string\n" + end + + end + + + ## + ## set buffer variable name to '_erbout' as well as '_buf' + ## + ## this is only for Eruby. + ## + module ErboutEnhancer + + def self.desc # :nodoc: + "set '_erbout = _buf = \"\";' to be compatible with ERB." + end + + def add_preamble(src) + src << "_erbout = _buf = '';" + end + + def add_postamble(src) + src << "\n" unless src[-1] == ?\n + src << "_buf.to_s\n" + end + + end + + + ## + ## remove text and leave code, especially useful when debugging. + ## + ## ex. + ## $ erubis -s -E NoText file.eruby | more + ## + ## this is language independent. + ## + module NoTextEnhancer + + def self.desc # :nodoc: + "remove text and leave code (useful when debugging)" + end + + def add_text(src, text) + src << ("\n" * text.count("\n")) + if text[-1] != ?\n + text =~ /^(.*?)\z/ + src << (' ' * $1.length) + end + end + + end + + + ## + ## remove code and leave text, especially useful when validating HTML tags. + ## + ## ex. + ## $ erubis -s -E NoCode file.eruby | tidy -errors + ## + ## this is language independent. + ## + module NoCodeEnhancer + + def self.desc # :nodoc: + "remove code and leave text (useful when validating HTML)" + end + + def add_preamble(src) + end + + def add_postamble(src) + end + + def add_text(src, text) + src << text + end + + def add_expr(src, code, indicator) + src << "\n" * code.count("\n") + end + + def add_stmt(src, code) + src << "\n" * code.count("\n") + end + + end + + + ## + ## get convert faster, but spaces around '<%...%>' are not trimmed. + ## + ## this is language-independent. + ## + module SimplifyEnhancer + + def self.desc # :nodoc: + "get convert faster but leave spaces around '<% %>'" + end + + #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m + SIMPLE_REGEXP = /<%(=+|\#)?(.*?)-?%>/m + + def convert(input) + src = "" + add_preamble(src) + #regexp = pattern_regexp(@pattern) + pos = 0 + input.scan(SIMPLE_REGEXP) do |indicator, code| + match = Regexp.last_match + index = match.begin(0) + text = input[pos, index - pos] + pos = match.end(0) + add_text(src, text) + if !indicator # <% %> + add_stmt(src, code) + elsif indicator[0] == ?\# # <%# %> + n = code.count("\n") + add_stmt(src, "\n" * n) + else # <%= %> + add_expr(src, code, indicator) + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + add_text(src, rest) + add_postamble(src) + return src + end + + end + + + ## + ## enable to use other embedded expression pattern (default is '\[= =\]'). + ## + ## notice! this is an experimental. spec may change in the future. + ## + ## ex. + ## input = < + ## <%= item %> : <%== item %> + ## [= item =] : [== item =] + ## <% end %> + ## END + ## + ## class BiPatternEruby + ## include BiPatternEnhancer + ## end + ## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]') + ## list = ['', 'b&b', '"c"'] + ## print eruby.result(binding()) + ## + ## ## output + ## : <a> + ## : <a> + ## b&b : b&b + ## b&b : b&b + ## "c" : "c" + ## "c" : "c" + ## + ## this is language independent. + ## + module BiPatternEnhancer + + def self.desc # :nodoc: + "another embedded expression pattern (default '\[= =\]')." + end + + def initialize(input, properties={}) + self.bipattern = properties[:bipattern] # or '\$\{ \}' + super + end + + ## when pat is nil then '\[= =\]' is used + def bipattern=(pat) # :nodoc: + @bipattern = pat || '\[= =\]' + pre, post = @bipattern.split() + @bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m + end + + def add_text(src, text) + return unless text + m = nil + text.scan(@bipattern_regexp) do |txt, indicator, code| + m = Regexp.last_match + super(src, txt) + add_expr(src, code, '=' + indicator) + end + #rest = $' || text # ruby1.8 + rest = m ? text[m.end(0)..-1] : text # ruby1.9 + super(src, rest) + end + + end + + + ## + ## regards lines starting with '%' as program code + ## + ## this is for compatibility to eruby and ERB. + ## + ## this is language-independent. + ## + module PercentLineEnhancer + + def self.desc # :nodoc: + "regard lines starting with '%' as program code" + end + + def add_text(src, text) + pos = 0 + text2 = '' + text.scan(/^\%(.*?\r?\n)/) do + line = $1 + match = Regexp.last_match + len = match.begin(0) - pos + str = text[pos, len] + pos = match.end(0) + if text2.empty? + text2 = str + else + text2 << str + end + if line[0] == ?% + text2 << line + else + super(src, text2) + text2 = '' + add_stmt(src, line) + end + end + #rest = pos == 0 ? text : $' # ruby1.8 + rest = pos == 0 ? text : text[pos..-1] # ruby1.9 + unless text2.empty? + text2 << rest if rest + rest = text2 + end + super(src, rest) + end + + end + + + ## + ## [experimental] allow header and footer in eRuby script + ## + ## ex. + ## ==================== + ## ## without header and footer + ## $ cat ex1.eruby + ## <% def list_items(list) %> + ## <% for item in list %> + ##
  • <%= item %>
  • + ## <% end %> + ## <% end %> + ## + ## $ erubis -s ex1.eruby + ## _buf = []; def list_items(list) + ## ; for item in list + ## ; _buf << '
  • '; _buf << ( item ).to_s; _buf << '
  • + ## '; end + ## ; end + ## ; + ## _buf.join + ## + ## ## with header and footer + ## $ cat ex2.eruby + ## + ## <% for item in list %> + ##
  • <%= item %>
  • + ## <% end %> + ## + ## + ## $ erubis -s -c HeaderFooterEruby ex4.eruby + ## + ## def list_items(list) + ## _buf = []; _buf << ' + ## '; for item in list + ## ; _buf << '
  • '; _buf << ( item ).to_s; _buf << '
  • + ## '; end + ## ; _buf << ' + ## '; + ## _buf.join + ## end + ## + ## ==================== + ## + ## this is language-independent. + ## + module HeaderFooterEnhancer + + def self.desc # :nodoc: + "allow header/footer in document (ex. '')" + end + + HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?([ \t]*\r?\n)?/m + + def add_text(src, text) + m = nil + text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace| + m = Regexp.last_match + flag_trim = @trim && lspace && rspace + super(src, txt) + content = "#{lspace}#{content}#{rspace}" if flag_trim + super(src, lspace) if !flag_trim && lspace + instance_variable_set("@#{word}", content) + super(src, rspace) if !flag_trim && rspace + end + #rest = $' || text # ruby1.8 + rest = m ? text[m.end(0)..-1] : text # ruby1.9 + super(src, rest) + end + + attr_accessor :header, :footer + + def convert(input) + source = super + return @src = "#{@header}#{source}#{@footer}" + end + + end + + + ## + ## delete indentation of HTML. + ## + ## this is language-independent. + ## + module DeleteIndentEnhancer + + def self.desc # :nodoc: + "delete indentation of HTML." + end + + def convert_input(src, input) + input = input.gsub(/^[ \t]+<%=title%>" into "_buf << %Q`

    #{title}

    `" + ## + ## this is only for Eruby. + ## + module InterpolationEnhancer + + def self.desc # :nodoc: + "convert '

    <%=text%>

    ' into '_buf << %Q`

    \#{text}

    `'" + end + + def convert_input(src, input) + pat = @pattern + regexp = pat.nil? || pat == '<% %>' ? Basic::Converter::DEFAULT_REGEXP : pattern_regexp(pat) + pos = 0 + is_bol = true # is beginning of line + str = '' + input.scan(regexp) do |indicator, code, tailch, rspace| + match = Regexp.last_match() + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + ch = indicator ? indicator[0] : nil + lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol) + is_bol = rspace ? true : false + _add_text_to_str(str, text) + ## * when '<%= %>', do nothing + ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>' + if ch == ?= # <%= %> + rspace = nil if tailch && !tailch.empty? + str << lspace if lspace + add_expr(str, code, indicator) + str << rspace if rspace + elsif ch == ?\# # <%# %> + n = code.count("\n") + (rspace ? 1 : 0) + if @trim && lspace && rspace + add_text(src, str) + str = '' + add_stmt(src, "\n" * n) + else + str << lspace if lspace + add_text(src, str) + str = '' + add_stmt(src, "\n" * n) + str << rspace if rspace + end + else # <% %> + if @trim && lspace && rspace + add_text(src, str) + str = '' + add_stmt(src, "#{lspace}#{code}#{rspace}") + else + str << lspace if lspace + add_text(src, str) + str = '' + add_stmt(src, code) + str << rspace if rspace + end + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + _add_text_to_str(str, rest) + add_text(src, str) + end + + def add_text(src, text) + return if !text || text.empty? + #src << " _buf << %Q`" << text << "`;" + if text[-1] == ?\n + text[-1] = "\\n" + src << " _buf << %Q`" << text << "`\n" + else + src << " _buf << %Q`" << text << "`;" + end + end + + def _add_text_to_str(str, text) + return if !text || text.empty? + text.gsub!(/['\#\\]/, '\\\\\&') + str << text + end + + def add_expr_escaped(str, code) + str << "\#{#{escaped_expr(code)}}" + end + + def add_expr_literal(str, code) + str << "\#{#{code}}" + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/error.rb b/vendor/gems/erubis-2.6.5/lib/erubis/error.rb new file mode 100644 index 0000000..be6ac2c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/error.rb @@ -0,0 +1,23 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +module Erubis + + + ## + ## base error class + ## + class ErubisError < StandardError + end + + + ## + ## raised when method or function is not supported + ## + class NotSupportedError < ErubisError + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/evaluator.rb b/vendor/gems/erubis-2.6.5/lib/erubis/evaluator.rb new file mode 100644 index 0000000..05e3609 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/evaluator.rb @@ -0,0 +1,88 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'erubis/error' +require 'erubis/context' + + +module Erubis + + EMPTY_BINDING = binding() + + + ## + ## evaluate code + ## + module Evaluator + + def self.supported_properties # :nodoc: + return [] + end + + attr_accessor :src, :filename + + def init_evaluator(properties) + @filename = properties[:filename] + end + + def result(*args) + raise NotSupportedError.new("evaluation of code except Ruby is not supported.") + end + + def evaluate(*args) + raise NotSupportedError.new("evaluation of code except Ruby is not supported.") + end + + end + + + ## + ## evaluator for Ruby + ## + module RubyEvaluator + include Evaluator + + def self.supported_properties # :nodoc: + list = Evaluator.supported_properties + return list + end + + ## eval(@src) with binding object + def result(_binding_or_hash=TOPLEVEL_BINDING) + _arg = _binding_or_hash + if _arg.is_a?(Hash) + _b = binding() + eval _arg.collect{|k,v| "#{k} = _arg[#{k.inspect}]; "}.join, _b + elsif _arg.is_a?(Binding) + _b = _arg + elsif _arg.nil? + _b = binding() + else + raise ArgumentError.new("#{self.class.name}#result(): argument should be Binding or Hash but passed #{_arg.class.name} object.") + end + return eval(@src, _b, (@filename || '(erubis')) + end + + ## invoke context.instance_eval(@src) + def evaluate(_context=Context.new) + _context = Context.new(_context) if _context.is_a?(Hash) + #return _context.instance_eval(@src, @filename || '(erubis)') + #@_proc ||= eval("proc { #{@src} }", Erubis::EMPTY_BINDING, @filename || '(erubis)') + @_proc ||= eval("proc { #{@src} }", binding(), @filename || '(erubis)') + return _context.instance_eval(&@_proc) + end + + ## if object is an Class or Module then define instance method to it, + ## else define singleton method to it. + def def_method(object, method_name, filename=nil) + m = object.is_a?(Module) ? :module_eval : :instance_eval + object.__send__(m, "def #{method_name}; #{@src}; end", filename || @filename || '(erubis)') + end + + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/generator.rb b/vendor/gems/erubis-2.6.5/lib/erubis/generator.rb new file mode 100644 index 0000000..a080dfd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/generator.rb @@ -0,0 +1,85 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require 'abstract' + +module Erubis + + + ## + ## code generator, called by Converter module + ## + module Generator + + def self.supported_properties() # :nodoc: + return [ + [:escapefunc, nil, "escape function name"], + ] + end + + attr_accessor :escapefunc + + def init_generator(properties={}) + @escapefunc = properties[:escapefunc] + end + + + ## (abstract) escape text string + ## + ## ex. + ## def escape_text(text) + ## return text.dump + ## # or return "'" + text.gsub(/['\\]/, '\\\\\&') + "'" + ## end + def escape_text(text) + not_implemented + end + + ## return escaped expression code (ex. 'h(...)' or 'htmlspecialchars(...)') + def escaped_expr(code) + code.strip! + return "#{@escapefunc}(#{code})" + end + + ## (abstract) add @preamble to src + def add_preamble(src) + not_implemented + end + + ## (abstract) add text string to src + def add_text(src, text) + not_implemented + end + + ## (abstract) add statement code to src + def add_stmt(src, code) + not_implemented + end + + ## (abstract) add expression literal code to src. this is called by add_expr(). + def add_expr_literal(src, code) + not_implemented + end + + ## (abstract) add escaped expression code to src. this is called by add_expr(). + def add_expr_escaped(src, code) + not_implemented + end + + ## (abstract) add expression code to src for debug. this is called by add_expr(). + def add_expr_debug(src, code) + not_implemented + end + + ## (abstract) add @postamble to src + def add_postamble(src) + not_implemented + end + + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/helper.rb b/vendor/gems/erubis-2.6.5/lib/erubis/helper.rb new file mode 100644 index 0000000..47623bd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/helper.rb @@ -0,0 +1,47 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +module Erubis + + ## + ## helper for xml + ## + module XmlHelper + + module_function + + ESCAPE_TABLE = { + '&' => '&', + '<' => '<', + '>' => '>', + '"' => '"', + "'" => ''', + } + + def escape_xml(value) + value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] } # or /[&<>"']/ + #value.to_s.gsub(/[&<>"]/) { ESCAPE_TABLE[$&] } + end + + def escape_xml2(value) + return value.to_s.gsub(/\&/,'&').gsub(//,'>').gsub(/"/,'"') + end + + alias h escape_xml + alias html_escape escape_xml + + def url_encode(str) + return str.gsub(/[^-_.a-zA-Z0-9]+/) { |s| + s.unpack('C*').collect { |i| "%%%02X" % i }.join + } + end + + alias u url_encode + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/helpers/rails_form_helper.rb b/vendor/gems/erubis-2.6.5/lib/erubis/helpers/rails_form_helper.rb new file mode 100644 index 0000000..e9aab84 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/helpers/rails_form_helper.rb @@ -0,0 +1,197 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + + +module Erubis + module Helpers + module RailsFormHelper + end + end +end + + +module Erubis::Helpers::RailsFormHelper + + +if ActionPack::VERSION::MAJOR == 1 ### Rails 1.X + def pp_template_filename(basename) + return "#{RAILS_ROOT}/app/views/#{controller.controller_name}/#{basename}.rhtml" + end +else ### Rails 2.X + def pp_template_filename(basename) + fname = "#{RAILS_ROOT}/app/views/#{controller.controller_name}/#{basename}.html.erb" + return fname if test(?f, fname) + return "#{RAILS_ROOT}/app/views/#{controller.controller_name}/#{basename}.rhtml" + end +end + + def pp_render_partial(basename) + basename = "_#{basename}" unless basename[0] == ?_ + filename = pp_template_filename(basename) + preprocessor = _create_preprocessor(File.read(filename)) + return preprocessor.evaluate(_preprocessing_context_object()) + end + + def pp_error_on(object_name, method) + s = '' + s << "<% _stag, _etag = _pp_error_tags(@#{object_name}.errors.on('#{method}')) %>" + s << "<%= _stag %>" + s << yield(object_name, method) + s << "<%= _etag %>" + return s + end + + def _pp_error_tags(value) + return value ? ['
    ', '
    '] : ['', ''] + end + + def _pp_remove_error_div(s) + s.sub!(/\A
    (.*)<\/div>\z/, '\1') + return s + end + + def pp_tag_helper(helper, object_name, method, options={}) + if object_name.is_a?(ActionView::Helpers::FormHelper) + object_name = object_name.object_name + end + unless options.key?(:value) || options.key?('value') + options['value'] = _?("h @#{object_name}.#{method}") + end + #$stderr.puts "*** debug: pp_tag_helper(): options=#{options.inspect}" + return pp_error_on(object_name, method) { + s = __send__(helper, object_name, method, options) + _pp_remove_error_div(s) + } + end + + def pp_form_tag(url_for_options={}, options={}, *parameters_for_url, &block) + return form_tag(url_for_options, options, *parameters_for_url, &block) + end + + #-- + #def pp_form_for(object_name, *args, &block) + # return form_for(object_name, *args, &block) + #end + #++ + + def pp_text_field(object_name, method, options={}) + return pp_tag_helper(:text_field, object_name, method, options) + end + + def pp_password_field(object_name, method, options={}) + return pp_tag_helper(:password_field, object_name, method, options) + end + + def pp_hidden_field(object_name, method, options={}) + return pp_tag_helper(:hidden_field, object_name, method, options) + end + + def pp_file_field(object_name, method, options={}) + return pp_tag_helper(:file_field, object_name, method, options) + end + + def pp_text_area(object_name, method, options={}) + return pp_tag_helper(:text_area, object_name, method, options) + end + + def pp_check_box(object_name, method, options={}, checked_value="1", unchecked_value="0") + s = check_box(object_name, method, options, checked_value, unchecked_value) + s.sub!(/\schecked=\"checked\"/, '') + s.sub!(/type="checkbox"/, "\\&<%= _pp_check_box_checked?(@#{object_name}.#{method}, #{checked_value.inspect}) ? ' checked=\"checked\"' : '' %>") + return pp_error_on(object_name, method) { _pp_remove_error_div(s) } + end + + def _pp_check_box_checked?(value, checked_value) + return ActionView::Helpers::InstanceTag::check_box_checked?(value, checked_value) + end + + def pp_radio_button(object_name, method, tag_value, options={}) + s = radio_button(object_name, method, tag_value, options) + s.sub!(/\schecked=\"checked\"/, '') + s.sub!(/type="radio"/, "\\&<%= _pp_radio_button_checked?(@#{object_name}.#{method}, #{tag_value.inspect}) ? ' checked=\"checked\"' : '' %>") + return pp_error_on(object_name, method) { _pp_remove_error_div(s) } + end + + def _pp_radio_button_checked?(value, tag_value) + return ActionView::Helpers::InstanceTag::radio_button_checked?(value, tag_value) + end + + def _pp_select(object, method, collection, priority_collection, options={}, html_options={}) + return pp_error_on(object, method) do + s = "" + ## start tag + s << "" + s + end + end + + def _pp_select_options(s, collection, selected, operator) + for item in collection + value, text = item.is_a?(Array) ? item : [item, item] + if !selected + t = '' + elsif operator == 'delete' + t = "<%= _table.delete(#{value.inspect}) %>" + else + t = "<%= _table[#{value.inspect}] %>" + end + s << "\n" + end + end + + def pp_select(object, method, collection, options={}, html_options={}) + return _pp_select(object, method, collection, nil, options, html_options) + end + + def pp_collection_select(object, method, collection, value_method, text_method, options={}, html_options={}) + collection2 = collection.collect { |e| + [e.__send__(value_method), e.__send__(text_method)] + } + return _pp_select(object, method, collection2, nil, options, html_options) + end + + def pp_country_select(object, method, priority_countries=nil, options={}, html_options={}) + collection = ActionView::Helpers::FormOptionsHelper::COUNTRIES + return _pp_select(object, method, collection, priority_countries, options, html_options) + end + + def pp_time_zone_select(object, method, priority_zones=nil, options={}, html_options={}) + model = options[:model] || options['model'] || TimeZone + collection = model.all.collect { |e| [e.name, e.to_s] } + return _pp_select(object, method, collection, priority_zones, options, html_options) + end + + def pp_submit_tag(value="Save changes", options={}) + return submit_tag(value, options) + end + + def pp_image_submit_tag(source, options={}) + return image_submit_tag(source, options) + end + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/helpers/rails_helper.rb b/vendor/gems/erubis-2.6.5/lib/erubis/helpers/rails_helper.rb new file mode 100644 index 0000000..b868df9 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/helpers/rails_helper.rb @@ -0,0 +1,353 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + + +require 'erubis' +require 'erubis/preprocessing' + + +module Erubis + + class Eruby + include ErboutEnhancer # will generate '_erbout = _buf = ""; ' + end + + class FastEruby + include ErboutEnhancer # will generate '_erbout = _buf = ""; ' + end + + module Helpers + + ## + ## helper module for Ruby on Rails + ## + ## howto: + ## + ## 1. add the folliwng code in your 'config/environment.rb' + ## + ## require 'erubis/helpers/rails_helper' + ## #Erubis::Helpers::RailsHelper.engine_class = Erubis::Eruby # or Erubis::FastEruby + ## #Erubis::Helpers::RailsHelper.init_properties = {} + ## #Erubis::Helpers::RailsHelper.show_src = false # set true for debugging + ## #Erubis::Helpers::RailsHelper.preprocessing = true # set true to enable preprocessing + ## + ## 2. restart web server. + ## + ## if Erubis::Helper::Rails.show_src is true, Erubis prints converted Ruby code + ## into log file ('log/development.log' or so). if false, it doesn't. + ## if nil, Erubis prints converted Ruby code if ENV['RAILS_ENV'] == 'development'. + ## + module RailsHelper + + #cattr_accessor :init_properties + @@engine_class = ::Erubis::Eruby + #@@engine_class = ::Erubis::FastEruby + def self.engine_class + @@engine_class + end + def self.engine_class=(klass) + @@engine_class = klass + end + + #cattr_accessor :init_properties + @@init_properties = {} + def self.init_properties + @@init_properties + end + def self.init_properties=(hash) + @@init_properties = hash + end + + #cattr_accessor :show_src + @@show_src = nil + def self.show_src + @@show_src + end + def self.show_src=(flag) + @@show_src = flag + end + + #cattr_accessor :preprocessing + @@preprocessing = false + def self.preprocessing + @@preprocessing + end + def self.preprocessing=(flag) + @@preprocessing = flag + end + + + ## define class for backward-compatibility + class PreprocessingEruby < Erubis::PreprocessingEruby # :nodoc: + end + + + module TemplateConverter + ## covert eRuby string into ruby code + def _convert_template(template) # :nodoc: + #src = ::Erubis::Eruby.new(template).src + klass = ::Erubis::Helpers::RailsHelper.engine_class + properties = ::Erubis::Helpers::RailsHelper.init_properties + show_src = ::Erubis::Helpers::RailsHelper.show_src + show_src = ENV['RAILS_ENV'] == 'development' if show_src.nil? + ## preprocessing + if ::Erubis::Helpers::RailsHelper.preprocessing + preprocessor = _create_preprocessor(template) + template = preprocessor.evaluate(_preprocessing_context_object()) + _logger_info "** Erubis: preprocessed==<<'END'\n#{template}END\n" if show_src + end + ## convert into ruby code + src = klass.new(template, properties).src + #src.insert(0, '_erbout = ') + _logger_info "** Erubis: src==<<'END'\n#{src}END\n" if show_src + return src + end + def _create_preprocessor(template) + return PreprocessingEruby.new(template, :escape=>true) + end + def _preprocessing_context_object + return self + end + def _logger_info(message) + logger.info message + end + end + + end + + end + +end + + +class ActionView::Base # :nodoc: + include ::Erubis::Helpers::RailsHelper::TemplateConverter + include ::Erubis::PreprocessingHelper + private + # convert template into ruby code + def convert_template_into_ruby_code(template) + #ERB.new(template, nil, @@erb_trim_mode).src + return _convert_template(template) + end +end + + +require 'action_pack/version' + +rails22 = false + +if ActionPack::VERSION::MAJOR >= 2 ### Rails 2.X + + + if ActionPack::VERSION::MINOR >=2 ### Rails 2.2, 2.3 or higher + + rails22 = true + module ActionView + module TemplateHandlers + class ErubisHandler < TemplateHandler + include Compilable + include ::Erubis::Helpers::RailsHelper::TemplateConverter + include ::Erubis::PreprocessingHelper + def compile(template) + #src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src + return _convert_template("<% __in_erb_template=true %>#{template.source}") + end + end + end + handler_klass = TemplateHandlers::ErubisHandler + Template.register_default_template_handler :erb, handler_klass + Template.register_template_handler :rhtml, handler_klass + end + module Erubis::Helpers::RailsHelper::TemplateConverter + def _logger_info(message) + #logger.info message # logger.info seems not available in Rails 2.2 + ActionController::Base.new.logger.info message + end + end + + elsif ActionPack::VERSION::MINOR >=1 ### Rails 2.1 + + module ActionView + module TemplateHandlers # :nodoc: + class ErubisHandler < TemplateHandler + include Compilable + include Erubis::Helpers::RailsHelper::TemplateConverter + include Erubis::PreprocessingHelper + # + def compile(template) + return _convert_template(template.source) # template.is_a?(ActionView::Template) + end + def logger #:nodoc: + return @view.controller.logger + end + def _preprocessing_context_object #:nodoc: + return @view.controller.instance_variable_get('@template') + end + # + def cache_fragment(block, name = {}, options = nil) #:nodoc: + @view.fragment_for(block, name, options) do + #eval(ActionView::Base.erb_variable, block.binding) + eval('_buf', block.binding) + end + end + end + end + handler_klass = TemplateHandlers::ErubisHandler + Template.register_default_template_handler :erb, handler_klass + Template.register_template_handler :rhtml, handler_klass + end + + elsif ActionPack::VERSION::TINY >= 2 ### Rails 2.0.X (X >= 2) + + module ActionView + module TemplateHandlers # :nodoc: + class ErubisHandler < TemplateHandler + include Erubis::Helpers::RailsHelper::TemplateConverter + include Erubis::PreprocessingHelper + def compile(template) + return _convert_template(template) # template.is_a?(String) + end + def logger #:nodoc: + return @view.controller.logger + end + def _preprocessing_context_object #:nodoc: + return @view.controller.instance_variable_get('@template') + end + end + end + Base.class_eval do + handler_klass = TemplateHandlers::ErubisHandler + register_default_template_handler :erb, handler_klass + register_template_handler :rhtml, handler_klass + end + end + + else ### Rails 2.0.0 or 2.0.1 + + class ActionView::Base # :nodoc: + private + # Method to create the source code for a given template. + def create_template_source(extension, template, render_symbol, locals) + if template_requires_setup?(extension) + body = case extension.to_sym + when :rxml, :builder + content_type_handler = (controller.respond_to?(:response) ? "controller.response" : "controller") + "#{content_type_handler}.content_type ||= Mime::XML\n" + + "xml = Builder::XmlMarkup.new(:indent => 2)\n" + + template + + "\nxml.target!\n" + when :rjs + "controller.response.content_type ||= Mime::JS\n" + + "update_page do |page|\n#{template}\nend" + end + else + #body = ERB.new(template, nil, @@erb_trim_mode).src + body = convert_template_into_ruby_code(template) + end + # + @@template_args[render_symbol] ||= {} + locals_keys = @@template_args[render_symbol].keys | locals + @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } + # + locals_code = "" + locals_keys.each do |key| + locals_code << "#{key} = local_assigns[:#{key}]\n" + end + # + "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" + end + end + + end #if + + +else ### Rails 1.X + + + if ActionPack::VERSION::MINOR > 12 ### Rails 1.2 + + class ActionView::Base # :nodoc: + private + # Create source code for given template + def create_template_source(extension, template, render_symbol, locals) + if template_requires_setup?(extension) + body = case extension.to_sym + when :rxml + "controller.response.content_type ||= 'application/xml'\n" + + "xml = Builder::XmlMarkup.new(:indent => 2)\n" + + template + when :rjs + "controller.response.content_type ||= 'text/javascript'\n" + + "update_page do |page|\n#{template}\nend" + end + else + #body = ERB.new(template, nil, @@erb_trim_mode).src + body = convert_template_into_ruby_code(template) + end + # + @@template_args[render_symbol] ||= {} + locals_keys = @@template_args[render_symbol].keys | locals + @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } + # + locals_code = "" + locals_keys.each do |key| + locals_code << "#{key} = local_assigns[:#{key}]\n" + end + # + "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" + end + end + + else ### Rails 1.1 + + class ActionView::Base # :nodoc: + private + # Create source code for given template + def create_template_source(extension, template, render_symbol, locals) + if template_requires_setup?(extension) + body = case extension.to_sym + when :rxml + "xml = Builder::XmlMarkup.new(:indent => 2)\n" + + "@controller.headers['Content-Type'] ||= 'application/xml'\n" + + template + when :rjs + "@controller.headers['Content-Type'] ||= 'text/javascript'\n" + + "update_page do |page|\n#{template}\nend" + end + else + #body = ERB.new(template, nil, @@erb_trim_mode).src + body = convert_template_into_ruby_code(template) + end + # + @@template_args[render_symbol] ||= {} + locals_keys = @@template_args[render_symbol].keys | locals + @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } + # + locals_code = "" + locals_keys.each do |key| + locals_code << "#{key} = local_assigns[:#{key}] if local_assigns.has_key?(:#{key})\n" + end + # + "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" + end + end + + end #if + + ## make h() method faster (only for Rails 1.X) + module ERB::Util # :nodoc: + ESCAPE_TABLE = { '&'=>'&', '<'=>'<', '>'=>'>', '"'=>'"', "'"=>''', } + def h(value) + value.to_s.gsub(/[&<>"]/) {|s| ESCAPE_TABLE[s] } + end + module_function :h + end + +end ### + + +## finish +ActionController::Base.new.logger.info "** Erubis #{::Erubis::VERSION}" +$stdout.puts "** Erubis #{::Erubis::VERSION}" if rails22 diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/local-setting.rb b/vendor/gems/erubis-2.6.5/lib/erubis/local-setting.rb new file mode 100644 index 0000000..307cfa9 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/local-setting.rb @@ -0,0 +1,9 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +## +## you can add site-local settings here. +## this files is required by erubis.rb +## diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/main.rb b/vendor/gems/erubis-2.6.5/lib/erubis/main.rb new file mode 100644 index 0000000..265f832 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/main.rb @@ -0,0 +1,489 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require 'yaml' +require 'erubis' +require 'erubis/tiny' +require 'erubis/engine/enhanced' +require 'erubis/engine/optimized' +require 'erubis/engine/eruby' +require 'erubis/engine/ephp' +require 'erubis/engine/ec' +require 'erubis/engine/ejava' +require 'erubis/engine/escheme' +require 'erubis/engine/eperl' +require 'erubis/engine/ejavascript' + + +module Erubis + + + Ejs = Ejavascript + EscapedEjs = EscapedEjavascript + + + class CommandOptionError < ErubisError + end + + + ## + ## main class of command + ## + ## ex. + ## Main.main(ARGV) + ## + class Main + + def self.main(argv=ARGV) + status = 0 + begin + Main.new.execute(ARGV) + rescue CommandOptionError => ex + $stderr.puts ex.message + status = 1 + end + exit(status) + end + + def initialize + @single_options = "hvxztTSbeBXNUC" + @arg_options = "pcrfKIlaE" #C + @option_names = { + 'h' => :help, + 'v' => :version, + 'x' => :source, + 'z' => :syntax, + 'T' => :unexpand, + 't' => :untabify, # obsolete + 'S' => :intern, + 'b' => :bodyonly, + 'B' => :binding, + 'p' => :pattern, + 'c' => :context, + #'C' => :class, + 'e' => :escape, + 'r' => :requires, + 'f' => :datafiles, + 'K' => :kanji, + 'I' => :includes, + 'l' => :lang, + 'a' => :action, + 'E' => :enhancers, + 'X' => :notext, + 'N' => :linenum, + 'U' => :unique, + 'C' => :compact, + } + assert unless @single_options.length + @arg_options.length == @option_names.length + (@single_options + @arg_options).each_byte do |ch| + assert unless @option_names.key?(ch.chr) + end + end + + + def execute(argv=ARGV) + ## parse command-line options + options, properties = parse_argv(argv, @single_options, @arg_options) + filenames = argv + options['h'] = true if properties[:help] + opts = Object.new + arr = @option_names.collect {|ch, name| "def #{name}; @#{name}; end\n" } + opts.instance_eval arr.join + options.each do |ch, val| + name = @option_names[ch] + opts.instance_variable_set("@#{name}", val) + end + + ## help, version, enhancer list + if opts.help || opts.version + puts version() if opts.version + puts usage() if opts.help + puts show_properties() if opts.help + puts show_enhancers() if opts.help + return + end + + ## include path + opts.includes.split(/,/).each do |path| + $: << path + end if opts.includes + + ## require library + opts.requires.split(/,/).each do |library| + require library + end if opts.requires + + ## action + action = opts.action + action ||= 'syntax' if opts.syntax + action ||= 'convert' if opts.source || opts.notext + + ## lang + lang = opts.lang || 'ruby' + action ||= 'convert' if opts.lang + + ## class name of Eruby + #classname = opts.class + classname = nil + klass = get_classobj(classname, lang, properties[:pi]) + + ## kanji code + $KCODE = opts.kanji if opts.kanji + + ## read context values from yaml file + datafiles = opts.datafiles + context = load_datafiles(datafiles, opts) + + ## parse context data + if opts.context + context = parse_context_data(opts.context, opts) + end + + ## properties for engine + properties[:escape] = true if opts.escape && !properties.key?(:escape) + properties[:pattern] = opts.pattern if opts.pattern + #properties[:trim] = false if opts.notrim + properties[:preamble] = properties[:postamble] = false if opts.bodyonly + properties[:pi] = nil if properties[:pi] == true + + ## create engine and extend enhancers + engine = klass.new(nil, properties) + enhancers = get_enhancers(opts.enhancers) + #enhancers.push(Erubis::EscapeEnhancer) if opts.escape + enhancers.each do |enhancer| + engine.extend(enhancer) + engine.bipattern = properties[:bipattern] if enhancer == Erubis::BiPatternEnhancer + end + + ## no-text + engine.extend(Erubis::NoTextEnhancer) if opts.notext + + ## convert and execute + val = nil + msg = "Syntax OK\n" + if filenames && !filenames.empty? + filenames.each do |filename| + File.file?(filename) or + raise CommandOptionError.new("#{filename}: file not found.") + engine.filename = filename + engine.convert!(File.read(filename)) + val = do_action(action, engine, context, filename, opts) + msg = nil if val + end + else + engine.filename = filename = '(stdin)' + engine.convert!($stdin.read()) + val = do_action(action, engine, context, filename, opts) + msg = nil if val + end + print msg if action == 'syntax' && msg + + end + + private + + def do_action(action, engine, context, filename, opts) + case action + when 'convert' + s = manipulate_src(engine.src, opts) + when nil, 'exec', 'execute' + s = opts.binding ? engine.result(context.to_hash) : engine.evaluate(context) + when 'syntax' + s = check_syntax(filename, engine.src) + else + raise "*** internal error" + end + print s if s + return s + end + + def manipulate_src(source, opts) + flag_linenum = opts.linenum + flag_unique = opts.unique + flag_compact = opts.compact + if flag_linenum + n = 0 + source.gsub!(/^/) { n += 1; "%5d: " % n } + source.gsub!(/^ *\d+:\s+?\n/, '') if flag_compact + source.gsub!(/(^ *\d+:\s+?\n)+/, "\n") if flag_unique + else + source.gsub!(/^\s*?\n/, '') if flag_compact + source.gsub!(/(^\s*?\n)+/, "\n") if flag_unique + end + return source + end + + def usage(command=nil) + command ||= File.basename($0) + buf = [] + buf << "erubis - embedded program converter for multi-language" + buf << "Usage: #{command} [..options..] [file ...]" + buf << " -h, --help : help" + buf << " -v : version" + buf << " -x : show converted code" + buf << " -X : show converted code, only ruby code and no text part" + buf << " -N : numbering: add line numbers (for '-x/-X')" + buf << " -U : unique: compress empty lines to a line (for '-x/-X')" + buf << " -C : compact: remove empty lines (for '-x/-X')" + buf << " -b : body only: no preamble nor postamble (for '-x/-X')" + buf << " -z : syntax checking" + buf << " -e : escape (equal to '--E Escape')" + buf << " -p pattern : embedded pattern (default '<% %>')" + buf << " -l lang : convert but no execute (ruby/php/c/java/scheme/perl/js)" + buf << " -E e1,e2,... : enhancer names (Escape, PercentLine, BiPattern, ...)" + buf << " -I path : library include path" + buf << " -K kanji : kanji code (euc/sjis/utf8) (default none)" + buf << " -c context : context data string (yaml inline style or ruby code)" + buf << " -f datafile : context data file ('*.yaml', '*.yml', or '*.rb')" + #buf << " -t : expand tab characters in YAML file" + buf << " -T : don't expand tab characters in YAML file" + buf << " -S : convert mapping key from string to symbol in YAML file" + buf << " -B : invoke 'result(binding)' instead of 'evaluate(context)'" + buf << " --pi=name : parse '' instead of '<% ... %>'" + #' + # -T : don't trim spaces around '<% %>' + # -c class : class name (XmlEruby/PercentLineEruby/...) (default Eruby) + # -r library : require library + # -a : action (convert/execute) + return buf.join("\n") + end + + def collect_supported_properties(erubis_klass) + list = [] + erubis_klass.ancestors.each do |klass| + if klass.respond_to?(:supported_properties) + list.concat(klass.supported_properties) + end + end + return list + end + + def show_properties + s = "supported properties:\n" + basic_props = collect_supported_properties(Erubis::Basic::Engine) + pi_props = collect_supported_properties(Erubis::PI::Engine) + list = [] + common_props = basic_props & pi_props + list << ['(common)', common_props] + list << ['(basic)', basic_props - common_props] + list << ['(pi)', pi_props - common_props] + %w[ruby php c java scheme perl javascript].each do |lang| + klass = Erubis.const_get("E#{lang}") + list << [lang, collect_supported_properties(klass) - basic_props] + end + list.each do |lang, props| + s << " * #{lang}\n" + props.each do |name, default_val, desc| + s << (" --%-23s : %s\n" % ["#{name}=#{default_val.inspect}", desc]) + end + end + s << "\n" + return s + end + + def show_enhancers + dict = {} + ObjectSpace.each_object(Module) do |mod| + dict[$1] = mod if mod.name =~ /\AErubis::(.*)Enhancer\z/ + end + s = "enhancers:\n" + dict.sort_by {|name, mod| name }.each do |name, mod| + s << (" %-13s : %s\n" % [name, mod.desc]) + end + return s + end + + def version + return Erubis::VERSION + end + + def parse_argv(argv, arg_none='', arg_required='', arg_optional='') + options = {} + context = {} + while argv[0] && argv[0][0] == ?- + optstr = argv.shift + optstr = optstr[1, optstr.length-1] + # + if optstr[0] == ?- # context + optstr =~ /\A\-([-\w]+)(?:=(.*))?/ or + raise CommandOptionError.new("-#{optstr}: invalid context value.") + name, value = $1, $2 + name = name.gsub(/-/, '_').intern + #value = value.nil? ? true : YAML.load(value) # error, why? + value = value.nil? ? true : YAML.load("---\n#{value}\n") + context[name] = value + # + else # options + while optstr && !optstr.empty? + optchar = optstr[0].chr + optstr = optstr[1..-1] + if arg_none.include?(optchar) + options[optchar] = true + elsif arg_required.include?(optchar) + arg = optstr.empty? ? argv.shift : optstr or + raise CommandOptionError.new("-#{optchar}: #{@option_names[optchar]} required.") + options[optchar] = arg + optstr = nil + elsif arg_optional.include?(optchar) + arg = optstr.empty? ? true : optstr + options[optchar] = arg + optstr = nil + else + raise CommandOptionError.new("-#{optchar}: unknown option.") + end + end + end + # + end # end of while + + return options, context + end + + + def untabify(str, width=8) + list = str.split(/\t/) + last = list.pop + sb = '' + list.each do |s| + column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length + n = width - (column % width) + sb << s << (' ' * n) + end + sb << last + return sb + end + #-- + #def untabify(str, width=8) + # sb = '' + # str.scan(/(.*?)\t/m) do |s, | + # len = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length + # sb << s << (" " * (width - len % width)) + # end + # return $' ? (sb << $') : str + #end + #++ + + + def get_classobj(classname, lang, pi) + classname ||= "E#{lang}" + base_module = pi ? Erubis::PI : Erubis + begin + klass = base_module.const_get(classname) + rescue NameError + klass = nil + end + unless klass + if lang + msg = "-l #{lang}: invalid language name (class #{base_module.name}::#{classname} not found)." + else + msg = "-c #{classname}: invalid class name." + end + raise CommandOptionError.new(msg) + end + return klass + end + + def get_enhancers(enhancer_names) + return [] unless enhancer_names + enhancers = [] + shortname = nil + begin + enhancer_names.split(/,/).each do |name| + shortname = name + enhancers << Erubis.const_get("#{shortname}Enhancer") + end + rescue NameError + raise CommandOptionError.new("#{shortname}: no such Enhancer (try '-h' to show all enhancers).") + end + return enhancers + end + + def load_datafiles(filenames, opts) + context = Erubis::Context.new + return context unless filenames + filenames.split(/,/).each do |filename| + filename.strip! + test(?f, filename) or raise CommandOptionError.new("#{filename}: file not found.") + if filename =~ /\.ya?ml$/ + if opts.unexpand + ydoc = YAML.load_file(filename) + else + ydoc = YAML.load(untabify(File.read(filename))) + end + ydoc.is_a?(Hash) or raise CommandOptionError.new("#{filename}: root object is not a mapping.") + intern_hash_keys(ydoc) if opts.intern + context.update(ydoc) + elsif filename =~ /\.rb$/ + str = File.read(filename) + context2 = Erubis::Context.new + _instance_eval(context2, str) + context.update(context2) + else + CommandOptionError.new("#{filename}: '*.yaml', '*.yml', or '*.rb' required.") + end + end + return context + end + + def _instance_eval(_context, _str) + _context.instance_eval(_str) + end + + def parse_context_data(context_str, opts) + if context_str[0] == ?{ + require 'yaml' + ydoc = YAML.load(context_str) + unless ydoc.is_a?(Hash) + raise CommandOptionError.new("-c: root object is not a mapping.") + end + intern_hash_keys(ydoc) if opts.intern + return ydoc + else + context = Erubis::Context.new + context.instance_eval(context_str, '-c') + return context + end + end + + def intern_hash_keys(obj, done={}) + return if done.key?(obj.__id__) + case obj + when Hash + done[obj.__id__] = obj + obj.keys.each do |key| + obj[key.intern] = obj.delete(key) if key.is_a?(String) + end + obj.values.each do |val| + intern_hash_keys(val, done) if val.is_a?(Hash) || val.is_a?(Array) + end + when Array + done[obj.__id__] = obj + obj.each do |val| + intern_hash_keys(val, done) if val.is_a?(Hash) || val.is_a?(Array) + end + end + end + + def check_syntax(filename, src) + require 'open3' + #command = (ENV['_'] || 'ruby') + ' -wc' # ENV['_'] stores command name + bin = ENV['_'] && File.basename(ENV['_']) =~ /^ruby/ ? ENV['_'] : 'ruby' + command = bin + ' -wc' + stdin, stdout, stderr = Open3.popen3(command) + stdin.write(src) + stdin.close + result = stdout.read() + stdout.close() + errmsg = stderr.read() + stderr.close() + return nil unless errmsg && !errmsg.empty? + errmsg =~ /\A-:(\d+): / + linenum, message = $1, $' + return "#{filename}:#{linenum}: #{message}" + end + + end + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/preprocessing.rb b/vendor/gems/erubis-2.6.5/lib/erubis/preprocessing.rb new file mode 100644 index 0000000..c9e9420 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/preprocessing.rb @@ -0,0 +1,58 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require 'cgi' + + +module Erubis + + + ## + ## for preprocessing + ## + class PreprocessingEruby < Erubis::Eruby + + def initialize(input, params={}) + params = params.dup + params[:pattern] ||= '\[% %\]' # use '[%= %]' instead of '<%= %>' + #params[:escape] = true # transport '[%= %]' and '[%== %]' + super + end + + def add_expr_escaped(src, code) + add_expr_literal(src, "_decode((#{code}))") + end + + end + + + ## + ## helper methods for preprocessing + ## + module PreprocessingHelper + + module_function + + def _p(arg) + return "<%=#{arg}%>" + end + + def _P(arg) + return "<%=h(#{arg})%>" + end + + alias _? _p + + def _decode(arg) + arg = arg.to_s + arg.gsub!(/%3C%25(?:=|%3D)(.*?)%25%3E/) { "<%=#{CGI.unescape($1)}%>" } + arg.gsub!(/<%=(.*?)%>/) { "<%=#{CGI.unescapeHTML($1)}%>" } + return arg + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/lib/erubis/tiny.rb b/vendor/gems/erubis-2.6.5/lib/erubis/tiny.rb new file mode 100644 index 0000000..ae039a4 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/lib/erubis/tiny.rb @@ -0,0 +1,144 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +module Erubis + + ## + ## tiny and the simplest implementation of eRuby + ## + ## ex. + ## eruby = TinyEruby.new(File.read('example.rhtml')) + ## print eruby.src # print ruby code + ## print eruby.result(binding()) # eval ruby code with Binding object + ## print eruby.evalute(context) # eval ruby code with context object + ## + class TinyEruby + + def initialize(input=nil) + @src = convert(input) if input + end + attr_reader :src + + EMBEDDED_PATTERN = /<%(=+|\#)?(.*?)-?%>/m + + def convert(input) + src = "_buf = '';" # preamble + pos = 0 + input.scan(EMBEDDED_PATTERN) do |indicator, code| + m = Regexp.last_match + text = input[pos...m.begin(0)] + pos = m.end(0) + #src << " _buf << '" << escape_text(text) << "';" + text.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << text << "';" unless text.empty? + if !indicator # <% %> + src << code << ";" + elsif indicator == '#' # <%# %> + src << ("\n" * code.count("\n")) + else # <%= %> + src << " _buf << (" << code << ").to_s;" + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + #src << " _buf << '" << escape_text(rest) << "';" + rest.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << rest << "';" unless rest.empty? + src << "\n_buf.to_s\n" # postamble + return src + end + + #def escape_text(text) + # return text.gsub!(/['\\]/, '\\\\\&') || text + #end + + def result(_binding=TOPLEVEL_BINDING) + eval @src, _binding + end + + def evaluate(_context=Object.new) + if _context.is_a?(Hash) + _obj = Object.new + _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end + _context = _obj + end + _context.instance_eval @src + end + + end + + + + module PI + end + + class PI::TinyEruby + + def initialize(input=nil, options={}) + @escape = options[:escape] || 'Erubis::XmlHelper.escape_xml' + @src = convert(input) if input + end + + attr_reader :src + + EMBEDDED_PATTERN = /(^[ \t]*)?<\?rb(\s.*?)\?>([ \t]*\r?\n)?|@(!+)?\{(.*?)\}@/m + + def convert(input) + src = "_buf = '';" # preamble + pos = 0 + input.scan(EMBEDDED_PATTERN) do |lspace, stmt, rspace, indicator, expr| + match = Regexp.last_match + len = match.begin(0) - pos + text = input[pos, len] + pos = match.end(0) + #src << " _buf << '" << escape_text(text) << "';" + text.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << text << "';" unless text.empty? + if stmt # + if lspace && rspace + src << "#{lspace}#{stmt}#{rspace}" + else + src << " _buf << '" << lspace << "';" if lspace + src << stmt << ";" + src << " _buf << '" << rspace << "';" if rspace + end + else # ${...}, $!{...} + if !indicator + src << " _buf << " << @escape << "(" << expr << ");" + elsif indicator == '!' + src << " _buf << (" << expr << ").to_s;" + end + end + end + #rest = $' || input # ruby1.8 + rest = pos == 0 ? input : input[pos..-1] # ruby1.9 + #src << " _buf << '" << escape_text(rest) << "';" + rest.gsub!(/['\\]/, '\\\\\&') + src << " _buf << '" << rest << "';" unless rest.empty? + src << "\n_buf.to_s\n" # postamble + return src + end + + #def escape_text(text) + # return text.gsub!(/['\\]/, '\\\\\&') || text + #end + + def result(_binding=TOPLEVEL_BINDING) + eval @src, _binding + end + + def evaluate(_context=Object.new) + if _context.is_a?(Hash) + _obj = Object.new + _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end + _context = _obj + end + _context.instance_eval @src + end + + end + + +end diff --git a/vendor/gems/erubis-2.6.5/setup.rb b/vendor/gems/erubis-2.6.5/setup.rb new file mode 100644 index 0000000..f1c9d9a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/setup.rb @@ -0,0 +1,1331 @@ +# +# setup.rb +# +# Copyright (c) 2000-2004 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU Lesser General Public License version 2.1. +# + +# +# For backward compatibility +# + +unless Enumerable.method_defined?(:map) + module Enumerable + alias map collect + end +end + +unless Enumerable.method_defined?(:detect) + module Enumerable + alias detect find + end +end + +unless Enumerable.method_defined?(:select) + module Enumerable + alias select find_all + end +end + +unless Enumerable.method_defined?(:reject) + module Enumerable + def reject + result = [] + each do |i| + result.push i unless yield(i) + end + result + end + end +end + +unless Enumerable.method_defined?(:inject) + module Enumerable + def inject(result) + each do |i| + result = yield(result, i) + end + result + end + end +end + +unless Enumerable.method_defined?(:any?) + module Enumerable + def any? + each do |i| + return true if yield(i) + end + false + end + end +end + +unless File.respond_to?(:read) + def File.read(fname) + open(fname) {|f| + return f.read + } + end +end + +# +# Application independent utilities +# + +def File.binread(fname) + open(fname, 'rb') {|f| + return f.read + } +end + +# for corrupted windows stat(2) +def File.dir?(path) + File.directory?((path[-1,1] == '/') ? path : path + '/') +end + +# +# Config +# + +if arg = ARGV.detect{|arg| /\A--rbconfig=/ =~ arg } + ARGV.delete(arg) + require arg.split(/=/, 2)[1] + $".push 'rbconfig.rb' +else + require 'rbconfig' +end + +def multipackage_install? + FileTest.directory?(File.dirname($0) + '/packages') +end + + +class ConfigTable + + c = ::Config::CONFIG + + rubypath = c['bindir'] + '/' + c['ruby_install_name'] + + major = c['MAJOR'].to_i + minor = c['MINOR'].to_i + teeny = c['TEENY'].to_i + version = "#{major}.#{minor}" + + # ruby ver. >= 1.4.4? + newpath_p = ((major >= 2) or + ((major == 1) and + ((minor >= 5) or + ((minor == 4) and (teeny >= 4))))) + + subprefix = lambda {|path| + path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix') + } + + if c['rubylibdir'] + # V < 1.6.3 + stdruby = subprefix.call(c['rubylibdir']) + siteruby = subprefix.call(c['sitedir']) + versite = subprefix.call(c['sitelibdir']) + sodir = subprefix.call(c['sitearchdir']) + elsif newpath_p + # 1.4.4 <= V <= 1.6.3 + stdruby = "$prefix/lib/ruby/#{version}" + siteruby = subprefix.call(c['sitedir']) + versite = siteruby + '/' + version + sodir = "$site-ruby/#{c['arch']}" + else + # V < 1.4.4 + stdruby = "$prefix/lib/ruby/#{version}" + siteruby = "$prefix/lib/ruby/#{version}/site_ruby" + versite = siteruby + sodir = "$site-ruby/#{c['arch']}" + end + + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } + makeprog = arg.sub(/'/, '').split(/=/, 2)[1] + else + makeprog = 'make' + end + + common_descripters = [ + [ 'prefix', [ c['prefix'], + 'path', + 'path prefix of target environment' ] ], + [ 'std-ruby', [ stdruby, + 'path', + 'the directory for standard ruby libraries' ] ], + [ 'site-ruby-common', [ siteruby, + 'path', + 'the directory for version-independent non-standard ruby libraries' ] ], + [ 'site-ruby', [ versite, + 'path', + 'the directory for non-standard ruby libraries' ] ], + [ 'bin-dir', [ '$prefix/bin', + 'path', + 'the directory for commands' ] ], + [ 'rb-dir', [ '$site-ruby', + 'path', + 'the directory for ruby scripts' ] ], + [ 'so-dir', [ sodir, + 'path', + 'the directory for ruby extentions' ] ], + [ 'data-dir', [ '$prefix/share', + 'path', + 'the directory for shared data' ] ], + [ 'ruby-path', [ rubypath, + 'path', + 'path to set to #! line' ] ], + [ 'ruby-prog', [ rubypath, + 'name', + 'the ruby program using for installation' ] ], + [ 'make-prog', [ makeprog, + 'name', + 'the make program to compile ruby extentions' ] ], + [ 'without-ext', [ 'no', + 'yes/no', + 'does not compile/install ruby extentions' ] ] + ] + multipackage_descripters = [ + [ 'with', [ '', + 'name,name...', + 'package names that you want to install', + 'ALL' ] ], + [ 'without', [ '', + 'name,name...', + 'package names that you do not want to install', + 'NONE' ] ] + ] + if multipackage_install? + DESCRIPTER = common_descripters + multipackage_descripters + else + DESCRIPTER = common_descripters + end + + SAVE_FILE = 'config.save' + + def ConfigTable.each_name(&block) + keys().each(&block) + end + + def ConfigTable.keys + DESCRIPTER.map {|name, *dummy| name } + end + + def ConfigTable.each_definition(&block) + DESCRIPTER.each(&block) + end + + def ConfigTable.get_entry(name) + name, ent = DESCRIPTER.assoc(name) + ent + end + + def ConfigTable.get_entry!(name) + get_entry(name) or raise ArgumentError, "no such config: #{name}" + end + + def ConfigTable.add_entry(name, vals) + ConfigTable::DESCRIPTER.push [name,vals] + end + + def ConfigTable.remove_entry(name) + get_entry(name) or raise ArgumentError, "no such config: #{name}" + DESCRIPTER.delete_if {|n, arr| n == name } + end + + def ConfigTable.config_key?(name) + get_entry(name) ? true : false + end + + def ConfigTable.bool_config?(name) + ent = get_entry(name) or return false + ent[1] == 'yes/no' + end + + def ConfigTable.value_config?(name) + ent = get_entry(name) or return false + ent[1] != 'yes/no' + end + + def ConfigTable.path_config?(name) + ent = get_entry(name) or return false + ent[1] == 'path' + end + + + class << self + alias newobj new + end + + def ConfigTable.new + c = newobj() + c.initialize_from_table + c + end + + def ConfigTable.load + c = newobj() + c.initialize_from_file + c + end + + def initialize_from_table + @table = {} + DESCRIPTER.each do |k, (default, vname, desc, default2)| + @table[k] = default + end + end + + def initialize_from_file + raise InstallError, "#{File.basename $0} config first"\ + unless File.file?(SAVE_FILE) + @table = {} + File.foreach(SAVE_FILE) do |line| + k, v = line.split(/=/, 2) + @table[k] = v.strip + end + end + + def save + File.open(SAVE_FILE, 'w') {|f| + @table.each do |k, v| + f.printf "%s=%s\n", k, v if v + end + } + end + + def []=(k, v) + raise InstallError, "unknown config option #{k}"\ + unless ConfigTable.config_key?(k) + @table[k] = v + end + + def [](key) + return nil unless @table[key] + @table[key].gsub(%r<\$([^/]+)>) { self[$1] } + end + + def set_raw(key, val) + @table[key] = val + end + + def get_raw(key) + @table[key] + end + +end + + +module MetaConfigAPI + + def eval_file_ifexist(fname) + instance_eval File.read(fname), fname, 1 if File.file?(fname) + end + + def config_names + ConfigTable.keys + end + + def config?(name) + ConfigTable.config_key?(name) + end + + def bool_config?(name) + ConfigTable.bool_config?(name) + end + + def value_config?(name) + ConfigTable.value_config?(name) + end + + def path_config?(name) + ConfigTable.path_config?(name) + end + + def add_config(name, argname, default, desc) + ConfigTable.add_entry name,[default,argname,desc] + end + + def add_path_config(name, default, desc) + add_config name, 'path', default, desc + end + + def add_bool_config(name, default, desc) + add_config name, 'yes/no', default ? 'yes' : 'no', desc + end + + def set_config_default(name, default) + if bool_config?(name) + ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no') + else + ConfigTable.get_entry!(name)[0] = default + end + end + + def remove_config(name) + ent = ConfigTable.get_entry(name) + ConfigTable.remove_entry name + ent + end + +end + +# +# File Operations +# + +module FileOperations + + def mkdir_p(dirname, prefix = nil) + dirname = prefix + dirname if prefix + $stderr.puts "mkdir -p #{dirname}" if verbose? + return if no_harm? + + # does not check '/'... it's too abnormal case + dirs = dirname.split(%r<(?=/)>) + if /\A[a-z]:\z/i =~ dirs[0] + disk = dirs.shift + dirs[0] = disk + dirs[0] + end + dirs.each_index do |idx| + path = dirs[0..idx].join('') + Dir.mkdir path unless File.dir?(path) + end + end + + def rm_f(fname) + $stderr.puts "rm -f #{fname}" if verbose? + return if no_harm? + + if File.exist?(fname) or File.symlink?(fname) + File.chmod 0777, fname + File.unlink fname + end + end + + def rm_rf(dn) + $stderr.puts "rm -rf #{dn}" if verbose? + return if no_harm? + + Dir.chdir dn + Dir.foreach('.') do |fn| + next if fn == '.' + next if fn == '..' + if File.dir?(fn) + verbose_off { + rm_rf fn + } + else + verbose_off { + rm_f fn + } + end + end + Dir.chdir '..' + Dir.rmdir dn + end + + def move_file(src, dest) + File.unlink dest if File.exist?(dest) + begin + File.rename src, dest + rescue + File.open(dest, 'wb') {|f| f.write File.binread(src) } + File.chmod File.stat(src).mode, dest + File.unlink src + end + end + + def install(from, dest, mode, prefix = nil) + $stderr.puts "install #{from} #{dest}" if verbose? + return if no_harm? + + realdest = prefix + dest if prefix + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) + str = File.binread(from) + if diff?(str, realdest) + verbose_off { + rm_f realdest if File.exist?(realdest) + } + File.open(realdest, 'wb') {|f| + f.write str + } + File.chmod mode, realdest + + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| + if prefix + f.puts realdest.sub(prefix, '') + else + f.puts realdest + end + } + end + end + + def diff?(new_content, path) + return true unless File.exist?(path) + new_content != File.binread(path) + end + + def command(str) + $stderr.puts str if verbose? + system str or raise RuntimeError, "'system #{str}' failed" + end + + def ruby(str) + command config('ruby-prog') + ' ' + str + end + + def make(task = '') + command config('make-prog') + ' ' + task + end + + def extdir?(dir) + File.exist?(dir + '/MANIFEST') + end + + def all_files_in(dirname) + Dir.open(dirname) {|d| + return d.select {|ent| File.file?("#{dirname}/#{ent}") } + } + end + + REJECT_DIRS = %w( + CVS SCCS RCS CVS.adm + ) + + def all_dirs_in(dirname) + Dir.open(dirname) {|d| + return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS + } + end + +end + +# +# Main Installer +# + +class InstallError < StandardError; end + + +module HookUtils + + def run_hook(name) + try_run_hook "#{curr_srcdir()}/#{name}" or + try_run_hook "#{curr_srcdir()}/#{name}.rb" + end + + def try_run_hook(fname) + return false unless File.file?(fname) + begin + instance_eval File.read(fname), fname, 1 + rescue + raise InstallError, "hook #{fname} failed:\n" + $!.message + end + true + end + +end + + +module HookScriptAPI + + def get_config(key) + @config[key] + end + + alias config get_config + + def set_config(key, val) + @config[key] = val + end + + # + # srcdir/objdir (works only in the package directory) + # + + #abstract srcdir_root + #abstract objdir_root + #abstract relpath + + def curr_srcdir + "#{srcdir_root()}/#{relpath()}" + end + + def curr_objdir + "#{objdir_root()}/#{relpath()}" + end + + def srcfile(path) + "#{curr_srcdir()}/#{path}" + end + + def srcexist?(path) + File.exist?(srcfile(path)) + end + + def srcdirectory?(path) + File.dir?(srcfile(path)) + end + + def srcfile?(path) + File.file? srcfile(path) + end + + def srcentries(path = '.') + Dir.open("#{curr_srcdir()}/#{path}") {|d| + return d.to_a - %w(. ..) + } + end + + def srcfiles(path = '.') + srcentries(path).select {|fname| + File.file?(File.join(curr_srcdir(), path, fname)) + } + end + + def srcdirectories(path = '.') + srcentries(path).select {|fname| + File.dir?(File.join(curr_srcdir(), path, fname)) + } + end + +end + + +class ToplevelInstaller + + Version = '3.2.4' + Copyright = 'Copyright (c) 2000-2004 Minero Aoki' + + TASKS = [ + [ 'config', 'saves your configurations' ], + [ 'show', 'shows current configuration' ], + [ 'setup', 'compiles ruby extentions and others' ], + [ 'install', 'installs files' ], + [ 'clean', "does `make clean' for each extention" ], + [ 'distclean',"does `make distclean' for each extention" ] + ] + + def ToplevelInstaller.invoke + instance().invoke + end + + @singleton = nil + + def ToplevelInstaller.instance + @singleton ||= new(File.dirname($0)) + @singleton + end + + include MetaConfigAPI + + def initialize(ardir_root) + @config = nil + @options = { 'verbose' => true } + @ardir = File.expand_path(ardir_root) + end + + def inspect + "#<#{self.class} #{__id__()}>" + end + + def invoke + run_metaconfigs + task = parsearg_global() + @config = load_config(task) + __send__ "parsearg_#{task}" + init_installers + __send__ "exec_#{task}" + end + + def run_metaconfigs + eval_file_ifexist "#{@ardir}/metaconfig" + end + + def load_config(task) + case task + when 'config' + ConfigTable.new + when 'clean', 'distclean' + if File.exist?('config.save') + then ConfigTable.load + else ConfigTable.new + end + else + ConfigTable.load + end + end + + def init_installers + @installer = Installer.new(@config, @options, @ardir, File.expand_path('.')) + end + + # + # Hook Script API bases + # + + def srcdir_root + @ardir + end + + def objdir_root + '.' + end + + def relpath + '.' + end + + # + # Option Parsing + # + + def parsearg_global + valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/ + + while arg = ARGV.shift + case arg + when /\A\w+\z/ + raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg + return arg + + when '-q', '--quiet' + @options['verbose'] = false + + when '--verbose' + @options['verbose'] = true + + when '-h', '--help' + print_usage $stdout + exit 0 + + when '-v', '--version' + puts "#{File.basename($0)} version #{Version}" + exit 0 + + when '--copyright' + puts Copyright + exit 0 + + else + raise InstallError, "unknown global option '#{arg}'" + end + end + + raise InstallError, <" + out.puts " ruby #{File.basename $0} [] []" + + fmt = " %-20s %s\n" + out.puts + out.puts 'Global options:' + out.printf fmt, '-q,--quiet', 'suppress message outputs' + out.printf fmt, ' --verbose', 'output messages verbosely' + out.printf fmt, '-h,--help', 'print this message' + out.printf fmt, '-v,--version', 'print version and quit' + out.printf fmt, ' --copyright', 'print copyright and quit' + + out.puts + out.puts 'Tasks:' + TASKS.each do |name, desc| + out.printf " %-10s %s\n", name, desc + end + + out.puts + out.puts 'Options for config:' + ConfigTable.each_definition do |name, (default, arg, desc, default2)| + out.printf " %-20s %s [%s]\n", + '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg), + desc, + default2 || default + end + out.printf " %-20s %s [%s]\n", + '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's" + + out.puts + out.puts 'Options for install:' + out.printf " %-20s %s [%s]\n", + '--no-harm', 'only display what to do if given', 'off' + out.printf " %-20s %s [%s]\n", + '--prefix', 'install path prefix', '$prefix' + + out.puts + end + + # + # Task Handlers + # + + def exec_config + @installer.exec_config + @config.save # must be final + end + + def exec_setup + @installer.exec_setup + end + + def exec_install + @installer.exec_install + end + + def exec_show + ConfigTable.each_name do |k| + v = @config.get_raw(k) + if not v or v.empty? + v = '(not specified)' + end + printf "%-10s %s\n", k, v + end + end + + def exec_clean + @installer.exec_clean + end + + def exec_distclean + @installer.exec_distclean + end + +end + + +class ToplevelInstallerMulti < ToplevelInstaller + + include HookUtils + include HookScriptAPI + include FileOperations + + def initialize(ardir) + super + @packages = all_dirs_in("#{@ardir}/packages") + raise 'no package exists' if @packages.empty? + end + + def run_metaconfigs + eval_file_ifexist "#{@ardir}/metaconfig" + @packages.each do |name| + eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig" + end + end + + def init_installers + @installers = {} + @packages.each do |pack| + @installers[pack] = Installer.new(@config, @options, + "#{@ardir}/packages/#{pack}", + "packages/#{pack}") + end + + with = extract_selection(config('with')) + without = extract_selection(config('without')) + @selected = @installers.keys.select {|name| + (with.empty? or with.include?(name)) \ + and not without.include?(name) + } + end + + def extract_selection(list) + a = list.split(/,/) + a.each do |name| + raise InstallError, "no such package: #{name}" \ + unless @installers.key?(name) + end + a + end + + def print_usage(f) + super + f.puts 'Inluded packages:' + f.puts ' ' + @packages.sort.join(' ') + f.puts + end + + # + # multi-package metaconfig API + # + + attr_reader :packages + + def declare_packages(list) + raise 'package list is empty' if list.empty? + list.each do |name| + raise "directory packages/#{name} does not exist"\ + unless File.dir?("#{@ardir}/packages/#{name}") + end + @packages = list + end + + # + # Task Handlers + # + + def exec_config + run_hook 'pre-config' + each_selected_installers {|inst| inst.exec_config } + run_hook 'post-config' + @config.save # must be final + end + + def exec_setup + run_hook 'pre-setup' + each_selected_installers {|inst| inst.exec_setup } + run_hook 'post-setup' + end + + def exec_install + run_hook 'pre-install' + each_selected_installers {|inst| inst.exec_install } + run_hook 'post-install' + end + + def exec_clean + rm_f 'config.save' + run_hook 'pre-clean' + each_selected_installers {|inst| inst.exec_clean } + run_hook 'post-clean' + end + + def exec_distclean + rm_f 'config.save' + run_hook 'pre-distclean' + each_selected_installers {|inst| inst.exec_distclean } + run_hook 'post-distclean' + end + + # + # lib + # + + def each_selected_installers + Dir.mkdir 'packages' unless File.dir?('packages') + @selected.each do |pack| + $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose'] + Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") + Dir.chdir "packages/#{pack}" + yield @installers[pack] + Dir.chdir '../..' + end + end + + def verbose? + @options['verbose'] + end + + def no_harm? + @options['no-harm'] + end + +end + + +class Installer + + FILETYPES = %w( bin lib ext data ) + + include HookScriptAPI + include HookUtils + include FileOperations + + def initialize(config, opt, srcroot, objroot) + @config = config + @options = opt + @srcdir = File.expand_path(srcroot) + @objdir = File.expand_path(objroot) + @currdir = '.' + end + + def inspect + "#<#{self.class} #{File.basename(@srcdir)}>" + end + + # + # Hook Script API bases + # + + def srcdir_root + @srcdir + end + + def objdir_root + @objdir + end + + def relpath + @currdir + end + + # + # configs/options + # + + def no_harm? + @options['no-harm'] + end + + def verbose? + @options['verbose'] + end + + def verbose_off + begin + save, @options['verbose'] = @options['verbose'], false + yield + ensure + @options['verbose'] = save + end + end + + # + # TASK config + # + + def exec_config + exec_task_traverse 'config' + end + + def config_dir_bin(rel) + end + + def config_dir_lib(rel) + end + + def config_dir_ext(rel) + extconf if extdir?(curr_srcdir()) + end + + def extconf + opt = @options['config-opt'].join(' ') + command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}" + end + + def config_dir_data(rel) + end + + # + # TASK setup + # + + def exec_setup + exec_task_traverse 'setup' + end + + def setup_dir_bin(rel) + all_files_in(curr_srcdir()).each do |fname| + adjust_shebang "#{curr_srcdir()}/#{fname}" + end + end + + # modify: #!/usr/bin/ruby + # modify: #! /usr/bin/ruby + # modify: #!ruby + # not modify: #!/usr/bin/env ruby + SHEBANG_RE = /\A\#!\s*\S*ruby\S*/ + + def adjust_shebang(path) + return if no_harm? + + tmpfile = File.basename(path) + '.tmp' + begin + File.open(path, 'rb') {|r| + File.open(tmpfile, 'wb') {|w| + first = r.gets + return unless SHEBANG_RE =~ first + + $stderr.puts "adjusting shebang: #{File.basename path}" if verbose? + w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path')) + w.write r.read + } + } + move_file tmpfile, File.basename(path) + ensure + File.unlink tmpfile if File.exist?(tmpfile) + end + end + + def setup_dir_lib(rel) + end + + def setup_dir_ext(rel) + make if extdir?(curr_srcdir()) + end + + def setup_dir_data(rel) + end + + # + # TASK install + # + + def exec_install + exec_task_traverse 'install' + end + + def install_dir_bin(rel) + install_files collect_filenames_auto(), "#{config('bin-dir')}/#{rel}", 0755 + end + + def install_dir_lib(rel) + install_files ruby_scripts(), "#{config('rb-dir')}/#{rel}", 0644 + end + + def install_dir_ext(rel) + return unless extdir?(curr_srcdir()) + install_files ruby_extentions('.'), + "#{config('so-dir')}/#{File.dirname(rel)}", + 0555 + end + + def install_dir_data(rel) + install_files collect_filenames_auto(), "#{config('data-dir')}/#{rel}", 0644 + end + + def install_files(list, dest, mode) + mkdir_p dest, @options['install-prefix'] + list.each do |fname| + install fname, dest, mode, @options['install-prefix'] + end + end + + def ruby_scripts + collect_filenames_auto().select {|n| /\.rb\z/ =~ n } + end + + # picked up many entries from cvs-1.11.1/src/ignore.c + reject_patterns = %w( + core RCSLOG tags TAGS .make.state + .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb + *~ *.old *.bak *.BAK *.orig *.rej _$* *$ + + *.org *.in .* + ) + mapping = { + '.' => '\.', + '$' => '\$', + '#' => '\#', + '*' => '.*' + } + REJECT_PATTERNS = Regexp.new('\A(?:' + + reject_patterns.map {|pat| + pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] } + }.join('|') + + ')\z') + + def collect_filenames_auto + mapdir((existfiles() - hookfiles()).reject {|fname| + REJECT_PATTERNS =~ fname + }) + end + + def existfiles + all_files_in(curr_srcdir()) | all_files_in('.') + end + + def hookfiles + %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| + %w( config setup install clean ).map {|t| sprintf(fmt, t) } + }.flatten + end + + def mapdir(filelist) + filelist.map {|fname| + if File.exist?(fname) # objdir + fname + else # srcdir + File.join(curr_srcdir(), fname) + end + } + end + + def ruby_extentions(dir) + _ruby_extentions(dir) or + raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first" + end + + DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/ + + def _ruby_extentions(dir) + Dir.open(dir) {|d| + return d.select {|fname| DLEXT =~ fname } + } + end + + # + # TASK clean + # + + def exec_clean + exec_task_traverse 'clean' + rm_f 'config.save' + rm_f 'InstalledFiles' + end + + def clean_dir_bin(rel) + end + + def clean_dir_lib(rel) + end + + def clean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'clean' if File.file?('Makefile') + end + + def clean_dir_data(rel) + end + + # + # TASK distclean + # + + def exec_distclean + exec_task_traverse 'distclean' + rm_f 'config.save' + rm_f 'InstalledFiles' + end + + def distclean_dir_bin(rel) + end + + def distclean_dir_lib(rel) + end + + def distclean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'distclean' if File.file?('Makefile') + end + + # + # lib + # + + def exec_task_traverse(task) + run_hook "pre-#{task}" + FILETYPES.each do |type| + if config('without-ext') == 'yes' and type == 'ext' + $stderr.puts 'skipping ext/* by user option' if verbose? + next + end + traverse task, type, "#{task}_dir_#{type}" + end + run_hook "post-#{task}" + end + + def traverse(task, rel, mid) + dive_into(rel) { + run_hook "pre-#{task}" + __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') + all_dirs_in(curr_srcdir()).each do |d| + traverse task, "#{rel}/#{d}", mid + end + run_hook "post-#{task}" + } + end + + def dive_into(rel) + return unless File.dir?("#{@srcdir}/#{rel}") + + dir = File.basename(rel) + Dir.mkdir dir unless File.dir?(dir) + prevdir = Dir.pwd + Dir.chdir dir + $stderr.puts '---> ' + rel if verbose? + @currdir = rel + yield + Dir.chdir prevdir + $stderr.puts '<--- ' + rel if verbose? + @currdir = File.dirname(rel) + end + +end + + +if $0 == __FILE__ + begin + if multipackage_install? + ToplevelInstallerMulti.invoke + else + ToplevelInstaller.invoke + end + rescue + raise if $DEBUG + $stderr.puts $!.message + $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." + exit 1 + end +end diff --git a/vendor/gems/erubis-2.6.5/test/assert-text-equal.rb b/vendor/gems/erubis-2.6.5/test/assert-text-equal.rb new file mode 100644 index 0000000..b1d34f9 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/assert-text-equal.rb @@ -0,0 +1,44 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require 'test/unit' +require 'tempfile' + + +module Test + module Unit + class TestCase + + def assert_text_equal(expected, actual, message=nil, diffopt='-u', flag_cut=true) + if expected == actual + assert(true) + return + end + if expected[-1] != ?\n || actual[-1] != ?\n + expected += "\n" + actual += "\n" + end + begin + expfile = Tempfile.new(".expected.") + expfile.write(expected); expfile.flush() + actfile = Tempfile.new(".actual.") + actfile.write(actual); actfile.flush() + diff = `diff #{diffopt} #{expfile.path} #{actfile.path}` + ensure + expfile.close(true) if expfile + actfile.close(true) if actfile + end + # cut 1st & 2nd lines + message = (flag_cut ? diff.gsub(/\A.*\n.*\n/, '') : diff) unless message + #raise Test::Unit::AssertionFailedError.new(message) + assert_block(message) { false } # or assert(false, message) + end + + alias assert_equal_with_diff assert_text_equal # for compatibility + alias assert_text_equals assert_text_equal # for typo + + end + end +end diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/Example.ejava b/vendor/gems/erubis-2.6.5/test/data/users-guide/Example.ejava new file mode 100644 index 0000000..1fc2fe0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/Example.ejava @@ -0,0 +1,55 @@ +<% +import java.util.*; + +public class Example { + private String user; + private String[] list; + public example(String user, String[] list) { + this.user = user; + this.list = list; + } + + public String view() { + StringBuffer _buf = new StringBuffer(); +%> + + +

    Hello <%= user %>!

    + + + <% for (int i = 0; i < list.length; i++) { %> + "> + + + + <% } %> + +
    <%= i + 1 %><%== list[i] %>
    + + +<% + return _buf.toString(); + } + + public static void main(String[] args) { + String[] list = { "", "b&b", "\"ccc\"" }; + Example ex = Example.new("Erubis", list); + System.out.print(ex.view()); + } + + public static String escape(String s) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch (ch) { + case '<': sb.append("<"); break; + case '>': sb.append(">"); break; + case '&': sb.append("&"); break; + case '"': sb.append("""); break; + default: sb.append(ch); + } + } + return sb.toString(); + } +} +%> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/array_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/array_example.result new file mode 100644 index 0000000..ebd00f4 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/array_example.result @@ -0,0 +1,9 @@ +$ erubis -xE Array example.eruby +_buf = []; _buf << '
    +'; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +'; end + _buf << '
    +'; +_buf diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/arraybuffer_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/arraybuffer_example.result new file mode 100644 index 0000000..d2906db --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/arraybuffer_example.result @@ -0,0 +1,9 @@ +$ erubis -xE ArrayBuffer example.eruby +_buf = []; _buf << '
    +'; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +'; end + _buf << '
    +'; +_buf.join diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/bipattern-example.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/bipattern-example.rhtml new file mode 100644 index 0000000..a47fda8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/bipattern-example.rhtml @@ -0,0 +1,4 @@ +<% for item in list %> + [= item =] + [== item =] +<% end %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/bipattern_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/bipattern_example.result new file mode 100644 index 0000000..15159b5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/bipattern_example.result @@ -0,0 +1,6 @@ +$ erubis -xE BiPattern bipattern-example.rhtml +_buf = ''; for item in list + _buf << ' '; _buf << ( item ).to_s; _buf << ' + '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << ' +'; end +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/context.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/context.rb new file mode 100644 index 0000000..66a6663 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/context.rb @@ -0,0 +1,6 @@ +@title = 'Users List' +@users = [ + { 'name'=>'foo', 'mail'=>'foo@mail.com' }, + { 'name'=>'bar', 'mail'=>'bar@mail.net' }, + { 'name'=>'baz', 'mail'=>'baz@mail.org' }, +] diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/context.yaml b/vendor/gems/erubis-2.6.5/test/data/users-guide/context.yaml new file mode 100644 index 0000000..25f4e19 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/context.yaml @@ -0,0 +1,8 @@ +title: Users List +users: + - name: foo + mail: foo@mail.com + - name: bar + mail: bar@mail.net + - name: baz + mail: baz@mail.org diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/def_method.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/def_method.rb new file mode 100644 index 0000000..3b378da --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/def_method.rb @@ -0,0 +1,14 @@ +require 'erubis' +s = "hello <%= name %>" +eruby = Erubis::Eruby.new(s) +filename = 'hello.rhtml' + +## define instance method to Dummy class (or module) +class Dummy; end +eruby.def_method(Dummy, 'render(name)', filename) # filename is optional +p Dummy.new.render('world') #=> "hello world" + +## define singleton method to dummy object +obj = Object.new +eruby.def_method(obj, 'render(name)', filename) # filename is optional +p obj.render('world') #=> "hello world" diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/def_method.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/def_method.result new file mode 100644 index 0000000..f2a1b5b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/def_method.result @@ -0,0 +1,3 @@ +$ ruby def_method.rb +"hello world" +"hello world" diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/escape_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/escape_example.result new file mode 100644 index 0000000..95de2dc --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/escape_example.result @@ -0,0 +1,9 @@ +$ erubis -xE Escape example.eruby +_buf = ''; _buf << '
    +'; for item in list + _buf << '

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +

    '; _buf << ( item ).to_s; _buf << '

    +'; end + _buf << '
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ec b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ec new file mode 100644 index 0000000..a804f05 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ec @@ -0,0 +1,27 @@ +<% +#include + +int main(int argc, char *argv[]) +{ + int i; + +%> + + +

    Hello <%= "%s", argv[0] %>!

    + + + <% for (i = 1; i < argc; i++) { %> + "> + + + + <% } %> + +
    <%= "%d", i %><%= "%s", argv[i] %>
    + + +<% + return 0; +} +%> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ejs b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ejs new file mode 100644 index 0000000..44f2e3f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ejs @@ -0,0 +1,20 @@ +<% + var user = 'Erubis'; + var list = ['', 'b&b', '"ccc"']; + %> + + +

    Hello <%= user %>!

    + + + <% var i; %> + <% for (i = 0; i < list.length; i++) { %> + + + + + <% } %> + +
    <%= i + 1 %><%= list[i] %>
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example.eperl b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.eperl new file mode 100644 index 0000000..46f7508 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.eperl @@ -0,0 +1,18 @@ +<% + my $user = 'Erubis'; + my @list = ('', 'b&b', '"ccc"'); +%> + + +

    Hello <%= $user %>!

    + + <% $i = 0; %> + <% for $item (@list) { %> + "> + + + + <% } %> +
    <%= $i %><%= $item %>
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ephp b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ephp new file mode 100644 index 0000000..d92b46c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.ephp @@ -0,0 +1,18 @@ + + + +

    Hello <%= $user %>!

    + + + <% $i = 0; %> + <% foreach ($list as $item) { %> + <% $i++; %> + + + + + <% } %> + +
    <%= $i %><%== $item %>
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.eruby new file mode 100644 index 0000000..564c876 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.eruby @@ -0,0 +1,6 @@ +
    +<% for item in list %> +

    <%= item %>

    +

    <%== item %>

    +<% end %> +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example.escheme b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.escheme new file mode 100644 index 0000000..e2296ba --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example.escheme @@ -0,0 +1,28 @@ + + +<% +(let ((user "Erubis") + (items '("" "b&b" "\"ccc\"")) + (i 0)) + %> +

    Hello <%= user %>!

    + +<% + (for-each + (lambda (item) + (set! i (+ i 1)) + %> + "> + + + +<% + ) ; lambda end + items) ; for-each end + %> +
    <%= i %><%= item %>
    +<% +) ; let end +%> + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.eruby new file mode 100644 index 0000000..84bd1fd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.eruby @@ -0,0 +1,6 @@ +
      + <% for item in list %> +
    • <%= item %>
    • + <% end %> + <%# here is ignored because starting with '#' %> +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.rb new file mode 100644 index 0000000..8838206 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.rb @@ -0,0 +1,17 @@ +require 'erubis' +input = File.read('example1.eruby') +eruby = Erubis::Eruby.new(input) # create Eruby object + +puts "---------- script source ---" +puts eruby.src # print script source + +puts "---------- result ----------" +list = ['aaa', 'bbb', 'ccc'] +puts eruby.result(binding()) # get result +## or puts eruby.result(:list=>list) # or pass Hash instead of Binding + +## # or +## eruby = Erubis::Eruby.new +## input = File.read('example1.eruby') +## src = eruby.convert(input) +## eval src diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.result new file mode 100644 index 0000000..95ee6bb --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1.result @@ -0,0 +1,16 @@ +$ ruby example1.rb +---------- script source --- +_buf = ''; _buf << '
      +'; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • +'; end + + _buf << '
    +'; +_buf.to_s +---------- result ---------- +
      +
    • aaa
    • +
    • bbb
    • +
    • ccc
    • +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.rb new file mode 100644 index 0000000..b459cc0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.rb @@ -0,0 +1,4 @@ +require 'erubis' +input = File.read('example10.xhtml') +eruby = Erubis::PI::Eruby.new(input) +print eruby.src diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.result new file mode 100644 index 0000000..b080fa8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.result @@ -0,0 +1,17 @@ +$ ruby example10.rb +_buf = ''; _buf << ' +'; + lang = 'en' + list = ['', 'b&b', '"ccc"'] + + _buf << ' + +
      +'; for item in list + _buf << '
    • '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
    • +'; end + _buf << '
    + + +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.xhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.xhtml new file mode 100644 index 0000000..3ec00d5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10.xhtml @@ -0,0 +1,14 @@ + +', 'b&b', '"ccc"'] +?> + + +
      + +
    • @{item}@
    • + +
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example10_x.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10_x.result new file mode 100644 index 0000000..d19e078 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example10_x.result @@ -0,0 +1,17 @@ +$ erubis -x --pi example10.xhtml +_buf = ''; _buf << ' +'; + lang = 'en' + list = ['', 'b&b', '"ccc"'] + + _buf << ' + +
      +'; for item in list + _buf << '
    • '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
    • +'; end + _buf << '
    + + +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.php b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.php new file mode 100644 index 0000000..354ffc0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.php @@ -0,0 +1,20 @@ + + + +

    List

    + +

    not found.

    + + + + + + + + + + +
    + + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.result new file mode 100644 index 0000000..f69bb2d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.result @@ -0,0 +1,23 @@ +$ erubis -X example11.rhtml +_buf = ''; + + + + + + if @list.nil? || @list.empty? + + else + + + @list.each_with_index do |item, i| + _buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s; + _buf << ( item ).to_s; + + end + + + end + + +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.rhtml new file mode 100644 index 0000000..93d9326 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11.rhtml @@ -0,0 +1,21 @@ + + + + +

    List

    + <% if @list.nil? || @list.empty? %> +

    not found.

    + <% else %> + + + <% @list.each_with_index do |item, i| %> + + + + <% end %> + +
    <%= item %>
    + <% end %> + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_C.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_C.result new file mode 100644 index 0000000..a394dae --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_C.result @@ -0,0 +1,10 @@ +$ erubis -XC example11.rhtml +_buf = ''; + if @list.nil? || @list.empty? + else + @list.each_with_index do |item, i| + _buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s; + _buf << ( item ).to_s; + end + end +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_N.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_N.result new file mode 100644 index 0000000..ef0ad4a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_N.result @@ -0,0 +1,16 @@ +$ erubis -XNU example11.rhtml + 1: _buf = ''; + + 7: if @list.nil? || @list.empty? + + 9: else + + 12: @list.each_with_index do |item, i| + 13: _buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s; + 14: _buf << ( item ).to_s; + + 16: end + + 19: end + + 22: _buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_U.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_U.result new file mode 100644 index 0000000..2c89bbb --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_U.result @@ -0,0 +1,16 @@ +$ erubis -XU example11.rhtml +_buf = ''; + + if @list.nil? || @list.empty? + + else + + @list.each_with_index do |item, i| + _buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s; + _buf << ( item ).to_s; + + end + + end + +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_php.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_php.result new file mode 100644 index 0000000..65f62dd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example11_php.result @@ -0,0 +1,15 @@ +$ erubis -XNU -l php --pi=php --trim=false example11.php + + 5: + + 7: + + 10: + 11: + 12: + 13: + + 15: + + 18: + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example1_x.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1_x.result new file mode 100644 index 0000000..ab305c5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example1_x.result @@ -0,0 +1,9 @@ +$ erubis -x example1.eruby +_buf = ''; _buf << '
      +'; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • +'; end + + _buf << '
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.eruby new file mode 100644 index 0000000..a9ef194 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.eruby @@ -0,0 +1,7 @@ +
      + <% for item in list %> +
    • + <%= item %> +
    • + <% end %> +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.rb new file mode 100644 index 0000000..29b969b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.rb @@ -0,0 +1,10 @@ +require 'erubis' +input = File.read('example2.eruby') +eruby = Erubis::Eruby.new(input, :trim=>false) + +puts "----- script source ---" +puts eruby.src # print script source + +puts "----- result ----------" +list = ['aaa', 'bbb', 'ccc'] +puts eruby.result(binding()) # get result diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.result new file mode 100644 index 0000000..0a5b2d5 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2.result @@ -0,0 +1,27 @@ +$ ruby example2.rb +----- script source --- +_buf = ''; _buf << '
      +'; _buf << ' '; for item in list ; _buf << ' +'; _buf << '
    • + '; _buf << ( item ).to_s; _buf << ' +'; _buf << '
    • +'; _buf << ' '; end ; _buf << ' +'; _buf << '
    +'; +_buf.to_s +----- result ---------- +
      + +
    • + aaa +
    • + +
    • + bbb +
    • + +
    • + ccc +
    • + +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example2_trim.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2_trim.result new file mode 100644 index 0000000..1f4e6f0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2_trim.result @@ -0,0 +1,10 @@ +$ erubis -x --trim=false example2.eruby +_buf = ''; _buf << '
      +'; _buf << ' '; for item in list ; _buf << ' +'; _buf << '
    • + '; _buf << ( item ).to_s; _buf << ' +'; _buf << '
    • +'; _buf << ' '; end ; _buf << ' +'; _buf << '
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example2_x.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2_x.result new file mode 100644 index 0000000..81d0dcf --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example2_x.result @@ -0,0 +1,10 @@ +$ erubis -x example2.eruby +_buf = ''; _buf << '
      +'; for item in list + _buf << '
    • + '; _buf << ( item ).to_s; _buf << ' +'; _buf << '
    • +'; end + _buf << '
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example3.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example3.eruby new file mode 100644 index 0000000..9bb5e35 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example3.eruby @@ -0,0 +1,6 @@ +<% for item in list %> +

    <%= item %>

    +

    <%== item %>

    +

    <%=== item %>

    + +<% end %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example3.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example3.rb new file mode 100644 index 0000000..482b511 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example3.rb @@ -0,0 +1,10 @@ +require 'erubis' +input = File.read('example3.eruby') +eruby = Erubis::EscapedEruby.new(input) # or Erubis::XmlEruby + +puts "----- script source ---" +puts eruby.src # print script source + +puts "----- result ----------" +list = ['', 'b&b', '"ccc"'] +puts eruby.result(binding()) # get result diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example31.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example31.result new file mode 100644 index 0000000..9c37839 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example31.result @@ -0,0 +1,22 @@ +$ ruby example3.rb 2> stderr.log +----- script source --- +_buf = ''; for item in list + _buf << '

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +

    '; _buf << ( item ).to_s; _buf << '

    +

    '; $stderr.puts("*** debug: item=#{(item).inspect}"); _buf << '

    + +'; end +_buf.to_s +----- result ---------- +

    <aaa>

    +

    +

    + +

    b&b

    +

    b&b

    +

    + +

    "ccc"

    +

    "ccc"

    +

    + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example32.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example32.result new file mode 100644 index 0000000..692524a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example32.result @@ -0,0 +1,4 @@ +$ cat stderr.log +*** debug: item="" +*** debug: item="b&b" +*** debug: item="\"ccc\"" diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example3_e.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example3_e.result new file mode 100644 index 0000000..b5b45c2 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example3_e.result @@ -0,0 +1,8 @@ +$ erubis -l ruby -e example3.eruby +_buf = ''; for item in list + _buf << '

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +

    '; _buf << ( item ).to_s; _buf << '

    +

    '; $stderr.puts("*** debug: item=#{(item).inspect}"); _buf << '

    + +'; end +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.eruby new file mode 100644 index 0000000..3550f5a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.eruby @@ -0,0 +1,3 @@ + +

    + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.rb new file mode 100644 index 0000000..e8d0d8d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.rb @@ -0,0 +1,11 @@ +require 'erubis' +input = File.read('example4.eruby') +eruby = Erubis::Eruby.new(input, :pattern=>'') + # or '<(?:!--)?% %(?:--)?>' + +puts "---------- script source ---" +puts eruby.src # print script source + +puts "---------- result ----------" +list = ['aaa', 'bbb', 'ccc'] +puts eruby.result(binding()) # get result diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.result new file mode 100644 index 0000000..bcd1e2a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4.result @@ -0,0 +1,10 @@ +$ ruby example4.rb +---------- script source --- +_buf = ''; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +'; end +_buf.to_s +---------- result ---------- +

    aaa

    +

    bbb

    +

    ccc

    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example4_x.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4_x.result new file mode 100644 index 0000000..97edb2f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example4_x.result @@ -0,0 +1,5 @@ +$ erubis -x -p '' example4.eruby +_buf = ''; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +'; end +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.eruby new file mode 100644 index 0000000..e106fd9 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.eruby @@ -0,0 +1,6 @@ +<%= @val %> +
      + <% for item in @list %> +
    • <%= item %>
    • + <% end %> +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.rb new file mode 100644 index 0000000..2ad042e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.rb @@ -0,0 +1,16 @@ +require 'erubis' +input = File.read('example5.eruby') +eruby = Erubis::Eruby.new(input) # create Eruby object + +## create context object +## (key means var name, which may be string or symbol.) +context = { + :val => 'Erubis Example', + 'list' => ['aaa', 'bbb', 'ccc'], +} +## or +# context = Erubis::Context.new() +# context['val'] = 'Erubis Example' +# context[:list] = ['aaa', 'bbb', 'ccc'], + +puts eruby.evaluate(context) # get result diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.result new file mode 100644 index 0000000..836f6ce --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example5.result @@ -0,0 +1,7 @@ +$ ruby example5.rb +Erubis Example +
      +
    • aaa
    • +
    • bbb
    • +
    • ccc
    • +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example6.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example6.rb new file mode 100644 index 0000000..f80719f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example6.rb @@ -0,0 +1,12 @@ +class MyData + attr_accessor :val, :list +end + +## any object can be a context object +mydata = MyData.new +mydata.val = 'Erubis Example' +mydata.list = ['aaa', 'bbb', 'ccc'] + +require 'erubis' +eruby = Erubis::Eruby.new(File.read('example5.eruby')) +puts eruby.evaluate(mydata) diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example6.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example6.result new file mode 100644 index 0000000..f482d0b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example6.result @@ -0,0 +1,7 @@ +$ ruby example6.rb +Erubis Example +
      +
    • aaa
    • +
    • bbb
    • +
    • ccc
    • +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example7.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example7.eruby new file mode 100644 index 0000000..53f9ec8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example7.eruby @@ -0,0 +1,8 @@ +

    <%= @title %>

    +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example71.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example71.result new file mode 100644 index 0000000..ab555b1 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example71.result @@ -0,0 +1,13 @@ +$ erubis -f context.yaml example7.eruby +

    Users List

    + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example72.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example72.result new file mode 100644 index 0000000..dfcafd3 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example72.result @@ -0,0 +1,13 @@ +$ erubis -f context.rb example7.eruby +

    Users List

    + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example8.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example8.eruby new file mode 100644 index 0000000..5ea6da8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example8.eruby @@ -0,0 +1,6 @@ +

    <%= @title %>

    +
      +<% for item in @list %> +
    • <%= item %>
    • +<% end %> +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example8_ruby.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example8_ruby.result new file mode 100644 index 0000000..bdfd23e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example8_ruby.result @@ -0,0 +1,7 @@ +$ erubis -c '@title="Example"; @list=%w[AAA BBB CCC]' example8.eruby +

    Example

    +
      +
    • AAA
    • +
    • BBB
    • +
    • CCC
    • +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example8_yaml.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example8_yaml.result new file mode 100644 index 0000000..739e42b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example8_yaml.result @@ -0,0 +1,7 @@ +$ erubis -c '{title: Example, list: [AAA, BBB, CCC]}' example8.eruby +

    Example

    +
      +
    • AAA
    • +
    • BBB
    • +
    • CCC
    • +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.eruby new file mode 100644 index 0000000..0f2dc8f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.eruby @@ -0,0 +1,3 @@ +<% for item in @list %> + <%= item %> +<% end %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.rb new file mode 100644 index 0000000..bde1de6 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.rb @@ -0,0 +1,8 @@ +require 'erubis' +input = File.read('example9.eruby') +eruby1 = Erubis::Eruby.new(input) +eruby2 = Erubis::Eruby.new(input, :preamble=>false, :postamble=>false) + +puts eruby1.src # print preamble and postamble +puts "--------------" +puts eruby2.src # don't print preamble and postamble diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.result new file mode 100644 index 0000000..60e71e2 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example9.result @@ -0,0 +1,9 @@ +$ ruby example9.rb +_buf = ''; for item in @list + _buf << ' '; _buf << ( item ).to_s; _buf << ' +'; end +_buf.to_s +-------------- + for item in @list + _buf << ' '; _buf << ( item ).to_s; _buf << ' +'; end diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example91.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example91.result new file mode 100644 index 0000000..fde06a8 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example91.result @@ -0,0 +1,5 @@ +$ erubis -x example9.eruby +_buf = ''; for item in @list + _buf << ' '; _buf << ( item ).to_s; _buf << ' +'; end +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example92.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example92.result new file mode 100644 index 0000000..0cff68d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example92.result @@ -0,0 +1,4 @@ +$ erubis -x -b example9.eruby + for item in @list + _buf << ' '; _buf << ( item ).to_s; _buf << ' +'; end diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_c.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_c.result new file mode 100644 index 0000000..bd3239d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_c.result @@ -0,0 +1,29 @@ +$ erubis -l c example.ec +#line 1 "example.ec" + +#include + +int main(int argc, char *argv[]) +{ + int i; + + +fputs("\n" + " \n" + "

    Hello ", stdout); fprintf(stdout, "%s", argv[0]); fputs("!

    \n" + " \n" + " \n", stdout); + for (i = 1; i < argc; i++) { +fputs(" \n" + " \n" + " \n" + " \n", stdout); + } +fputs(" \n" + "
    ", stdout); fprintf(stdout, "%d", i); fputs("", stdout); fprintf(stdout, "%s", argv[i]); fputs("
    \n" + " \n" + "\n", stdout); + + return 0; +} + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_java.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_java.result new file mode 100644 index 0000000..70c10d2 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_java.result @@ -0,0 +1,56 @@ +$ erubis -b -l java example.ejava + +import java.util.*; + +public class Example { + private String user; + private String[] list; + public example(String user, String[] list) { + this.user = user; + this.list = list; + } + + public String view() { + StringBuffer _buf = new StringBuffer(); + +_buf.append("\n" + + " \n" + + "

    Hello "); _buf.append(user); _buf.append("!

    \n" + + " \n" + + " \n"); + for (int i = 0; i < list.length; i++) { +_buf.append(" \n" + + " \n" + + " \n" + + " \n"); + } +_buf.append(" \n" + + "
    "); _buf.append(i + 1); _buf.append(""); _buf.append(escape(list[i])); _buf.append("
    \n" + + " \n" + + "\n"); + + return _buf.toString(); + } + + public static void main(String[] args) { + String[] list = { "", "b&b", "\"ccc\"" }; + Example ex = Example.new("Erubis", list); + System.out.print(ex.view()); + } + + public static String escape(String s) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch (ch) { + case '<': sb.append("<"); break; + case '>': sb.append(">"); break; + case '&': sb.append("&"); break; + case '"': sb.append("""); break; + default: sb.append(ch); + } + } + return sb.toString(); + } +} + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_js.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_js.result new file mode 100644 index 0000000..f93f910 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_js.result @@ -0,0 +1,22 @@ +$ erubis -l js example.ejs +var _buf = []; + var user = 'Erubis'; + var list = ['', 'b&b', '"ccc"']; + +_buf.push("\n\ + \n\ +

    Hello "); _buf.push(user); _buf.push("!

    \n\ + \n\ + \n"); + var i; + for (i = 0; i < list.length; i++) { +_buf.push(" \n\ + \n\ + \n\ + \n"); + } +_buf.push(" \n\ +
    "); _buf.push(i + 1); _buf.push(""); _buf.push(list[i]); _buf.push("
    \n\ + \n\ +\n"); +document.write(_buf.join("")); diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_perl.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_perl.result new file mode 100644 index 0000000..3efbb73 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_perl.result @@ -0,0 +1,20 @@ +$ erubis -l perl example.eperl +use HTML::Entities; + my $user = 'Erubis'; + my @list = ('', 'b&b', '"ccc"'); + +print(' + +

    Hello '); print($user); print('!

    + +'); $i = 0; + for $item (@list) { +print(' + + + +'); } +print('
    '); print($i); print(''); print($item); print('
    + + +'); diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_php.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_php.result new file mode 100644 index 0000000..b9fa7d0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_php.result @@ -0,0 +1,19 @@ +$ erubis -l php example.ephp +<?xml version="1.0"?> + + +

    Hello !

    + + + + + + + + + + + +
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_scheme.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_scheme.result new file mode 100644 index 0000000..0bfb1e0 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_scheme.result @@ -0,0 +1,30 @@ +$ erubis -l scheme example.escheme +(let ((_buf '())) (define (_add x) (set! _buf (cons x _buf))) (_add " + \n") + +(let ((user "Erubis") + (items '("" "b&b" "\"ccc\"")) + (i 0)) + +(_add "

    Hello ")(_add user)(_add "!

    + \n") + + (for-each + (lambda (item) + (set! i (+ i 1)) + +(_add " + + + \n") + + ) ; lambda end + items) ; for-each end + +(_add "
    ")(_add i)(_add "")(_add item)(_add "
    \n") + +) ; let end + +(_add " +\n") + (reverse _buf)) diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/example_scheme_display.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_scheme_display.result new file mode 100644 index 0000000..1481e51 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/example_scheme_display.result @@ -0,0 +1,29 @@ +$ erubis -l scheme --func=display example.escheme +(display " + \n") + +(let ((user "Erubis") + (items '("" "b&b" "\"ccc\"")) + (i 0)) + +(display "

    Hello ")(display user)(display "!

    + \n") + + (for-each + (lambda (item) + (set! i (+ i 1)) + +(display " + + + \n") + + ) ; lambda end + items) ; for-each end + +(display "
    ")(display i)(display "")(display item)(display "
    \n") + +) ; let end + +(display " +\n") diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.rb new file mode 100644 index 0000000..e336147 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.rb @@ -0,0 +1,11 @@ +require 'erubis' +input = File.read('fasteruby.rhtml') +eruby = Erubis::FastEruby.new(input) # create Eruby object + +puts "---------- script source ---" +puts eruby.src + +puts "---------- result ----------" +context = { :title=>'Example', :list=>['aaa', 'bbb', 'ccc'] } +output = eruby.evaluate(context) +print output diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.result new file mode 100644 index 0000000..fa1cb58 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.result @@ -0,0 +1,38 @@ +$ ruby fasteruby.rb +---------- script source --- +_buf = ''; _buf << %Q` + +

    #{Erubis::XmlHelper.escape_xml( @title )}

    + \n` + i = 0 + for item in @list + i += 1 + _buf << %Q` + + + \n` + end + _buf << %Q`
    #{ i }#{Erubis::XmlHelper.escape_xml( item )}
    + +\n` +_buf.to_s +---------- result ---------- + + +

    Example

    + + + + + + + + + + + + + +
    1aaa
    2bbb
    3ccc
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.rhtml new file mode 100644 index 0000000..9c526c4 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/fasteruby.rhtml @@ -0,0 +1,15 @@ + + +

    <%== @title %>

    + +<% i = 0 %> +<% for item in @list %> +<% i += 1 %> + + + + +<% end %> +
    <%= i %><%== item %>
    + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example.eruby new file mode 100644 index 0000000..e4708bb --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example.eruby @@ -0,0 +1,9 @@ + +<% for item in items %> + <%= item %> +<% end %> + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example2.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example2.rb new file mode 100644 index 0000000..5247296 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example2.rb @@ -0,0 +1,8 @@ +require 'erubis' +class HeaderFooterEruby < Erubis::Eruby + include Erubis::HeaderFooterEnhancer +end + +input = File.read('headerfooter-example2.rhtml') +eruby = HeaderFooterEruby.new(input) +print eruby.src diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example2.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example2.rhtml new file mode 100644 index 0000000..520c037 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter-example2.rhtml @@ -0,0 +1,10 @@ + + + + : + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter_example.result new file mode 100644 index 0000000..58ab90d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter_example.result @@ -0,0 +1,11 @@ +$ erubis -xE HeaderFooter headerfooter-example.eruby + +def list_items(items) + +_buf = ''; for item in items + _buf << ' '; _buf << ( item ).to_s; _buf << ' +'; end +_buf.to_s + +end + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter_example2.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter_example2.result new file mode 100644 index 0000000..147fc54 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/headerfooter_example2.result @@ -0,0 +1,13 @@ +$ erubis -xE HeaderFooter headerfooter-example2.rhtml + +def page(list) + +_buf = ''; _buf << ' + +'; _buf << ' : +'; _buf << ' +'; +_buf.to_s + +end + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/interpolation_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/interpolation_example.result new file mode 100644 index 0000000..a96a685 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/interpolation_example.result @@ -0,0 +1,9 @@ +$ erubis -xE DeleteIndent example.eruby +_buf = ''; _buf << '
    +'; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +'; end + _buf << '
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program1.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program1.rb new file mode 100644 index 0000000..dd4d349 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program1.rb @@ -0,0 +1,8 @@ +require 'erubis' +eruby = Erubis::Eruby.new(File.read('template1.rhtml')) +items = ['foo', 'bar', 'baz'] +x = 1 +## local variable 'x' and 'eruby' are passed to template as well as 'items'! +print eruby.result(binding()) +## local variable 'x' is changed unintendedly because it is changed in template! +puts "** debug: x=#{x.inspect}" #=> "baz" diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program1.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program1.result new file mode 100644 index 0000000..8e8c653 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program1.result @@ -0,0 +1,6 @@ +$ ruby main_program1.rb +item = foo +item = bar +item = baz +** debug: local variables=["eruby", "items", "x", "_buf"] +** debug: x="baz" diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program2.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program2.rb new file mode 100644 index 0000000..0d5883b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program2.rb @@ -0,0 +1,8 @@ +require 'erubis' +eruby = Erubis::Eruby.new(File.read('template2.rhtml')) +items = ['foo', 'bar', 'baz'] +x = 1 +## only 'items' are passed to template +print eruby.evaluate(:items=>items) +## local variable 'x' is not changed! +puts "** debug: x=#{x.inspect}" #=> 1 diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program2.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program2.result new file mode 100644 index 0000000..f95fa05 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/main_program2.result @@ -0,0 +1,6 @@ +$ ruby main_program2.rb +item = foo +item = bar +item = baz +** debug: local variables=["_context", "x", "_buf"] +** debug: x=1 diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode-example.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode-example.eruby new file mode 100644 index 0000000..f0ed27a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode-example.eruby @@ -0,0 +1,14 @@ +

    List

    +<% if !@list || @list.empty? %> +

    not found.

    +<% else %> + + + <% @list.each_with_index do |item, i| %> + + + + <% end %> + +
    <%= item %>
    +<% end %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode-php.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode-php.result new file mode 100644 index 0000000..f331243 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode-php.result @@ -0,0 +1,20 @@ +$ erubis -l php --pi=php -N -E NoCode --trim=false notext-example.php + 1: + 2: + 3:

    List

    + 4: + 5:

    not found.

    + 6: + 7: + 8: + 9: + 10: + 11: + 12: + 13: + 14: + 15: + 16:
    + 17: + 18: + 19: diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode_example.result new file mode 100644 index 0000000..c6c2601 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/nocode_example.result @@ -0,0 +1,15 @@ +$ erubis -xE NoCode notext-example.eruby +

    List

    + +

    not found.

    + + + + + + + + + +
    + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/normal-eruby-test.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/normal-eruby-test.eruby new file mode 100644 index 0000000..81bd711 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/normal-eruby-test.eruby @@ -0,0 +1,9 @@ +<% +def list_items(items) +%> +<% for item in items %> +
  • <%= item %>
  • +<% end %> +<% +end +%> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/normal_eruby_test.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/normal_eruby_test.result new file mode 100644 index 0000000..01016a7 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/normal_eruby_test.result @@ -0,0 +1,11 @@ +$ erubis -x normal-eruby-test.eruby +_buf = ''; +def list_items(items) + + for item in items + _buf << '
  • '; _buf << ( item ).to_s; _buf << '
  • +'; end + +end + +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-example.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-example.eruby new file mode 100644 index 0000000..f0ed27a --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-example.eruby @@ -0,0 +1,14 @@ +

    List

    +<% if !@list || @list.empty? %> +

    not found.

    +<% else %> + + + <% @list.each_with_index do |item, i| %> + + + + <% end %> + +
    <%= item %>
    +<% end %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-example.php b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-example.php new file mode 100644 index 0000000..c40cb91 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-example.php @@ -0,0 +1,19 @@ + + +

    List

    + +

    not found.

    + + + + + + + + + + +
    + + + diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-php.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-php.result new file mode 100644 index 0000000..249e62c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext-php.result @@ -0,0 +1,20 @@ +$ erubis -l php --pi=php -N -E NoText --trim=false notext-example.php + 1: + 2: + 3: + 4: + 5: + 6: + 7: + 8: + 9: + 10: + 11: + 12: + 13: + 14: + 15: + 16: + 17: + 18: + 19: diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/notext_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext_example.result new file mode 100644 index 0000000..dccbaca --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/notext_example.result @@ -0,0 +1,16 @@ +$ erubis -xE NoText notext-example.eruby +_buf = ''; + if !@list || @list.empty? + + else + + + @list.each_with_index do |item, i| + _buf << ( i%2 == 0 ? '#FFCCCC' : '#CCCCFF' ).to_s; + _buf << ( item ).to_s; + + end + + + end +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/percentline-example.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/percentline-example.rhtml new file mode 100644 index 0000000..38c0a48 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/percentline-example.rhtml @@ -0,0 +1,4 @@ +% for item in list + <%= item %> +% end +%% lines with '%%' diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/percentline_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/percentline_example.result new file mode 100644 index 0000000..34d5984 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/percentline_example.result @@ -0,0 +1,7 @@ +$ erubis -xE PercentLine percentline-example.rhtml +_buf = ''; for item in list + _buf << ' '; _buf << ( item ).to_s; _buf << ' +'; end + _buf << '% lines with \'%%\' +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/printenable_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/printenable_example.result new file mode 100644 index 0000000..69fb91c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/printenable_example.result @@ -0,0 +1,4 @@ +$ ruby printenabled-example.rb + aaa + bbb + ccc diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/printenabled-example.eruby b/vendor/gems/erubis-2.6.5/test/data/users-guide/printenabled-example.eruby new file mode 100644 index 0000000..84b345f --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/printenabled-example.eruby @@ -0,0 +1,3 @@ +<% for item in @list %> + <% print item %> +<% end %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/printenabled-example.rb b/vendor/gems/erubis-2.6.5/test/data/users-guide/printenabled-example.rb new file mode 100644 index 0000000..289964c --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/printenabled-example.rb @@ -0,0 +1,8 @@ +require 'erubis' +class PrintEnabledEruby < Erubis::Eruby + include Erubis::PrintEnabledEnhancer +end +input = File.read('printenabled-example.eruby') +eruby = PrintEnabledEruby.new(input) +list = ['aaa', 'bbb', 'ccc'] +print eruby.evaluate(:list=>list) diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/printstatement_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/printstatement_example.result new file mode 100644 index 0000000..49fcd81 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/printstatement_example.result @@ -0,0 +1,8 @@ +$ erubis -xE PrintOut example.eruby + print '
    +'; for item in list + print '

    '; print(( item ).to_s); print '

    +

    '; print Erubis::XmlHelper.escape_xml( item ); print '

    +'; end + print '
    +'; diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/simplify_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/simplify_example.result new file mode 100644 index 0000000..82022ce --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/simplify_example.result @@ -0,0 +1,9 @@ +$ erubis -xE Simplify example.eruby +_buf = ''; _buf << '
    +'; for item in list ; _buf << ' +

    '; _buf << ( item ).to_s; _buf << '

    +

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +'; end ; _buf << ' +
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/stderr.log b/vendor/gems/erubis-2.6.5/test/data/users-guide/stderr.log new file mode 100644 index 0000000..422f276 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/stderr.log @@ -0,0 +1,3 @@ +*** debug: item="" +*** debug: item="b&b" +*** debug: item="\"ccc\"" diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/stdout_exmple.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/stdout_exmple.result new file mode 100644 index 0000000..c5a714d --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/stdout_exmple.result @@ -0,0 +1,9 @@ +$ erubis -xE Stdout example.eruby +_buf = $stdout; _buf << '
    +'; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +'; end + _buf << '
    +'; +'' diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/stringbuffer_example.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/stringbuffer_example.result new file mode 100644 index 0000000..75e9894 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/stringbuffer_example.result @@ -0,0 +1,9 @@ +$ erubis -xE StringBuffer example.eruby +_buf = ''; _buf << '
    +'; for item in list + _buf << '

    '; _buf << ( item ).to_s; _buf << '

    +

    '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '

    +'; end + _buf << '
    +'; +_buf.to_s diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/tail_260.result b/vendor/gems/erubis-2.6.5/test/data/users-guide/tail_260.result new file mode 100644 index 0000000..7163bcd --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/tail_260.result @@ -0,0 +1,4 @@ +$ erubis -c '{var: "AAA\n"}' tailnewline.rhtml +
    +AAA +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/tailnewline.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/tailnewline.rhtml new file mode 100644 index 0000000..8674daa --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/tailnewline.rhtml @@ -0,0 +1,3 @@ +
    +<%= @var -%> +
    diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/template1.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/template1.rhtml new file mode 100644 index 0000000..2b88b6b --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/template1.rhtml @@ -0,0 +1,4 @@ +<% for x in items %> +item = <%= x %> +<% end %> +** debug: local variables=<%= local_variables().inspect() %> diff --git a/vendor/gems/erubis-2.6.5/test/data/users-guide/template2.rhtml b/vendor/gems/erubis-2.6.5/test/data/users-guide/template2.rhtml new file mode 100644 index 0000000..f5df553 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/data/users-guide/template2.rhtml @@ -0,0 +1,4 @@ +<% for x in @items %> +item = <%= x %> +<% end %> +** debug: local variables=<%= local_variables().inspect() %> diff --git a/vendor/gems/erubis-2.6.5/test/test-engines.rb b/vendor/gems/erubis-2.6.5/test/test-engines.rb new file mode 100644 index 0000000..14013cf --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/test-engines.rb @@ -0,0 +1,369 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require "#{File.dirname(__FILE__)}/test.rb" + +require 'erubis' +require 'erubis/engine/eruby' +require 'erubis/engine/ephp' +require 'erubis/engine/ec' +require 'erubis/engine/ejava' +require 'erubis/engine/escheme' +require 'erubis/engine/eperl' +require 'erubis/engine/ejavascript' + + +class EnginesTest < Test::Unit::TestCase + + #load_yaml_documents(__FILE__) + testdata_list = load_yaml_datafile(__FILE__) + define_testmethods(testdata_list) + + def _test() + klass = Erubis.const_get(@class) + engine = klass.new(@input, @options || {}) + actual = engine.src + assert_text_equal(@expected, actual) + end + + + self.post_definition() + +end + +__END__ +- name: ruby1 + lang: ruby + class: Eruby + options: + input: | + + + <% i = 0 + list.each_with_index do |item, i| %> + + + + + <% end %> + +
    <%= i+1 %><%== list %>
    + <%=== i+1 %> + expected: | + _buf = ''; _buf << ' + + '; i = 0 + list.each_with_index do |item, i| + _buf << ' + + + + '; end + _buf << ' +
    '; _buf << ( i+1 ).to_s; _buf << ''; _buf << Erubis::XmlHelper.escape_xml( list ); _buf << '
    + '; $stderr.puts("*** debug: i+1=#{(i+1).inspect}"); _buf << ' + '; + _buf.to_s +## +- name: php1 + lang: php + class: Ephp + options: + input: | + + + <% + $i = 0; + foreach ($list as $item) { + $i++; + %> + + + + + <% + } + %> + +
    <%= $i %><%== $item %>
    + <%=== $i %> + expected: | + + + + + + + + + +
    + +## +- name: c1 + lang: c + class: Ec + options: { :filename: foo.html, :indent: ' ' } + input: |4 + + + <% for (i = 0; i < list; i++) { %> + + + + + <% } %> + +
    <%= "%d", i %><%== list[i] %>
    + <%=== "%d", i %> + expected: | + #line 1 "foo.html" + fputs("\n" + " \n", stdout); + for (i = 0; i < list; i++) { + fputs(" \n" + " \n" + " \n" + " \n", stdout); + } + fputs(" \n" + "
    ", stdout); fprintf(stdout, "%d", i); fputs("", stdout); escape(list[i], stdout); fputs("
    \n", stdout); + fprintf(stderr, "*** debug: i=" "%d", i); fputs("\n", stdout); +## +- name: java1 + lang: java + class: Ejava + options: { :buf: _buf, :bufclass: StringBuilder, :indent: ' ' } + input: | + + + <% + int i = 0; + for (Iterator it = list.iterator(); it.hasNext(); ) { + String s = (String)it.next(); + i++; + %> + "> + + + + <% + } + %> + +
    <%= i %><%== s %>
    + <%=== i %> + expected: |4 + StringBuilder _buf = new StringBuilder(); _buf.append("\n" + + " \n"); + + int i = 0; + for (Iterator it = list.iterator(); it.hasNext(); ) { + String s = (String)it.next(); + i++; + + _buf.append(" \n" + + " \n" + + " \n" + + " \n"); + + } + + _buf.append(" \n" + + "
    "); _buf.append(i); _buf.append(""); _buf.append(escape(s)); _buf.append("
    \n"); + System.err.println("*** debug: i="+(i)); _buf.append("\n"); + return _buf.toString(); +## +- name: scheme1 + lang: scheme + class: Escheme + options: + input: &scheme1_input| + <% (let ((i 0)) %> + + + <% + (for-each + (lambda (item) + (set! i (+ i 1)) + %> + + + + + <% + ); lambda end + list); for-each end + %> + +
    <%= i %><%== item %>
    + <%=== i %> + <% ); let end %> + expected: |4 + (let ((_buf '())) (define (_add x) (set! _buf (cons x _buf))) (let ((i 0)) + (_add " + \n") + + (for-each + (lambda (item) + (set! i (+ i 1)) + + (_add " + + + \n") + + ); lambda end + list); for-each end + + (_add " +
    ")(_add i)(_add "")(_add (escape item))(_add "
    \n") + (display "*** debug: i=")(display i)(display "\n")(_add "\n") + ); let end + (reverse _buf)) + +## +- name: scheme2 + lang: scheme + class: Escheme + options: { :func: 'display' } + input: *scheme1_input + expected: |4 + (let ((i 0)) + (display " + \n") + + (for-each + (lambda (item) + (set! i (+ i 1)) + + (display " + + + \n") + + ); lambda end + list); for-each end + + (display " +
    ")(display i)(display "")(display (escape item))(display "
    \n") + (display "*** debug: i=")(display i)(display "\n")(display "\n") + ); let end +## +- name: perl1 + lang: perl + class: Eperl + options: + input: | + <% + my $user = 'Erubis'; + my @list = ('', 'b&b', '"ccc"'); + %> +

    Hello <%= $user %>!

    + + + <% $i = 0; %> + <% for $item (@list) { %> + "> + + + + <% } %> + +
    <%= $i %><%== $item %>
    + <%=== $i %> + expected: |4 + use HTML::Entities; + my $user = 'Erubis'; + my @list = ('', 'b&b', '"ccc"'); + + print('

    Hello '); print($user); print('!

    + + + '); $i = 0; + for $item (@list) { + print(' + + + + '); } + print(' +
    '); print($i); print(''); print(encode_entities($item)); print('
    + '); print('*** debug: $i=', $i, "\n");print(' + '); +## +- name: javascript1 + lang: javascript + class: Ejavascript + options: + input: &javascript_input | + <% + var user = 'Erubis'; + var list = ['', 'b&b', '"ccc"']; + %> +

    Hello <%= user %>!

    + + + <% var i; %> + <% for (i = 0; i < list.length; i++) { %> + "> + + + + <% } %> + +
    <%= i %><%= list[i] %>
    + <%=== i %> + expected: |4 + var _buf = []; + var user = 'Erubis'; + var list = ['', 'b&b', '"ccc"']; + + _buf.push("

    Hello "); _buf.push(user); _buf.push("!

    \n\ + \n\ + \n"); + var i; + for (i = 0; i < list.length; i++) { + _buf.push(" \n\ + \n\ + \n\ + \n"); + } + _buf.push(" \n\ +
    "); _buf.push(i); _buf.push(""); _buf.push(list[i]); _buf.push("
    \n"); + alert("*** debug: i="+(i)); _buf.push("\n"); + document.write(_buf.join("")); + ## +- name: javascript2 + lang: javascript + class: Ejavascript + options: { :docwrite: false } + input: *javascript_input + expected: |4 + var _buf = []; + var user = 'Erubis'; + var list = ['', 'b&b', '"ccc"']; + + _buf.push("

    Hello "); _buf.push(user); _buf.push("!

    \n\ + \n\ + \n"); + var i; + for (i = 0; i < list.length; i++) { + _buf.push(" \n\ + \n\ + \n\ + \n"); + } + _buf.push(" \n\ +
    "); _buf.push(i); _buf.push(""); _buf.push(list[i]); _buf.push("
    \n"); + alert("*** debug: i="+(i)); _buf.push("\n"); + _buf.join(""); + ## diff --git a/vendor/gems/erubis-2.6.5/test/test-enhancers.rb b/vendor/gems/erubis-2.6.5/test/test-enhancers.rb new file mode 100644 index 0000000..cd69e42 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/test-enhancers.rb @@ -0,0 +1,570 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require "#{File.dirname(__FILE__)}/test.rb" + +require 'stringio' + +require 'erubis' +require 'erubis/engine/enhanced' +require 'erubis/engine/optimized' + + +class EnhancersTest < Test::Unit::TestCase + + testdata_list = load_yaml_datafile(__FILE__) + define_testmethods(testdata_list) + + + def _test() + @src.gsub!(/\^/, ' ') + @output.gsub!(/\^/, ' ') if @output.is_a?(String) + if @class + k = Erubis + @class.split('::').each do |name| k = k.const_get(name) end + @klass = k + else + @klass = Erubis::Eruby + end + @options ||= {} + @chomp.each do |target| + case target + when 'src' ; @src.chomp! + when 'input' ; @input.chomp! + when 'expected' ; @expected.chomp! + else + raise "#{@name}: invalid chomp value: #{@chomp.inspect}" + end + end if @chomp + + if @testopt == 'load_file' + filename = "tmp.#{@name}.eruby" + begin + File.open(filename, 'w') { |f| f.write(@input) } + eruby = @klass.load_file(filename, @options) + ensure + cachename = filename + '.cache' + File.unlink(cachename) if test(?f, cachename) + File.unlink(filename) if test(?f, filename) + end + else + #if @klass == Erubis::TinyEruby + # eruby = @klass.new(@input) + #else + eruby = @klass.new(@input, @options) + #end + end + assert_text_equal(@src, eruby.src) + + return if @testopt == 'skip_output' + + list = ['', 'b&b', '"ccc"'] + context = @testopt == 'context' ? Erubis::Context.new : {} + context[:list] = list + + case @testopt + when /\Aeval\(/ + eval eruby.src + actual = eval @testopt + assert_text_equal(@output, actual) + when 'stdout', 'print' + begin + orig = $stdout + $stdout = stringio = StringIO.new + #actual = eruby.evaluate(context) + actual = eruby.result(context) + ensure + $stdout = orig + end + if @testopt == 'stdout' + assert_equal("", actual) + else + assert_nil(actual) + end + assert_text_equal(@output, stringio.string) + when 'evaluate', 'context' + actual = eruby.evaluate(context) + assert_text_equal(@output, actual) + when 'binding' + actual = eruby.result(binding()) + assert_text_equal(@output, actual) + else + actual = eruby.result(context) + assert_text_equal(@output, actual) + end + end + + + self.post_definition() + +end + +__END__ + +## +- name: basic1 + class: Eruby + input: &basic1_input| +
      + <% for item in list %> +
    • <%= item %>
    • + <% end %> +
    + src: &basic1_src| + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: &basic1_output| +
      +
    • +
    • b&b
    • +
    • "ccc"
    • +
    + +- name: xml1 + class: XmlEruby + input: | +
    +       <% for item in list %>
    +        <%= item %>
    +        <%== item %>
    +       <% end %>
    +      
    + src: | + _buf = ''; _buf << '
    +      ';  for item in list 
    +       _buf << '  '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
    +      '; _buf << '  '; _buf << ( item ).to_s; _buf << '
    +      ';  end 
    +       _buf << '
    + '; + _buf.to_s + output: | +
    +        <aaa>
    +        
    +        b&b
    +        b&b
    +        "ccc"
    +        "ccc"
    +      
    + +## +- name: xml2 + class: XmlEruby + testopt: skip_output + input: | + <% for item in list %> + <%= item["var#{n}"] %> + <%== item["var#{n}"] %> + <%=== item["var#{n}"] %> + <%==== item["var#{n}"] %> + <% end %> + src: | + _buf = ''; for item in list + _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item["var#{n}"] ); _buf << ' + '; _buf << ' '; _buf << ( item["var#{n}"] ).to_s; _buf << ' + '; _buf << ' '; $stderr.puts("*** debug: item[\"var\#{n}\"]=#{(item["var#{n}"]).inspect}"); _buf << ' + '; _buf << ' '; _buf << ' + '; end + _buf.to_s + output: | + +## +- name: printout1 + class: PrintOutEruby + testopt: print + input: *basic1_input + src: |4 + print '
      + '; for item in list + print '
    • '; print(( item ).to_s); print '
    • + '; end + print '
    + '; + output: *basic1_output + +## +- name: printenabled1 + class: PrintEnabledEruby + input: &printenabled1_input| +
      + <% for item in list %> +
    • <% print item %>
    • + <% end %> +
    + src: | + @_buf = _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; print item ; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output +#
      +#
    • +#
    • b&b
    • +#
    • "ccc"
    • +#
    + +## +- name: stdout1 + class: StdoutEruby + testopt: stdout + input: *basic1_input +#
      +# <% for item in list %> +#
    • <%= item %>
    • +# <% end %> +#
    + src: | + _buf = $stdout; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + '' + output: *basic1_output +#
      +#
    • +#
    • b&b
    • +#
    • "ccc"
    • +#
    + +## +- name: array1 + class: ArrayEruby + input: | +
      + <% for item in list %> +
    • <%= item %>
    • + <% end %> +
    + src: | + _buf = []; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf + output: + - "
      \n" + - "
    • " + - "" + - "
    • \n" + - "
    • " + - "b&b" + - "
    • \n" + - "
    • " + - "\"ccc\"" + - "
    • \n" + - "
    \n" + +## +- name: arraybuffer1 + class: ArrayBufferEruby + input: *basic1_input + src: | + _buf = []; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.join + output: *basic1_output + +- name: stringbuffer1 + class: StringBufferEruby + input: *basic1_input +#
      +# <% for item in list %> +#
    • <%= item %>
    • +# <% end %> +#
    + src: | + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output +#
      +#
    • +#
    • b&b
    • +#
    • "ccc"
    • +#
    + +## +- name: erbout1 + class: ErboutEruby + input: *basic1_input + src: | + _erbout = _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output + +## +- name: stringio1 + class: StringIOEruby + input: *basic1_input + src: | + _buf = StringIO.new; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.string + output: *basic1_output + +## +- name: notext1 + class: NoTextEruby + input: *basic1_input + src: | + _buf = ''; + for item in list + _buf << ( item ).to_s; + end + + _buf.to_s + output: 'b&b"ccc"' + + +## +- name: nocode1 + class: NoCodeEruby + testopt: skip_output + input: *basic1_input + src: | +
      + +
    • + +
    + output: + +## +- name: simplified + class: SimplifiedEruby + input: | +
      + <% for item in list %> +
    • + <%= item %> +
    • + <% end %> +
    + src: | + _buf = ''; _buf << '
      + '; for item in list ; _buf << ' +
    • + '; _buf << ( item ).to_s; _buf << ' +
    • + '; end ; _buf << ' +
    + '; + _buf.to_s + output: | +
      + ^ +
    • + +
    • + ^ +
    • + b&b +
    • + ^ +
    • + "ccc" +
    • + ^ +
    + +## +- name: bipattern1 + class: BiPatternEruby + #options: { :bipattern : '\[= =\]' } + input: | + <% for item in list %> + <%= item %> % <%== item %> + [= item =] = [== item =] + <% end %> + src: | + _buf = ''; for item in list + _buf << ' '; _buf << ( item ).to_s; _buf << ' % '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << ' + '; _buf << ' '; _buf << ( item ).to_s; _buf << ' = '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << ' + '; end + _buf.to_s + output: |4 + % <aaa> + = <aaa> + b&b % b&b + b&b = b&b + "ccc" % "ccc" + "ccc" = "ccc" + +## +- name: bipattern2 + class: BiPatternEruby + options: { :bipattern: '\$\{ \}' } + input: | + <% for item in list %> + <%=item%> % <%==item%> + ${item} = ${=item} + <% end %> + src: | + _buf = ''; for item in list + _buf << ' '; _buf << (item).to_s; _buf << ' % '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << ' + '; _buf << ' '; _buf << (item).to_s; _buf << ' = '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << ' + '; end + _buf.to_s + output: |4 + % <aaa> + = <aaa> + b&b % b&b + b&b = b&b + "ccc" % "ccc" + "ccc" = "ccc" + +## +- name: percentline1 + class: PercentLineEruby + options: + input: | + + % for item in list + + + + + % end +
    <%= item %><%== item %>
    +
    +      %% double percent
    +       % spaced percent
    +      
    + src: | + _buf = ''; _buf << ' + '; for item in list + _buf << ' + + + + '; end + _buf << '
    '; _buf << ( item ).to_s; _buf << ''; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
    +
    +      % double percent
    +       % spaced percent
    +      
    + '; + _buf.to_s + output: | + + + + + + + + + + + + + +
    <aaa>
    b&bb&b
    "ccc""ccc"
    +
    +      % double percent
    +       % spaced percent
    +      
    + +## +- name: headerfooter1 + class: HeaderFooterEruby + options: + testopt: eval('ordered_list(list)') + input: | + +
      + <% for item in list %> +
    1. <%==item%>
    2. + <% end %> +
    + + src: |4 + + def ordered_list(list) + + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    1. '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
    2. + '; end + _buf << '
    + '; + _buf.to_s + end + output: | +
      +
    1. <aaa>
    2. +
    3. b&b
    4. +
    5. "ccc"
    6. +
    + +## +- name: deleteindent1 + class: DeleteIndentEruby + options: + testopt: + input: *basic1_input + src: | + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: | +
      +
    • +
    • b&b
    • +
    • "ccc"
    • +
    + +## +- name: interpolation1 + class: InterpolationEruby + options: + testopt: + input: *basic1_input + src: | + _buf = ''; _buf << %Q`
      \n` + for item in list + _buf << %Q`
    • #{ item }
    • \n` + end + _buf << %Q`
    \n` + _buf.to_s + output: *basic1_output + + diff --git a/vendor/gems/erubis-2.6.5/test/test-erubis.rb b/vendor/gems/erubis-2.6.5/test/test-erubis.rb new file mode 100644 index 0000000..7f869dc --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/test-erubis.rb @@ -0,0 +1,883 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + +require "#{File.dirname(__FILE__)}/test.rb" + +require 'stringio' + +require 'erubis' +require 'erubis/engine/enhanced' +require 'erubis/engine/optimized' +require 'erubis/tiny' + + +class ErubisTest < Test::Unit::TestCase + + testdata_list = load_yaml_datafile(__FILE__) + define_testmethods(testdata_list) + + + def _test() + @src.gsub!(/\^/, ' ') + @output.gsub!(/\^/, ' ') if @output.is_a?(String) + if @class + k = Erubis + @class.split('::').each do |name| k = k.const_get(name) end + @klass = k + else + @klass = Erubis::Eruby + end + @options ||= {} + @chomp.each do |target| + case target + when 'src' ; @src.chomp! + when 'input' ; @input.chomp! + when 'expected' ; @expected.chomp! + else + raise "#{@name}: invalid chomp value: #{@chomp.inspect}" + end + end if @chomp + + if @testopt == 'load_file' + filename = "tmp.#{@name}.eruby" + begin + File.open(filename, 'w') { |f| f.write(@input) } + eruby = @klass.load_file(filename, @options) + ensure + cachename = filename + '.cache' + File.unlink(cachename) if test(?f, cachename) + File.unlink(filename) if test(?f, filename) + end + else + if @klass == Erubis::TinyEruby + eruby = @klass.new(@input) + else + eruby = @klass.new(@input, @options) + end + end + assert_text_equal(@src, eruby.src) + + return if @testopt == 'skip_output' + + list = ['', 'b&b', '"ccc"'] + context = @testopt == 'context' ? Erubis::Context.new : {} + context[:list] = list + + case @testopt + when /\Aeval\(/ + eval eruby.src + actual = eval @testopt + assert_text_equal(@output, actual) + when 'stdout', 'print' + begin + orig = $stdout + $stdout = stringio = StringIO.new + #actual = eruby.evaluate(context) + actual = eruby.result(context) + ensure + $stdout = orig + end + if @testopt == 'stdout' + assert_equal("", actual) + else + assert_nil(actual) + end + assert_text_equal(@output, stringio.string) + when 'evaluate', 'context' + actual = eruby.evaluate(context) + assert_text_equal(@output, actual) + when 'binding' + actual = eruby.result(binding()) + assert_text_equal(@output, actual) + else + actual = eruby.result(context) + assert_text_equal(@output, actual) + end + end + + + def test_load_file_cache1 + @input = < +<% for item in @list %> +
  • <%= item %>
  • +<% end %> + +END + @src = < +'; for item in @list + _buf << '
  • '; _buf << ( item ).to_s; _buf << '
  • +'; end + _buf << ' +'; +_buf.to_s +END + @klass = Erubis::Eruby + filename = 'tmp.load_file_timestamp1' + cachename = filename + '.cache' + begin + File.open(filename, 'w') { |f| f.write(@input) } + assert_block() { !test(?f, cachename) } + engine = @klass.load_file(filename) + assert_block() { test(?f, cachename) } + assert_block() { File.mtime(filename) <= File.mtime(cachename) } + assert_text_equal(@src, engine.src) + # + input2 = @input.gsub(/ul>/, 'ol>') + src2 = @src.gsub(/ul>/, 'ol>') + mtime = File.mtime(filename) + File.open(filename, 'w') { |f| f.write(input2) } + t1 = Time.now() + sleep(1) + t2 = Time.now() + File.utime(t1, t1, filename) + File.utime(t2, t2, cachename) + assert_block('cache should be newer') { File.mtime(filename) < File.mtime(cachename) } + engine = @klass.load_file(filename) + assert_block('cache should be newer') { File.mtime(filename) < File.mtime(cachename) } + assert_text_equal(@src, engine.src) + # + File.utime(t2, t2, filename) + File.utime(t1, t1, cachename) + assert_block('cache should be older') { File.mtime(filename) > File.mtime(cachename) } + engine = @klass.load_file(filename) + assert_block('cache should be newer') { File.mtime(filename) <= File.mtime(cachename) } + assert_text_equal(src2, engine.src) + ensure + File.unlink(cachename) if File.file?(cachename) + File.unlink(filename) if File.file?(filename) + end + end + + + class Dummy + end + + def _class_has_instance_method(klass, method) + return klass.instance_methods.collect{|m| m.to_s}.include?(method.to_s) + end + + def test_def_method1 + s = "<%for i in list%>i=<%=i%>\n<%end%>" + eruby = Erubis::Eruby.new(s) + assert(! _class_has_instance_method(Dummy, 'render')) + eruby.def_method(Dummy, 'render(list)', 'foo.rhtml') + assert(_class_has_instance_method(Dummy, 'render')) + actual = Dummy.new().render(%w[1 2 3]) + assert_equal("i=1\ni=2\ni=3\n", actual) + end + + def test_def_method2 + s = "<%for i in list%>i=<%=i%>\n<%end%>" + eruby = Erubis::Eruby.new(s) + assert(! (eruby.respond_to? :render)) + eruby.def_method(eruby, 'render(list)', 'foo.rhtml') + assert eruby.respond_to?(:render) + actual = eruby.render([1, 2, 3]) + assert_equal("i=1\ni=2\ni=3\n", actual) + assert(! _class_has_instance_method(eruby.class, 'render')) + end + + def test_evaluate_creates_proc + s = "hello <%= @name %>" + eruby = Erubis::Eruby.new(s) + assert_nil(eruby.instance_variable_get('@_proc')) + actual1 = eruby.evaluate(:name=>'world') + assert_not_nil(eruby.instance_variable_get('@_proc')) + assert_instance_of(Proc, eruby.instance_variable_get('@_proc')) + actual2 = eruby.evaluate(:name=>'world') + assert_equal(actual1, actual2) + # convert() must clear @_proc + eruby.convert(s) + assert_nil(eruby.instance_variable_get('@_proc')) + end + + #def test_toplevel_binding + # s = "locals = <%= local_variables().inspect %>\n<% x = 50 %>\n" + # eruby = Erubis::Eruby.new(s) + # _x = eval 'x', TOPLEVEL_BINDING + # _y = eval 'y', TOPLEVEL_BINDING + # actual = eruby.evaluate(:x=>_x, :y=>_y) + # _x = eval 'x', TOPLEVEL_BINDING + # _y = eval 'y', TOPLEVEL_BINDING + # puts "*** actual=#{actual.inspect}, x=#{_x.inspect}, y=#{_y.inspect}" + #end + + self.post_definition() + +end + +x = 10 +y = 20 + + +__END__ +- name: basic1 + input: &basic1_input| +
      + <% for item in list %> +
    • <%= item %>
    • + <% end %> +
    + src: &basic1_src| + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: &basic1_output| +
      +
    • +
    • b&b
    • +
    • "ccc"
    • +
    + +## +- name: basic2 + input: | +
      + <% i = 0 + for item in list + i += 1 + %> +
    • <%= item %>
    • + <% end %> +
    + src: | + _buf = ''; _buf << '
      + '; i = 0 + for item in list + i += 1 + ^^^ + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output +#
      +#
    • +#
    • b&b
    • +#
    • "ccc"
    • +#
    + +## +- name: basic3 + input: | +
      <% i = 0 + for item in list + i += 1 %>
    • <%= item %>
    • <% end %> +
    + src: | + _buf = ''; _buf << '
      '; i = 0 + for item in list + i += 1 ; _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • '; end ; _buf << ' + '; _buf << '
    + '; + _buf.to_s + output: | +
    • b&b
    • "ccc"
    • +
    + +## +- name: context1 + testopt: context + input: | +
      + <% for item in @list %> +
    • <%= item %>
    • + <% end %> +
    + src: | + _buf = ''; _buf << '
      + '; for item in @list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output + +## +- name: ignore1 + input: | +
      + <%# i = 0 %> + <% for item in list %> + <%# + i += 1 + color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' + %> +
    • <%#= i %> : <%= item %>
    • + <% end %> +
    + src: | + _buf = ''; _buf << '
      + '; + for item in list + + + + + _buf << '
    • ';; _buf << ' : '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: | +
      +
    • :
    • +
    • : b&b
    • +
    • : "ccc"
    • +
    + +## +- name: quotation1 + desc: single quotation and backslash + class: Eruby + input: "ation1_input| + a = "'" + b = "\"" + c = '\'' + src: | + _buf = ''; _buf << 'a = "\'" + b = "\\"" + c = \'\\\'\' + '; + _buf.to_s + output: *quotation1_input + +## +- name: minus1 + desc: '<%- -%>' + class: Eruby + input: | +
      + <%- for item in list -%> +
    • <%= item -%>
    • + <% end -%> +
    + src: *basic1_src + output: *basic1_output + +## +- name: pattern1 + options: + :pattern : '\[@ @\]' + input: | +
      + [@ for item in list @] +
    • [@= item @]
    • + [@ end @] +
    + src: | + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output +#
      +#
    • +#
    • b&b
    • +#
    • "ccc"
    • +#
    + +## +- name: pattern2 + options: + :pattern : '<(?:!--)?% %(?:--)?>' + input: | +
      + +
    • <%= item %>
    • + +
    + src: | + _buf = ''; _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: *basic1_output +#
      +#
    • +#
    • b&b
    • +#
    • "ccc"
    • +#
    + +## +- name: trim1 + options: + :trim : false + input: *basic1_input +#
      +# <% for item in list %> +#
    • <%= item %>
    • +# <% end %> +#
    + src: | + _buf = ''; _buf << '
      + '; _buf << ' '; for item in list ; _buf << ' + '; _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; _buf << ' '; end ; _buf << ' + '; _buf << '
    + '; + _buf.to_s + output: | +
      + ^ +
    • + ^ +
    • b&b
    • + ^ +
    • "ccc"
    • + ^ +
    + +## +- name: bodyonly1 + testopt: skip_output + options: { :preamble: no, :postamble: no } + input: *basic1_input + src: |4 + _buf << '
      + '; for item in list + _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + chomp: [src] + expected: null + +## +- name: loadfile1 + testopt: load_file + #input: | + #
      + # <% for item in list %> + #
    • <%= item %>
    • + # <% end %> + #
    + input: + "
      \r\n <% for item in list %>\r\n
    • <%= item %>
    • \r\n <% end %>\r\n
    \r\n" + #src: | + # _buf = ''; _buf << "
      \n" + # for item in list + # _buf << "
    • "; _buf << ( item ).to_s; _buf << "
    • \n" + # end + # _buf << "
    \n" + # _buf + src: + "_buf = ''; _buf << '
      \r\n'; for item in list \r\n _buf << '
    • '; _buf << ( item ).to_s; _buf << '
    • \r\n'; end \r\n _buf << '
    \r\n';\n_buf.to_s\n" + #output: | + #
      + #
    • + #
    • b&b
    • + #
    • "ccc"
    • + #
    + output: + "
      \n
    • \n
    • b&b
    • \n
    • \"ccc\"
    • \n
    \n" + # "
      \r\n
    • \r\n
    • b&b
    • \r\n
    • \"ccc\"
    • \r\n
    \r\n" + +## +- name: nomatch1 + desc: bug + input: &nomatch1| +
      +
    • foo
    • +
    + src: | + _buf = ''; _buf << '
      +
    • foo
    • +
    + '; + _buf.to_s + output: *nomatch1 + +## +- name: escape1 + options: { :escape: true } + input: | + <% str = '<>&"' %> + <%= str %> + <%== str %> + src: | + _buf = ''; str = '<>&"' + _buf << Erubis::XmlHelper.escape_xml( str ); _buf << ' + '; _buf << ( str ).to_s; _buf << ' + '; + _buf.to_s + output: | + <>&" + <>&" + +## +- name: tailch1 + options: + input: | +

    + <% str = '<>&"' %> + <%= str %> + <%= str =%> + <%= str -%> +

    + src: | + _buf = ''; _buf << '

    + '; str = '<>&"' + _buf << ' '; _buf << ( str ).to_s; _buf << ' + '; _buf << ' '; _buf << ( str ).to_s; _buf << ' '; _buf << ( str ).to_s; _buf << '

    + '; + _buf.to_s + output: | +

    + <>&" + <>&" <>&"

    + +## +- name: doublepercent1 + options: + input: | + <% x1 = 10 %> + <%% x2 = 20 %> + <%= x1 %> + <%%= x2 %> + src: | + _buf = ''; x1 = 10 + _buf << '<% x2 = 20 %> + '; _buf << ( x1 ).to_s; _buf << ' + '; _buf << '<%= x2 %> + '; + _buf.to_s + output: | + <% x2 = 20 %> + 10 + <%= x2 %> + +## +- name: optimized1 + class: OptimizedEruby + input: &optimized1_input| + + <% for item in list %> + + + + + <% end %> +
    <%= item %><%== item %>
    +
      <% for item in list %>
    • <%= item %>
    • <% end %>
    + src: | + _buf = ' + '; for item in list + _buf << ' + + + + '; end + _buf << '
    ' << ( item ).to_s << '' << Erubis::XmlHelper.escape_xml( item ) << '
    +
      '; for item in list ; _buf << '
    • ' << ( item ).to_s << '
    • '; end ; _buf << '
    + ' + _buf + output: | + + + + + + + + + + + + + +
    <aaa>
    b&bb&b
    "ccc""ccc"
    +
    • b&b
    • "ccc"
    + +## +- name: optimized2 + class: OptimizedXmlEruby + input: *optimized1_input +# +# <% for item in list %> +# +# +# +# +# <% end %> +#
    <%= item %><%== item %>
    +#
      <% for item in list %>
    • <%= item %>
    • <% end %>
    + src: | + _buf = ' + '; for item in list + _buf << ' + + + + '; end + _buf << '
    ' << Erubis::XmlHelper.escape_xml( item ) << '' << ( item ).to_s << '
    +
      '; for item in list ; _buf << '
    • ' << Erubis::XmlHelper.escape_xml( item ) << '
    • '; end ; _buf << '
    + ' + _buf + output: | + + + + + + + + + + + + + +
    <aaa>
    b&bb&b
    "ccc""ccc"
    +
    • <aaa>
    • b&b
    • "ccc"
    + +## +- name: optimized3 + desc: bug + class: OptimizedEruby + input: | + user = <%= "Foo" %> + <% for item in list %> + <%= item %> + <% end %> + src: | + _buf = 'user = '; _buf << ( "Foo" ).to_s << ' + '; for item in list + _buf << ' ' << ( item ).to_s << ' + '; end + + _buf + output: | + user = Foo + + b&b + "ccc" + +## +- name: optimized4 + desc: single quotation and backslash + class: OptimizedEruby + input: &optimized4_input| + a = "'" + b = "\"" + c = '\'' + src: | + _buf = 'a = "\'" + b = "\\"" + c = \'\\\'\' + '; + _buf + output: *optimized4_input + +## +- name: tiny1 + class: TinyEruby + testopt: binding + input: | +
      + <% for item in list %> +
    • <%= item %>
    • + <% end %> +
    + src: | + _buf = ''; _buf << '
      + '; for item in list ; _buf << ' +
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end ; _buf << ' +
    + '; + _buf.to_s + output: | +
      + ^ +
    • + ^ +
    • b&b
    • + ^ +
    • "ccc"
    • + ^ +
    + +## +- name: tiny2 + class: TinyEruby + testopt: evaluate + input: | +
      + <% for item in @list %> +
    • <%= item %>
    • + <% end %> +
    + src: | + _buf = ''; _buf << '
      + '; for item in @list ; _buf << ' +
    • '; _buf << ( item ).to_s; _buf << '
    • + '; end ; _buf << ' +
    + '; + _buf.to_s + output: | +
      + ^ +
    • + ^ +
    • b&b
    • + ^ +
    • "ccc"
    • + ^ +
    + +## +- name: pi1 + class: PI::Eruby + testopt: evaluate + input: &input_pi1| +
      + +
    • @{item}@ / @!{item}@
    • +
    • <%= item %> / <%== item %>
    • + +
    + src: &src_pi1| + _buf = ''; _buf << '
      + '; for item in @list + _buf << '
    • '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << ' / '; _buf << (item).to_s; _buf << '
    • +
    • '; _buf << ( item ).to_s; _buf << ' / '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: &output_pi1| +
      +
    • <aaa> /
    • +
    • / <aaa>
    • +
    • b&b / b&b
    • +
    • b&b / b&b
    • +
    • "ccc" / "ccc"
    • +
    • "ccc" / "ccc"
    • +
    + +## +- name: pi2 + class: PI::Eruby + options: { :escape: false } + testopt: evaluate + input: *input_pi1 + src: | + _buf = ''; _buf << '
      + '; for item in @list + _buf << '
    • '; _buf << (item).to_s; _buf << ' / '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
    • +
    • '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << ' / '; _buf << ( item ).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: | +
      +
    • / <aaa>
    • +
    • <aaa> /
    • +
    • b&b / b&b
    • +
    • b&b / b&b
    • +
    • "ccc" / "ccc"
    • +
    • "ccc" / "ccc"
    • +
    + +## +- name: pi3 + class: PI::Eruby + options: { :pi: hoge, :embchar: '$' } + testopt: evaluate + input: | +
      + +
    • ${item}$ / $!{item}$
    • +
    • <%= item %> / <%== item %>
    • + +
    + src: *src_pi1 + output: *output_pi1 + +- name: pi4 + class: PI::Eruby + testopt: evaluate + input: | + +
      + + + + +
    + + + src: |4 + + def show(list) + + _buf = ''; _buf << '
      + '; for item in list + _buf << ( item + ).to_s; end + + + + + _buf << '
    + '; + _buf.to_s + + end + show(@list) + + output: | +
      + b&b"ccc"
    + + +- name: pitiny1 + class: PI::TinyEruby + testopt: evaluate + input: | +
      + +
    • @{item}@ / @!{item}@
    • + +
    + src: | + _buf = ''; _buf << '
      + '; for item in @list + _buf << '
    • '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << ' / '; _buf << (item).to_s; _buf << '
    • + '; end + _buf << '
    + '; + _buf.to_s + output: | +
      +
    • <aaa> /
    • +
    • b&b / b&b
    • +
    • "ccc" / "ccc"
    • +
    + diff --git a/vendor/gems/erubis-2.6.5/test/test-main.rb b/vendor/gems/erubis-2.6.5/test/test-main.rb new file mode 100644 index 0000000..8c8e6df --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/test-main.rb @@ -0,0 +1,721 @@ +## +## $Rev$ +## $Release: 2.6.5 $ +## $Date$ +## + +require "#{File.dirname(__FILE__)}/test.rb" + +require 'tempfile' +require 'erubis/main' + + +$script = File.dirname(TESTDIR) + '/bin/erubis' +#if test(?f, 'bin/erubis') +# $script = 'bin/erubis' +#elsif test(?f, '../bin/erubis') +# $script = '../bin/erubis' +#end + + +class StringWriter < String + def write(arg) + self << arg + end + def flush(*args) + # pass + end +end + +class Erubis::Main + public :usage + public :show_properties + public :show_enhancers +end + + +class MainTest < Test::Unit::TestCase + + INPUT = <<'END' +list: +<% list = ['', 'b&b', '"ccc"'] + for item in list %> + - <%= item %> +<% end %> +user: <%= defined?(user) ? user : "(none)" %> +END + INPUT2 = INPUT.gsub(/\blist([^:])/, '@list\1').gsub(/\buser([^:])/, '@user\1') + +# SRC = <<'END' +#_buf = ''; _buf << "list:\n" +# list = ['', 'b&b', '"ccc"'] +# for item in list +#_buf << " - "; _buf << ( item ).to_s; _buf << "\n" +# end +#_buf << "user: "; _buf << ( defined?(user) ? user : "(none)" ).to_s; _buf << "\n" +#_buf +#END + SRC = <<'END' +_buf = ''; _buf << 'list: +'; list = ['', 'b&b', '"ccc"'] + for item in list + _buf << ' - '; _buf << ( item ).to_s; _buf << ' +'; end + _buf << 'user: '; _buf << ( defined?(user) ? user : "(none)" ).to_s; _buf << ' +'; +_buf.to_s +END +# SRC2 = SRC.gsub(/\blist /, '@list ').gsub(/\buser /, '@user ') + + OUTPUT = <<'END' +list: + - + - b&b + - "ccc" +user: (none) +END + + ESCAPED_OUTPUT = <<'END' +list: + - <aaa> + - b&b + - "ccc" +user: (none) +END + + + PI_INPUT = <<'END' +
      + ', 'b&b', '"ccc"'] + for item in @list ?> +
    • @{item}@ / @!{item}@ + <%= item %> / <%== item %>
    • + +
        +END + + PI_SRC = <<'END' +_buf = ''; _buf << '
          +'; @list = ['', 'b&b', '"ccc"'] + for item in @list + _buf << '
        • '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << ' / '; _buf << (item).to_s; _buf << ' + '; _buf << ( item ).to_s; _buf << ' / '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
        • +'; end + _buf << '
            +'; +_buf.to_s +END + + PI_ESCAPED_SRC = <<'END' +_buf = ''; _buf << '
              +'; @list = ['', 'b&b', '"ccc"'] + for item in @list + _buf << '
            • '; _buf << (item).to_s; _buf << ' / '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << ' + '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << ' / '; _buf << ( item ).to_s; _buf << '
            • +'; end + _buf << '
                +'; +_buf.to_s +END + + PI_OUTPUT = <<'END' +
                  +
                • <aaa> / + / <aaa>
                • +
                • b&b / b&b + b&b / b&b
                • +
                • "ccc" / "ccc" + "ccc" / "ccc"
                • +
                    +END + + PI_ESCAPED_OUTPUT = <<'END' +
                      +
                    • / <aaa> + <aaa> /
                    • +
                    • b&b / b&b + b&b / b&b
                    • +
                    • "ccc" / "ccc" + "ccc" / "ccc"
                    • +
                        +END + + def _test() + if @filename.nil? + method = (caller[0] =~ /in `(.*)'/) && $1 #' + method =~ /block in (.*)/ and method = $1 # for Ruby 1.9 + @filename = "tmp.#{method}" + end + File.open(@filename, 'w') {|f| f.write(@input) } if @filename + begin + argv = @options.is_a?(Array) ? @options.dup : @options.split + argv << @filename if @filename + $stdout = output = StringWriter.new + Erubis::Main.new.execute(argv) + ensure + $stdout = STDOUT + File.unlink(@filename) if @filename && test(?f, @filename) + end + assert_text_equal(@expected, output) + end + + def _error_test(errclass, errmsg) + ex = assert_raise(errclass) { _test() } + assert_equal(errmsg, ex.message) + end + + + def test_help # -h + @options = '-h' + m = Erubis::Main.new + @expected = m.usage() + "\n" + m.show_properties() + m.show_enhancers() + @filename = false + _test() + end + + def test_version # -v + @options = '-v' + @expected = (("$Release: 2.6.5 $" =~ /[.\d]+/) && $&) + "\n" + @filename = false + _test() + end + + + def test_basic1 + @input = INPUT + @expected = OUTPUT + @options = '' + _test() + end + + + def test_source1 # -x + @input = INPUT + @expected = SRC + @options = '-x' + _test() + end + + + def _with_dummy_file + bindir = File.join(File.dirname(File.dirname(__FILE__)), 'bin') + env_path = ENV['PATH'] + env__ = ENV['_'] + begin + ENV['PATH'] = bindir + File::PATH_SEPARATOR + ENV['PATH'] + ENV['_'] = 'erubis' + Tempfile.open(self.name.gsub(/[^\w]/,'_')) do |f| + f.write(INPUT) + f.flush + yield(f.path) + end + ensure + ENV['PATH'] = env_path + ENV['_'] = env__ if env__ + end + end + + + def test_syntax1 # -z (syntax ok) + @input = INPUT + @expected = "Syntax OK\n" + @options = '-z' + _test() + # + _with_dummy_file do |filepath| + actual = `erubis #{@options} #{filepath}` + assert_equal @expected, actual + end + end + + + def test_syntax2 # -z (syntax error) + inputs = [] + inputs << <<'END' +
                          +<% for item in list %> +
                        • <%= item[:name]] %>
                        • +<% end %> +
                        +END + inputs << <<'END' +
                          +<% for item in list %> +
                        • <%= item[:name] %>
                        • +<% edn %> +
                        +END + basename = 'tmp.test_syntax2_%d.rhtml' + filenames = [ basename % 0, basename % 1 ] + errmsgs = [] + if ruby19? + errmsgs << <<'END' +3: syntax error, unexpected ']', expecting ')' + _buf << '
                      • '; _buf << ( item[:name]] ).to_s; _buf << '
                      • + ^ +-:4: syntax error, unexpected keyword_end, expecting ')' +'; end + ^ +-:7: syntax error, unexpected $end, expecting ')' +END + errmsgs << <<'END' +7: syntax error, unexpected $end, expecting keyword_end +END + else + errmsgs << <<'END' +3: syntax error, unexpected ']', expecting ')' + _buf << '
                      • '; _buf << ( item[:name]] ).to_s; _buf << '
                      • + ^ +-:4: syntax error, unexpected kEND, expecting ')' +'; end + ^ +-:7: syntax error, unexpected $end, expecting ')' +END + errmsgs << <<'END' +7: syntax error, unexpected $end, expecting kEND +END + end + # + max = inputs.length + (0...max).each do |i| + @input = inputs[i] + @expected = "tmp.test_syntax2:#{errmsgs[i]}" + @options = '-z' + _test() + end + # + begin + (0...max).each do |i| + File.open(filenames[i], 'w') {|f| f.write(inputs[i]) } + end + @input = '' + @expected = '' + @options = '-z' + (0...max).each do |i| + @expected << "#{filenames[i]}:#{errmsgs[i]}" + @options << " #{filenames[i]}" + end + _test() + ensure + (0...max).each do |i| + File.unlink(filenames[i]) if test(?f, filenames[i]) + end + end + end + + + def test_pattern1 # -p + @input = INPUT.gsub(/<%/, '') + @expected = OUTPUT + #@options = "-p ''" + @options = ["-p", ""] + _test() + end + + +# def test_class1 # -C +# @input = INPUT +# @expected = OUTPUT.gsub(//, '<aaa>').gsub(/b&b/, 'b&b').gsub(/"ccc"/, '"ccc"') +# @options = "-C XmlEruby" +# _test() +# end + + + def test_notrim1 # --trim=false + @input = INPUT + @expected = <<'END' +list: + + - + + - b&b + + - "ccc" + +user: (none) +END + @options = "--trim=false" # -T + _test() + end + + + def test_notrim2 # --trim=false + @input = INPUT +# @expected = <<'END' +#_buf = ''; _buf << "list:\n" +# list = ['', 'b&b', '"ccc"'] +# for item in list ; _buf << "\n" +#_buf << " - "; _buf << ( item ).to_s; _buf << "\n" +# end ; _buf << "\n" +#_buf << "user: "; _buf << ( defined?(user) ? user : "(none)" ).to_s; _buf << "\n" +#_buf +#END + @expected = <<'END' +_buf = ''; _buf << 'list: +'; list = ['', 'b&b', '"ccc"'] + for item in list ; _buf << ' +'; _buf << ' - '; _buf << ( item ).to_s; _buf << ' +'; end ; _buf << ' +'; _buf << 'user: '; _buf << ( defined?(user) ? user : "(none)" ).to_s; _buf << ' +'; +_buf.to_s +END + @options = "-x --trim=false" # -xT + _test() + end + + + #-- + #def test_context1 + # @input = INPUT + # @expected = OUTPUT.gsub(/\(none\)/, 'Hello') + # @options = '--user=Hello' + # _test() + #end + #++ + + + def test_datafile1 # -f data.yaml + datafile = "test.context1.yaml" + @input = INPUT2 + @expected = OUTPUT.gsub(/\(none\)/, 'Hello') + @options = "-f #{datafile}" + # + str = <<-END + user: Hello + password: world + END + File.open(datafile, 'w') {|f| f.write(str) } + begin + _test() + ensure + File.unlink(datafile) if test(?f, datafile) + end + end + + + def test_datafile2 # -f data.rb + datafile = "test.context1.rb" + @input = INPUT2 + @expected = OUTPUT.gsub(/\(none\)/, 'Hello') + @options = "-f #{datafile}" + # + str = <<-END + @user = 'Hello' + @password = 'world' + END + File.open(datafile, 'w') {|f| f.write(str) } + begin + _test() + ensure + File.unlink(datafile) if test(?f, datafile) + end + end + + + def test_untabify1 # -t (obsolete) + yamlfile = "test.context2.yaml" + @input = INPUT2 + @expected = OUTPUT.gsub(/\(none\)/, 'Hello') + @options = "-tf #{yamlfile}" + # + yaml = <<-END + user: Hello + password: world + END + File.open(yamlfile, 'w') {|f| f.write(yaml) } + begin + _test() + ensure + File.unlink(yamlfile) if test(?f, yamlfile) + end + end + + + def test_untabify2 # -T + yamlfile = "test.context2.yaml" + @input = INPUT2 + @expected = OUTPUT.gsub(/\(none\)/, 'Hello') + @options = "-Tf #{yamlfile}" + # + yaml = <<-END + user: Hello + items: + - aaa + - bbb + - ccc + END + File.open(yamlfile, 'w') {|f| f.write(yaml) } + assert_raise(ArgumentError) do + _test() + end + File.open(yamlfile, 'w') {|f| f.write(yaml.gsub(/\t/, ' '*8)) } + _test() + ensure + File.unlink(yamlfile) if test(?f, yamlfile) + end + + + def test_symbolify1 # -S + yamlfile = "test.context3.yaml" + @input = < + + <%= h[:name] %><%= h[:mail] %> + +<% end %> +END + @expected = < + foofoo@mail.com + + + barbar@mail.org + +END + @options = "-f #{yamlfile} -S" + # + yaml = <<-END +list: + - name: foo + mail: foo@mail.com + - name: bar + mail: bar@mail.org +END + File.open(yamlfile, 'w') { |f| f.write(yaml) } + begin + _test() + ensure + File.unlink(yamlfile) if test(?f, yamlfile) + end + end + + + def test_result1 # -B + yamlfile = "test.context4.yaml" + # + @input = <<'END' +user = <%= user %> +<% for item in list %> + - <%= item %> +<% end %> +END + @expected = <<'END' +user = World + - aaa + - bbb + - ccc +END + @options = "-f #{yamlfile} -B " + # + yaml = <<-END +user: World +list: + - aaa + - bbb + - ccc +END + File.open(yamlfile, 'w') {|f| f.write(yaml) } + begin + _test() + ensure + File.unlink(yamlfile) if test(?f, yamlfile) + end + end + + + def test_context1 # -c + @input = <<'END' +user = <%= @user %> +<% for item in @list %> + - <%= item %> +<% end %> +END + @expected = <<'END' +user = World + - aaa + - bbb + - ccc +END + # + @options = ['-c', '{user: World, list: [aaa, bbb, ccc]}'] + _test() + @options = ['-c', '@user="World"; @list=%w[aaa bbb ccc]'] + _test() + end + + + def test_include1 # -I + dir = 'foo' + lib = 'bar' + Dir.mkdir dir unless test(?d, dir) + filename = "#{dir}/#{lib}.rb" + File.open(filename, 'w') do |f| + f.write <<-'END' + def escape(str) + return "<#{str.upcase}>" + end + END + end + # + @input = "<% require '#{lib}' %>\n" + INPUT.gsub(/<%= item %>/, '<%= escape(item) %>') + @expected = OUTPUT.gsub(//, '<>').gsub(/b\&b/, '').gsub(/"ccc"/, '<"CCC">') + @options = "-I #{dir}" + # + begin + _test() + ensure + File.unlink filename if test(?f, filename) + Dir.rmdir dir if test(?d, dir) + end + end + + + def test_require1 # -r + dir = 'foo' + lib = 'bar' + Dir.mkdir dir unless test(?d, dir) + filename = "#{dir}/#{lib}.rb" + File.open(filename, 'w') do |f| + f.write <<-'END' + def escape(str) + return "<#{str.upcase}>" + end + END + end + # + @input = INPUT.gsub(/<%= item %>/, '<%= escape(item) %>') + @expected = OUTPUT.gsub(//, '<>').gsub(/b\&b/, '').gsub(/"ccc"/, '<"CCC">') + @options = "-I #{dir} -r #{lib}" + # + begin + _test() + ensure + File.unlink filename if test(?f, filename) + Dir.rmdir dir if test(?d, dir) + end + end + + + def test_enhancers1 # -E + @input = < b&b "ccc"] %> +% for item in list + - <%= item %> : <%== item %> + - [= item =] : [== item =] +% end +END + @expected = < + - <aaa> : + - b&b : b&b + - b&b : b&b + - "ccc" : "ccc" + - "ccc" : "ccc" +END + @options = "-E Escape,PercentLine,HeaderFooter,BiPattern" + _test() + end + + + def test_bodyonly1 # -b + @input = INPUT + @expected = SRC.sub(/\A_buf = '';/,'').sub(/\n_buf.to_s\n\z/,'') + @options = '-b -x' + _test() + end + + + def test_escape1 # -e + @input = INPUT + @expected = SRC.gsub(/<< \((.*?)\).to_s;/, '<< Erubis::XmlHelper.escape_xml(\1);') + @options = '-ex' + _test() + end + + + def test_invalid_option # -1 (invalid option) + @input = INPUT + @options = '-1' + _error_test(Erubis::CommandOptionError, "-1: unknown option.") + end + + + def test_invalid_enhancer # -E hoge + @options = '-E hoge' + errmsg = "hoge: no such Enhancer (try '-h' to show all enhancers)." + _error_test(Erubis::CommandOptionError, errmsg) + end + + + def test_invalid_lang # -l hoge + @options = '-l hoge' + errmsg = "-l hoge: invalid language name (class Erubis::Ehoge not found)." + _error_test(Erubis::CommandOptionError, errmsg) + end + + + def test_missing_argument # -E + @filename = false + @options = '-E' + _error_test(Erubis::CommandOptionError, "-E: enhancers required.") + @options = '-l' + _error_test(Erubis::CommandOptionError, "-l: lang required.") + end + + + def test_pi1 # --pi -x + @input = PI_INPUT + @expected = PI_SRC + @options = '-x --pi' + _test() + end + + def test_pi2 # --pi -x --escape=false + @input = PI_INPUT + @expected = PI_ESCAPED_SRC + @options = '-x --pi --escape=false' + _test() + end + + def test_pi3 # --pi + @input = PI_INPUT + @expected = PI_OUTPUT + @options = '--pi' + _test() + end + + def test_pi4 # --pi --escape=false + @input = PI_INPUT + @expected = PI_ESCAPED_OUTPUT + @options = '--pi --escape=false' + _test() + end + + def test_pi5 # --pi=ruby -x + @input = PI_INPUT.gsub(/<\?rb/, ' + - @{arr[i]}@ / @!{arr[i]}@ + +END + @expected = <<'END' +StringBuffer _buf = new StringBuffer(); for (int i = 0; i < arr.length; i++) { +_buf.append(" - "); _buf.append(escape(arr[i])); _buf.append(" / "); _buf.append(arr[i]); _buf.append("\n"); + } +return _buf.toString(); +END + @options = '--pi -xl java' + _test() + end + + + self.post_definition() + +end diff --git a/vendor/gems/erubis-2.6.5/test/test-users-guide.rb b/vendor/gems/erubis-2.6.5/test/test-users-guide.rb new file mode 100644 index 0000000..f420c78 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/test-users-guide.rb @@ -0,0 +1,57 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require "#{File.dirname(__FILE__)}/test.rb" + + +class KwarkUsersGuideTest < Test::Unit::TestCase + + DIR = File.expand_path(File.dirname(__FILE__) + '/data/users-guide') + CWD = Dir.pwd() + + + def setup + Dir.chdir DIR + end + + + def teardown + Dir.chdir CWD + end + + + def _test + @name = (caller()[0] =~ /`(.*?)'/) && $1 + s = File.read(@filename) + s =~ /\A\$ (.*?)\n/ + command = $1 + expected = $' + result = `#{command}` + assert_text_equal(expected, result) + end + + + Dir.chdir DIR do + filenames = [] + filenames += Dir.glob('*.result') + filenames += Dir.glob('*.source') + filenames.each do |filename| + name = filename.gsub(/[^\w]/, '_') + s = <<-END + def test_#{name} + # $stderr.puts "*** debug: test_#{name}" + @name = '#{name}' + @filename = '#{filename}' + _test() + end + END + eval s + end + end + + + self.post_definition() + +end diff --git a/vendor/gems/erubis-2.6.5/test/test.rb b/vendor/gems/erubis-2.6.5/test/test.rb new file mode 100644 index 0000000..7318c2e --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/test.rb @@ -0,0 +1,29 @@ +## +## $Release: 2.6.5 $ +## copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +## + + +unless defined?(TESTDIR) + TESTDIR = File.dirname(__FILE__) + LIBDIR = TESTDIR == '.' ? '../lib' : File.dirname(TESTDIR) + '/lib' + $: << TESTDIR + $: << LIBDIR +end + + +require 'test/unit' +#require 'test/unit/ui/console/testrunner' +require 'assert-text-equal' +require 'yaml' +require 'testutil' +require 'erubis' + + +if $0 == __FILE__ + require "#{TESTDIR}/test-erubis.rb" + require "#{TESTDIR}/test-engines.rb" + require "#{TESTDIR}/test-enhancers.rb" + require "#{TESTDIR}/test-main.rb" + require "#{TESTDIR}/test-users-guide.rb" +end diff --git a/vendor/gems/erubis-2.6.5/test/testutil.rb b/vendor/gems/erubis-2.6.5/test/testutil.rb new file mode 100644 index 0000000..4da2bc3 --- /dev/null +++ b/vendor/gems/erubis-2.6.5/test/testutil.rb @@ -0,0 +1,96 @@ +### +### $Release: 2.6.5 $ +### copyright(c) 2006-2009 kuwata-lab.com all rights reserved. +### + +require 'yaml' + +require 'test/unit/testcase' + + + +def ruby18? # :nodoc: + RUBY_VERSION =~ /\A1.8/ +end + +def ruby19? # :nodoc: + RUBY_VERSION =~ /\A1.9/ +end + + + +class Test::Unit::TestCase + + + def self.load_yaml_datafile(filename, options={}, &block) # :nodoc: + # read datafile + s = File.read(filename) + if filename =~ /\.rb$/ + s =~ /^__END__$/ or raise "*** error: __END__ is not found in '#{filename}'." + s = $' + end + # untabify + unless options[:tabify] == false + s = s.split(/^/).inject('') do |sb, line| + sb << line.gsub(/([^\t]{8})|([^\t]*)\t/n) { [$+].pack("A8") } + end + end + # load yaml document + testdata_list = [] + YAML.load_documents(s) do |ydoc| + if ydoc.is_a?(Hash) + testdata_list << ydoc + elsif ydoc.is_a?(Array) + ydoc.each do |hash| + raise "testdata should be a mapping." unless hash.is_a?(Hash) + testdata_list << hash + end + else + raise "testdata should be a mapping." + end + end + # data check + identkey = options[:identkey] || 'name' + table = {} + testdata_list.each do |hash| + ident = hash[identkey] + ident or raise "*** key '#{identkey}' is required but not found." + table[ident] and raise "*** #{identkey} '#{ident}' is duplicated." + table[ident] = hash + yield(hash) if block + end + # + return testdata_list + end + + + def self.define_testmethods(testdata_list, options={}, &block) + identkey = options[:identkey] || 'name' + testmethod = options[:testmethod] || '_test' + testdata_list.each do |hash| + yield(hash) if block + ident = hash[identkey] + s = "def test_#{ident}\n" + hash.each do |key, val| + s << " @#{key} = #{val.inspect}\n" + end + s << " #{testmethod}\n" + s << "end\n" + $stderr.puts "*** load_yaml_testdata(): eval_str=<<'END'\n#{s}END" if $DEBUG + self.module_eval s + end + end + + + def self.post_definition + if ENV['TEST'] + target = "test_#{ENV['TEST']}" + self.instance_methods.each do |method_name| + m = method_name.to_s + private m if m =~ /\Atest_/ && m != target + end + end + end + + +end diff --git a/vendor/plugins/asset_packager/CHANGELOG b/vendor/plugins/asset_packager/CHANGELOG new file mode 100644 index 0000000..40f1f27 --- /dev/null +++ b/vendor/plugins/asset_packager/CHANGELOG @@ -0,0 +1,122 @@ +------------------------------------------------------------------------ +r52 | sbecker | 2007-11-04 01:38:21 -0400 (Sun, 04 Nov 2007) | 3 lines + +* Allow configuration of which environments the helpers should merge scripts with the Synthesis::AssetPackage.merge_environments variable. +* Refactored tests so they can all run together, and not depend on what the RAILS_ENV constant is. +* Only add file extension if it was explicitly passed in, fixes other helpers in rails. +------------------------------------------------------------------------ +r51 | sbecker | 2007-10-26 16:24:48 -0400 (Fri, 26 Oct 2007) | 1 line + +* Updated jsmin.rb to latest version from 2007-07-20 +------------------------------------------------------------------------ +r50 | sbecker | 2007-10-23 23:16:07 -0400 (Tue, 23 Oct 2007) | 1 line + +Updated CHANGELOG + +------------------------------------------------------------------------ +r49 | sbecker | 2007-10-23 23:13:27 -0400 (Tue, 23 Oct 2007) | 1 line + +* Finally committed the subdirectory patch. (Thanks James Coglan!) +------------------------------------------------------------------------ +r48 | sbecker | 2007-10-15 15:10:43 -0400 (Mon, 15 Oct 2007) | 1 line + +* Speed up rake tasks and remove rails environment dependencies +------------------------------------------------------------------------ +r43 | sbecker | 2007-07-02 15:30:29 -0400 (Mon, 02 Jul 2007) | 1 line + +* Updated the docs regarding testing. +------------------------------------------------------------------------ +r42 | sbecker | 2007-07-02 15:27:00 -0400 (Mon, 02 Jul 2007) | 1 line + +* For production helper test, build packages once - on first setup. +------------------------------------------------------------------------ +r41 | sbecker | 2007-07-02 15:14:13 -0400 (Mon, 02 Jul 2007) | 1 line + +* Put build_all in test setup and delete_all in test teardown so all tests will pass the on first run of test suite. +------------------------------------------------------------------------ +r40 | sbecker | 2007-07-02 14:55:28 -0400 (Mon, 02 Jul 2007) | 1 line + +* Fix quotes, add contact info +------------------------------------------------------------------------ +r39 | sbecker | 2007-07-02 14:53:52 -0400 (Mon, 02 Jul 2007) | 1 line + +* Add note on how to run the tests for asset packager. +------------------------------------------------------------------------ +r38 | sbecker | 2007-01-25 15:36:42 -0500 (Thu, 25 Jan 2007) | 1 line + +added CHANGELOG w/ subversion log entries +------------------------------------------------------------------------ +r37 | sbecker | 2007-01-25 15:34:39 -0500 (Thu, 25 Jan 2007) | 1 line + +updated jsmin with new version from 2007-01-23 +------------------------------------------------------------------------ +r35 | sbecker | 2007-01-15 19:22:16 -0500 (Mon, 15 Jan 2007) | 1 line + +require synthesis/asset_package in rake tasks, as Rails 1.2 seems to necessitate +------------------------------------------------------------------------ +r34 | sbecker | 2007-01-05 12:22:09 -0500 (Fri, 05 Jan 2007) | 1 line + +do a require before including in action view, because when running migrations, the plugin lib files don't automatically get required, causing the include to error out +------------------------------------------------------------------------ +r33 | sbecker | 2006-12-23 02:03:41 -0500 (Sat, 23 Dec 2006) | 1 line + +updating readme with various tweaks +------------------------------------------------------------------------ +r32 | sbecker | 2006-12-23 02:03:12 -0500 (Sat, 23 Dec 2006) | 1 line + +updating readme with various tweaks +------------------------------------------------------------------------ +r31 | sbecker | 2006-12-23 01:52:25 -0500 (Sat, 23 Dec 2006) | 1 line + +updated readme to show how to use different media for stylesheets +------------------------------------------------------------------------ +r28 | sbecker | 2006-11-27 21:02:14 -0500 (Mon, 27 Nov 2006) | 1 line + +updated compute_public_path, added check for images +------------------------------------------------------------------------ +r27 | sbecker | 2006-11-10 18:28:29 -0500 (Fri, 10 Nov 2006) | 1 line + +tolerate extra periods in source asset names. fixed subversion revision checking to be file specific, instead of repository specific. +------------------------------------------------------------------------ +r26 | sbecker | 2006-06-24 17:04:27 -0400 (Sat, 24 Jun 2006) | 1 line + +convert asset_packages_yml var to a class var +------------------------------------------------------------------------ +r25 | sbecker | 2006-06-24 12:37:47 -0400 (Sat, 24 Jun 2006) | 1 line + +Added ability to include assets by package name. In development, include all uncompressed asset files. In production, include the single compressed asset. +------------------------------------------------------------------------ +r24 | sbecker | 2006-06-19 21:57:23 -0400 (Mon, 19 Jun 2006) | 1 line + +Updates to README and about.yml +------------------------------------------------------------------------ +r23 | sbecker | 2006-06-19 14:55:39 -0400 (Mon, 19 Jun 2006) | 2 lines + +Modifying about.yml and README + +------------------------------------------------------------------------ +r21 | sbecker | 2006-06-19 12:18:32 -0400 (Mon, 19 Jun 2006) | 2 lines + +added "formerly known as MergeJS" + +------------------------------------------------------------------------ +r20 | sbecker | 2006-06-19 12:14:46 -0400 (Mon, 19 Jun 2006) | 2 lines + +Updating docs + +------------------------------------------------------------------------ +r19 | sbecker | 2006-06-19 11:26:08 -0400 (Mon, 19 Jun 2006) | 2 lines + +removing compiled test assets from subversion + +------------------------------------------------------------------------ +r18 | sbecker | 2006-06-19 11:19:59 -0400 (Mon, 19 Jun 2006) | 2 lines + +Initial import. + +------------------------------------------------------------------------ +r17 | sbecker | 2006-06-19 11:18:56 -0400 (Mon, 19 Jun 2006) | 2 lines + +Creating directory. + +------------------------------------------------------------------------ diff --git a/vendor/plugins/asset_packager/README b/vendor/plugins/asset_packager/README new file mode 100644 index 0000000..ae94cf3 --- /dev/null +++ b/vendor/plugins/asset_packager/README @@ -0,0 +1,178 @@ += AssetPackager + +JavaScript and CSS Asset Compression for Production Rails Apps + +== Description + +When it comes time to deploy your new web application, instead of +sending down a dozen JavaScript and CSS files full of formatting +and comments, this Rails plugin makes it simple to merge and +compress JavaScript and CSS down into one or more files, increasing +speed and saving bandwidth. + +When in development, it allows you to use your original versions +and retain formatting and comments for readability and debugging. + +This code is released under the MIT license (like Ruby). You're free +to rip it up, enhance it, etc. And if you make any enhancements, +I'd like to know so I can add them back in. Thanks! + +* Formerly known as MergeJS. + +== Credit + +This Rails Plugin was inspired by Cal Henderson's article +"Serving JavaScript Fast" on Vitamin: +http://www.thinkvitamin.com/features/webapps/serving-javascript-fast + +It also uses the Ruby JavaScript Minifier created by +Douglas Crockford. +http://www.crockford.com/javascript/jsmin.html + +== Key Features + +* Merges and compresses JavaScript and CSS when running in production. +* Uses uncompressed originals when running in development. +* Generates packages on demand in production + +== Components + +* Rake tasks for managing packages +* Helper functions for including these JavaScript and CSS files in your views. +* YAML configuration file for mapping JavaScript and CSS files to packages. +* Rake Task for auto-generating the YAML file from your existing JavaScript files. + +== Updates + +November '08: +* Rails 2.2 compatibility fixes +* No more mucking with internal Rails functions, which means: + * Return to use of query-string timestamps. Greatly simplifies things. + * Multiple asset-hosts supported + * Filenames with "."'s in them, such as "jquery-x.x.x" are supported. +* Now compatible with any revision control system since it no longer uses revision numbers. +* Packages generated on demand in production mode. Running create_all rake task no longer necessary. + +== How to Use: + +1. Download and install the plugin: + ./script/plugin install git://github.com/sbecker/asset_packager.git + +2. Run the rake task "asset:packager:create_yml" to generate the /config/asset_packages.yml +file the first time. You will need to reorder files under 'base' so dependencies are loaded +in correct order. Feel free to rename or create new file packages. + +IMPORTANT: JavaScript files can break once compressed if each statement doesn't end with a semi-colon. +The minifier puts multiple statements on one line, so if the semi-colon is missing, the statement may no +longer makes sense and cause a syntax error. + +== Examples of config/asset_packages.yml + +Example from a fresh rails app after running the rake task. (Stylesheets is blank because a +default rails app has no stylesheets yet.): + +--- +javascripts: +- base: + - prototype + - effects + - dragdrop + - controls + - application +stylesheets: +- base: [] + +Multiple packages: + +--- +javascripts: +- base: + - prototype + - effects + - controls + - dragdrop + - application +- secondary: + - foo + - bar +stylesheets: +- base: + - screen + - header +- secondary: + - foo + - bar + +3. Run the rake task "asset:packager:build_all" to generate the compressed, merged versions +for each package. Whenever you rearrange the yaml file, you'll need to run this task again. + +Merging and compressing is expensive, so this is something we want to do once, not every time +your app starts. Thats why its a rake task. You can run this task via Capistrano when deploying +to avoid an initially slow request the first time a page is generated. + +Note: The package will be generated on the fly if it doesn't yet exist, so you don't *need* +to run the rake task when deploying, its just recommended for speeding up initial requests. + +4. Use the helper functions whenever including these files in your application. See below for examples. + +5. Potential warning: css compressor function currently removes CSS comments. This might blow +away some CSS hackery. To disable comment removal, comment out /lib/synthesis/asset_package.rb line 176. + +== JavaScript Examples + +Example call (based on above /config/asset_packages.yml): + <%= javascript_include_merged :base %> + +In development, this generates: + + + + + + +In production, this generates: + + +== Stylesheet Examples + +Example call: + <%= stylesheet_link_merged :base %> + +In development, this generates: + + + +In production this generates: + + +== Different CSS Media + +All options for stylesheet_link_tag still work, so if you want to specify a different media type: + <%= stylesheet_link_merged :secondary, 'media' => 'print' %> + +== Rake tasks + +rake asset:packager:build_all # Merge and compress assets +rake asset:packager:create_yml # Generate asset_packages.yml from existing assets +rake asset:packager:delete_all # Delete all asset builds + +== Running the tests + +This plugin has a full suite of tests. But since they +depend on rails, it has to be run in the context of a +rails app, in the vendor/plugins directory. Observe: + +> rails newtestapp +> cd newtestapp +> ./script/plugin install ./script/plugin install git://github.com/sbecker/asset_packager.git +> rake test:plugins PLUGIN=asset_packager # all tests pass + +== License +Copyright (c) 2006-2008 Scott Becker - http://synthesis.sbecker.net +Contact via Github for change requests, etc. + +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. \ No newline at end of file diff --git a/vendor/plugins/asset_packager/Rakefile b/vendor/plugins/asset_packager/Rakefile new file mode 100644 index 0000000..ca20585 --- /dev/null +++ b/vendor/plugins/asset_packager/Rakefile @@ -0,0 +1,22 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the asset_packager plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the asset_packager plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'AssetPackager' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/vendor/plugins/asset_packager/about.yml b/vendor/plugins/asset_packager/about.yml new file mode 100644 index 0000000..8860039 --- /dev/null +++ b/vendor/plugins/asset_packager/about.yml @@ -0,0 +1,8 @@ +author: Scott Becker +name: AssetPackager +summary: JavaScript and CSS Asset Compression for Production Rails Apps +homepage: http://synthesis.sbecker.net/pages/asset_packager +plugin: http://sbecker.net/shared/plugins/asset_packager +license: MIT +version: 0.2 +rails_version: 1.1.2+ diff --git a/vendor/plugins/asset_packager/init.rb b/vendor/plugins/asset_packager/init.rb new file mode 100644 index 0000000..eebf127 --- /dev/null +++ b/vendor/plugins/asset_packager/init.rb @@ -0,0 +1,2 @@ +require 'synthesis/asset_package_helper' +ActionView::Base.send :include, Synthesis::AssetPackageHelper \ No newline at end of file diff --git a/vendor/plugins/asset_packager/install.rb b/vendor/plugins/asset_packager/install.rb new file mode 100644 index 0000000..f7732d3 --- /dev/null +++ b/vendor/plugins/asset_packager/install.rb @@ -0,0 +1 @@ +# Install hook code here diff --git a/vendor/plugins/asset_packager/lib/jsmin.rb b/vendor/plugins/asset_packager/lib/jsmin.rb new file mode 100644 index 0000000..00fd804 --- /dev/null +++ b/vendor/plugins/asset_packager/lib/jsmin.rb @@ -0,0 +1,205 @@ +#!/usr/bin/ruby +# jsmin.rb 2007-07-20 +# Author: Uladzislau Latynski +# This work is a translation from C to Ruby of jsmin.c published by +# Douglas Crockford. Permission is hereby granted to use the Ruby +# version under the same conditions as the jsmin.c on which it is +# based. +# +# /* jsmin.c +# 2003-04-21 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# 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 shall be used for Good, not Evil. +# +# 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. + +EOF = -1 +$theA = "" +$theB = "" + +# isAlphanum -- return true if the character is a letter, digit, underscore, +# dollar sign, or non-ASCII character +def isAlphanum(c) + return false if !c || c == EOF + return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || + c == '\\' || c[0] > 126) +end + +# get -- return the next character from stdin. Watch out for lookahead. If +# the character is a control character, translate it to a space or linefeed. +def get() + c = $stdin.getc + return EOF if(!c) + c = c.chr + return c if (c >= " " || c == "\n" || c.unpack("c") == EOF) + return "\n" if (c == "\r") + return " " +end + +# Get the next character without getting it. +def peek() + lookaheadChar = $stdin.getc + $stdin.ungetc(lookaheadChar) + return lookaheadChar.chr +end + +# mynext -- get the next character, excluding comments. +# peek() is used to see if a '/' is followed by a '/' or '*'. +def mynext() + c = get + if (c == "/") + if(peek == "/") + while(true) + c = get + if (c <= "\n") + return c + end + end + end + if(peek == "*") + get + while(true) + case get + when "*" + if (peek == "/") + get + return " " + end + when EOF + raise "Unterminated comment" + end + end + end + end + return c +end + + +# action -- do something! What you do is determined by the argument: 1 +# Output A. Copy B to A. Get the next B. 2 Copy B to A. Get the next B. +# (Delete A). 3 Get the next B. (Delete B). action treats a string as a +# single character. Wow! action recognizes a regular expression if it is +# preceded by ( or , or =. +def action(a) + if(a==1) + $stdout.write $theA + end + if(a==1 || a==2) + $theA = $theB + if ($theA == "\'" || $theA == "\"") + while (true) + $stdout.write $theA + $theA = get + break if ($theA == $theB) + raise "Unterminated string literal" if ($theA <= "\n") + if ($theA == "\\") + $stdout.write $theA + $theA = get + end + end + end + end + if(a==1 || a==2 || a==3) + $theB = mynext + if ($theB == "/" && ($theA == "(" || $theA == "," || $theA == "=" || + $theA == ":" || $theA == "[" || $theA == "!" || + $theA == "&" || $theA == "|" || $theA == "?" || + $theA == "{" || $theA == "}" || $theA == ";" || + $theA == "\n")) + $stdout.write $theA + $stdout.write $theB + while (true) + $theA = get + if ($theA == "/") + break + elsif ($theA == "\\") + $stdout.write $theA + $theA = get + elsif ($theA <= "\n") + raise "Unterminated RegExp Literal" + end + $stdout.write $theA + end + $theB = mynext + end + end +end + +# jsmin -- Copy the input to the output, deleting the characters which are +# insignificant to JavaScript. Comments will be removed. Tabs will be +# replaced with spaces. Carriage returns will be replaced with linefeeds. +# Most spaces and linefeeds will be removed. +def jsmin + $theA = "\n" + action(3) + while ($theA != EOF) + case $theA + when " " + if (isAlphanum($theB)) + action(1) + else + action(2) + end + when "\n" + case ($theB) + when "{","[","(","+","-" + action(1) + when " " + action(3) + else + if (isAlphanum($theB)) + action(1) + else + action(2) + end + end + else + case ($theB) + when " " + if (isAlphanum($theA)) + action(1) + else + action(3) + end + when "\n" + case ($theA) + when "}","]",")","+","-","\"","\\", "'", '"' + action(1) + else + if (isAlphanum($theA)) + action(1) + else + action(3) + end + end + else + action(1) + end + end + end +end + +ARGV.each do |anArg| + $stdout.write "// #{anArg}\n" +end + +jsmin \ No newline at end of file diff --git a/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb b/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb new file mode 100644 index 0000000..b59936a --- /dev/null +++ b/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb @@ -0,0 +1,212 @@ +module Synthesis + class AssetPackage + + # class variables + @@asset_packages_yml = $asset_packages_yml || + (File.exists?("#{RAILS_ROOT}/config/asset_packages.yml") ? YAML.load_file("#{RAILS_ROOT}/config/asset_packages.yml") : nil) + + # singleton methods + class << self + + def merge_environments=(environments) + @@merge_environments = environments + end + + def merge_environments + @@merge_environments ||= ["production"] + end + + def parse_path(path) + /^(?:(.*)\/)?([^\/]+)$/.match(path).to_a + end + + def find_by_type(asset_type) + @@asset_packages_yml[asset_type].map { |p| self.new(asset_type, p) } + end + + def find_by_target(asset_type, target) + package_hash = @@asset_packages_yml[asset_type].find {|p| p.keys.first == target } + package_hash ? self.new(asset_type, package_hash) : nil + end + + def find_by_source(asset_type, source) + path_parts = parse_path(source) + package_hash = @@asset_packages_yml[asset_type].find do |p| + key = p.keys.first + p[key].include?(path_parts[2]) && (parse_path(key)[1] == path_parts[1]) + end + package_hash ? self.new(asset_type, package_hash) : nil + end + + def targets_from_sources(asset_type, sources) + package_names = Array.new + sources.each do |source| + package = find_by_target(asset_type, source) || find_by_source(asset_type, source) + package_names << (package ? package.current_file : source) + end + package_names.uniq + end + + def sources_from_targets(asset_type, targets) + source_names = Array.new + targets.each do |target| + package = find_by_target(asset_type, target) + source_names += (package ? package.sources.collect do |src| + package.target_dir.gsub(/^(.+)$/, '\1/') + src + end : target.to_a) + end + source_names.uniq + end + + def build_all + @@asset_packages_yml.keys.each do |asset_type| + @@asset_packages_yml[asset_type].each { |p| self.new(asset_type, p).build } + end + end + + def delete_all + @@asset_packages_yml.keys.each do |asset_type| + @@asset_packages_yml[asset_type].each { |p| self.new(asset_type, p).delete_previous_build } + end + end + + def create_yml + unless File.exists?("#{RAILS_ROOT}/config/asset_packages.yml") + asset_yml = Hash.new + + asset_yml['javascripts'] = [{"base" => build_file_list("#{RAILS_ROOT}/public/javascripts", "js")}] + asset_yml['stylesheets'] = [{"base" => build_file_list("#{RAILS_ROOT}/public/stylesheets", "css")}] + + File.open("#{RAILS_ROOT}/config/asset_packages.yml", "w") do |out| + YAML.dump(asset_yml, out) + end + + log "config/asset_packages.yml example file created!" + log "Please reorder files under 'base' so dependencies are loaded in correct order." + else + log "config/asset_packages.yml already exists. Aborting task..." + end + end + + end + + # instance methods + attr_accessor :asset_type, :target, :target_dir, :sources + + def initialize(asset_type, package_hash) + target_parts = self.class.parse_path(package_hash.keys.first) + @target_dir = target_parts[1].to_s + @target = target_parts[2].to_s + @sources = package_hash[package_hash.keys.first] + @asset_type = asset_type + @asset_path = ($asset_base_path ? "#{$asset_base_path}/" : "#{RAILS_ROOT}/public/") + + "#{@asset_type}#{@target_dir.gsub(/^(.+)$/, '/\1')}" + @extension = get_extension + @file_name = "#{@target}_packaged.#{@extension}" + @full_path = File.join(@asset_path, @file_name) + end + + def package_exists? + File.exists?(@full_path) + end + + def current_file + build unless package_exists? + + path = @target_dir.gsub(/^(.+)$/, '\1/') + "#{path}#{@target}_packaged" + end + + def build + delete_previous_build + create_new_build + end + + def delete_previous_build + File.delete(@full_path) if File.exists?(@full_path) + end + + private + def create_new_build + new_build_path = "#{@asset_path}/#{@target}_packaged.#{@extension}" + if File.exists?(new_build_path) + log "Latest version already exists: #{new_build_path}" + else + File.open(new_build_path, "w") {|f| f.write(compressed_file) } + log "Created #{new_build_path}" + end + end + + def merged_file + merged_file = "" + @sources.each {|s| + File.open("#{@asset_path}/#{s}.#{@extension}", "r") { |f| + merged_file += f.read + "\n" + } + } + merged_file + end + + def compressed_file + case @asset_type + when "javascripts" then compress_js(merged_file) + when "stylesheets" then compress_css(merged_file) + end + end + + def compress_js(source) + jsmin_path = "#{RAILS_ROOT}/vendor/plugins/asset_packager/lib" + tmp_path = "#{RAILS_ROOT}/tmp/#{@target}_packaged" + + # write out to a temp file + File.open("#{tmp_path}_uncompressed.js", "w") {|f| f.write(source) } + + # compress file with JSMin library + `ruby #{jsmin_path}/jsmin.rb <#{tmp_path}_uncompressed.js >#{tmp_path}_compressed.js \n` + + # read it back in and trim it + result = "" + File.open("#{tmp_path}_compressed.js", "r") { |f| result += f.read.strip } + + # delete temp files if they exist + File.delete("#{tmp_path}_uncompressed.js") if File.exists?("#{tmp_path}_uncompressed.js") + File.delete("#{tmp_path}_compressed.js") if File.exists?("#{tmp_path}_compressed.js") + + result + end + + def compress_css(source) + source.gsub!(/\s+/, " ") # collapse space + source.gsub!(/\/\*(.*?)\*\//, "") # remove comments - caution, might want to remove this if using css hacks + source.gsub!(/\} /, "}\n") # add line breaks + source.gsub!(/\n$/, "") # remove last break + source.gsub!(/ \{ /, " {") # trim inside brackets + source.gsub!(/; \}/, "}") # trim inside brackets + source + end + + def get_extension + case @asset_type + when "javascripts" then "js" + when "stylesheets" then "css" + end + end + + def log(message) + self.class.log(message) + end + + def self.log(message) + puts message + end + + def self.build_file_list(path, extension) + re = Regexp.new(".#{extension}\\z") + file_list = Dir.new(path).entries.delete_if { |x| ! (x =~ re) }.map {|x| x.chomp(".#{extension}")} + # reverse javascript entries so prototype comes first on a base rails app + file_list.reverse! if extension == "js" + file_list + end + + end +end diff --git a/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb b/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb new file mode 100644 index 0000000..dd1ab23 --- /dev/null +++ b/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb @@ -0,0 +1,39 @@ +module Synthesis + module AssetPackageHelper + + def should_merge? + AssetPackage.merge_environments.include?(RAILS_ENV) + end + + def javascript_include_merged(*sources) + options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { } + + if sources.include?(:defaults) + sources = sources[0..(sources.index(:defaults))] + + ['prototype', 'effects', 'dragdrop', 'controls'] + + (File.exists?("#{RAILS_ROOT}/public/javascripts/application.js") ? ['application'] : []) + + sources[(sources.index(:defaults) + 1)..sources.length] + sources.delete(:defaults) + end + + sources.collect!{|s| s.to_s} + sources = (should_merge? ? + AssetPackage.targets_from_sources("javascripts", sources) : + AssetPackage.sources_from_targets("javascripts", sources)) + + sources.collect {|source| javascript_include_tag(source, options) }.join("\n") + end + + def stylesheet_link_merged(*sources) + options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { } + + sources.collect!{|s| s.to_s} + sources = (should_merge? ? + AssetPackage.targets_from_sources("stylesheets", sources) : + AssetPackage.sources_from_targets("stylesheets", sources)) + + sources.collect { |source| stylesheet_link_tag(source, options) }.join("\n") + end + + end +end \ No newline at end of file diff --git a/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake b/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake new file mode 100644 index 0000000..602fcc6 --- /dev/null +++ b/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake @@ -0,0 +1,23 @@ +require 'yaml' +require File.dirname(__FILE__) + '/../lib/synthesis/asset_package' + +namespace :asset do + namespace :packager do + + desc "Merge and compress assets" + task :build_all do + Synthesis::AssetPackage.build_all + end + + desc "Delete all asset builds" + task :delete_all do + Synthesis::AssetPackage.delete_all + end + + desc "Generate asset_packages.yml from existing assets" + task :create_yml do + Synthesis::AssetPackage.create_yml + end + + end +end diff --git a/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb b/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb new file mode 100644 index 0000000..fe58174 --- /dev/null +++ b/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb @@ -0,0 +1,100 @@ +$:.unshift(File.dirname(__FILE__) + '/../lib') + +ENV['RAILS_ENV'] = "development" +require File.dirname(__FILE__) + '/../../../../config/environment' +require 'test/unit' +require 'rubygems' +require 'mocha' + +require 'action_controller/test_process' + +ActionController::Base.logger = nil +ActionController::Routing::Routes.reload rescue nil + +$asset_packages_yml = YAML.load_file("#{RAILS_ROOT}/vendor/plugins/asset_packager/test/asset_packages.yml") +$asset_base_path = "#{RAILS_ROOT}/vendor/plugins/asset_packager/test/assets" + +class AssetPackageHelperDevelopmentTest < Test::Unit::TestCase + include ActionView::Helpers::TagHelper + include ActionView::Helpers::AssetTagHelper + include Synthesis::AssetPackageHelper + + def setup + Synthesis::AssetPackage.any_instance.stubs(:log) + + @controller = Class.new do + def request + @request ||= ActionController::TestRequest.new + end + end.new + end + + def build_js_expected_string(*sources) + sources.map {|s| javascript_include_tag(s) }.join("\n") + end + + def build_css_expected_string(*sources) + sources.map {|s| stylesheet_link_tag(s) }.join("\n") + end + + def test_js_basic + assert_dom_equal build_js_expected_string("prototype"), + javascript_include_merged("prototype") + end + + def test_js_multiple_packages + assert_dom_equal build_js_expected_string("prototype", "foo"), + javascript_include_merged("prototype", "foo") + end + + def test_js_unpackaged_file + assert_dom_equal build_js_expected_string("prototype", "foo", "not_part_of_a_package"), + javascript_include_merged("prototype", "foo", "not_part_of_a_package") + end + + def test_js_multiple_from_same_package + assert_dom_equal build_js_expected_string("prototype", "effects", "controls", "not_part_of_a_package", "foo"), + javascript_include_merged("prototype", "effects", "controls", "not_part_of_a_package", "foo") + end + + def test_js_by_package_name + assert_dom_equal build_js_expected_string("prototype", "effects", "controls", "dragdrop"), + javascript_include_merged(:base) + end + + def test_js_multiple_package_names + assert_dom_equal build_js_expected_string("prototype", "effects", "controls", "dragdrop", "foo", "bar", "application"), + javascript_include_merged(:base, :secondary) + end + + def test_css_basic + assert_dom_equal build_css_expected_string("screen"), + stylesheet_link_merged("screen") + end + + def test_css_multiple_packages + assert_dom_equal build_css_expected_string("screen", "foo", "subdir/bar"), + stylesheet_link_merged("screen", "foo", "subdir/bar") + end + + def test_css_unpackaged_file + assert_dom_equal build_css_expected_string("screen", "foo", "not_part_of_a_package", "subdir/bar"), + stylesheet_link_merged("screen", "foo", "not_part_of_a_package", "subdir/bar") + end + + def test_css_multiple_from_same_package + assert_dom_equal build_css_expected_string("screen", "header", "not_part_of_a_package", "foo", "bar", "subdir/foo", "subdir/bar"), + stylesheet_link_merged("screen", "header", "not_part_of_a_package", "foo", "bar", "subdir/foo", "subdir/bar") + end + + def test_css_by_package_name + assert_dom_equal build_css_expected_string("screen", "header"), + stylesheet_link_merged(:base) + end + + def test_css_multiple_package_names + assert_dom_equal build_css_expected_string("screen", "header", "foo", "bar", "subdir/foo", "subdir/bar"), + stylesheet_link_merged(:base, :secondary, "subdir/styles") + end + +end diff --git a/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb b/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb new file mode 100644 index 0000000..9680761 --- /dev/null +++ b/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb @@ -0,0 +1,140 @@ +$:.unshift(File.dirname(__FILE__) + '/../lib') + +require File.dirname(__FILE__) + '/../../../../config/environment' +require 'test/unit' +require 'rubygems' +require 'mocha' + +require 'action_controller/test_process' + +ActionController::Base.logger = nil +ActionController::Routing::Routes.reload rescue nil + +$asset_packages_yml = YAML.load_file("#{RAILS_ROOT}/vendor/plugins/asset_packager/test/asset_packages.yml") +$asset_base_path = "#{RAILS_ROOT}/vendor/plugins/asset_packager/test/assets" + +class AssetPackageHelperProductionTest < Test::Unit::TestCase + include ActionView::Helpers::TagHelper + include ActionView::Helpers::AssetTagHelper + include Synthesis::AssetPackageHelper + + cattr_accessor :packages_built + + def setup + Synthesis::AssetPackage.any_instance.stubs(:log) + self.stubs(:should_merge?).returns(true) + + @controller = Class.new do + def request + @request ||= ActionController::TestRequest.new + end + end.new + + build_packages_once + end + + def build_packages_once + unless @@packages_built + Synthesis::AssetPackage.build_all + @@packages_built = true + end + end + + def build_js_expected_string(*sources) + sources.map {|s| javascript_include_tag(s) }.join("\n") + end + + def build_css_expected_string(*sources) + sources.map {|s| stylesheet_link_tag(s) }.join("\n") + end + + def test_js_basic + current_file = Synthesis::AssetPackage.find_by_source("javascripts", "prototype").current_file + assert_dom_equal build_js_expected_string(current_file), + javascript_include_merged("prototype") + end + + def test_js_multiple_packages + current_file1 = Synthesis::AssetPackage.find_by_source("javascripts", "prototype").current_file + current_file2 = Synthesis::AssetPackage.find_by_source("javascripts", "foo").current_file + + assert_dom_equal build_js_expected_string(current_file1, current_file2), + javascript_include_merged("prototype", "foo") + end + + def test_js_unpackaged_file + current_file1 = Synthesis::AssetPackage.find_by_source("javascripts", "prototype").current_file + current_file2 = Synthesis::AssetPackage.find_by_source("javascripts", "foo").current_file + + assert_dom_equal build_js_expected_string(current_file1, current_file2, "not_part_of_a_package"), + javascript_include_merged("prototype", "foo", "not_part_of_a_package") + end + + def test_js_multiple_from_same_package + current_file1 = Synthesis::AssetPackage.find_by_source("javascripts", "prototype").current_file + current_file2 = Synthesis::AssetPackage.find_by_source("javascripts", "foo").current_file + + assert_dom_equal build_js_expected_string(current_file1, "not_part_of_a_package", current_file2), + javascript_include_merged("prototype", "effects", "controls", "not_part_of_a_package", "foo") + end + + def test_js_by_package_name + package_name = Synthesis::AssetPackage.find_by_target("javascripts", "base").current_file + assert_dom_equal build_js_expected_string(package_name), + javascript_include_merged(:base) + end + + def test_js_multiple_package_names + package_name1 = Synthesis::AssetPackage.find_by_target("javascripts", "base").current_file + package_name2 = Synthesis::AssetPackage.find_by_target("javascripts", "secondary").current_file + assert_dom_equal build_js_expected_string(package_name1, package_name2), + javascript_include_merged(:base, :secondary) + end + + def test_css_basic + current_file = Synthesis::AssetPackage.find_by_source("stylesheets", "screen").current_file + assert_dom_equal build_css_expected_string(current_file), + stylesheet_link_merged("screen") + end + + def test_css_multiple_packages + current_file1 = Synthesis::AssetPackage.find_by_source("stylesheets", "screen").current_file + current_file2 = Synthesis::AssetPackage.find_by_source("stylesheets", "foo").current_file + current_file3 = Synthesis::AssetPackage.find_by_source("stylesheets", "subdir/bar").current_file + + assert_dom_equal build_css_expected_string(current_file1, current_file2, current_file3), + stylesheet_link_merged("screen", "foo", "subdir/bar") + end + + def test_css_unpackaged_file + current_file1 = Synthesis::AssetPackage.find_by_source("stylesheets", "screen").current_file + current_file2 = Synthesis::AssetPackage.find_by_source("stylesheets", "foo").current_file + + assert_dom_equal build_css_expected_string(current_file1, current_file2, "not_part_of_a_package"), + stylesheet_link_merged("screen", "foo", "not_part_of_a_package") + end + + def test_css_multiple_from_same_package + current_file1 = Synthesis::AssetPackage.find_by_source("stylesheets", "screen").current_file + current_file2 = Synthesis::AssetPackage.find_by_source("stylesheets", "foo").current_file + current_file3 = Synthesis::AssetPackage.find_by_source("stylesheets", "subdir/bar").current_file + + assert_dom_equal build_css_expected_string(current_file1, "not_part_of_a_package", current_file2, current_file3), + stylesheet_link_merged("screen", "header", "not_part_of_a_package", "foo", "bar", "subdir/foo", "subdir/bar") + end + + def test_css_by_package_name + package_name = Synthesis::AssetPackage.find_by_target("stylesheets", "base").current_file + assert_dom_equal build_css_expected_string(package_name), + stylesheet_link_merged(:base) + end + + def test_css_multiple_package_names + package_name1 = Synthesis::AssetPackage.find_by_target("stylesheets", "base").current_file + package_name2 = Synthesis::AssetPackage.find_by_target("stylesheets", "secondary").current_file + package_name3 = Synthesis::AssetPackage.find_by_target("stylesheets", "subdir/styles").current_file + assert_dom_equal build_css_expected_string(package_name1, package_name2, package_name3), + stylesheet_link_merged(:base, :secondary, "subdir/styles") + end + +end diff --git a/vendor/plugins/asset_packager/test/asset_packager_test.rb b/vendor/plugins/asset_packager/test/asset_packager_test.rb new file mode 100644 index 0000000..7c13671 --- /dev/null +++ b/vendor/plugins/asset_packager/test/asset_packager_test.rb @@ -0,0 +1,92 @@ +require File.dirname(__FILE__) + '/../../../../config/environment' +require 'test/unit' +require 'mocha' + +$asset_packages_yml = YAML.load_file("#{RAILS_ROOT}/vendor/plugins/asset_packager/test/asset_packages.yml") +$asset_base_path = "#{RAILS_ROOT}/vendor/plugins/asset_packager/test/assets" + +class AssetPackagerTest < Test::Unit::TestCase + include Synthesis + + def setup + Synthesis::AssetPackage.any_instance.stubs(:log) + Synthesis::AssetPackage.build_all + end + + def teardown + Synthesis::AssetPackage.delete_all + end + + def test_find_by_type + js_asset_packages = Synthesis::AssetPackage.find_by_type("javascripts") + assert_equal 2, js_asset_packages.length + assert_equal "base", js_asset_packages[0].target + assert_equal ["prototype", "effects", "controls", "dragdrop"], js_asset_packages[0].sources + end + + def test_find_by_target + package = Synthesis::AssetPackage.find_by_target("javascripts", "base") + assert_equal "base", package.target + assert_equal ["prototype", "effects", "controls", "dragdrop"], package.sources + end + + def test_find_by_source + package = Synthesis::AssetPackage.find_by_source("javascripts", "controls") + assert_equal "base", package.target + assert_equal ["prototype", "effects", "controls", "dragdrop"], package.sources + end + + def test_delete_and_build + Synthesis::AssetPackage.delete_all + js_package_names = Dir.new("#{$asset_base_path}/javascripts").entries.delete_if { |x| ! (x =~ /\A\w+_packaged.js/) } + css_package_names = Dir.new("#{$asset_base_path}/stylesheets").entries.delete_if { |x| ! (x =~ /\A\w+_packaged.css/) } + css_subdir_package_names = Dir.new("#{$asset_base_path}/stylesheets/subdir").entries.delete_if { |x| ! (x =~ /\A\w+_packaged.css/) } + + assert_equal 0, js_package_names.length + assert_equal 0, css_package_names.length + assert_equal 0, css_subdir_package_names.length + + Synthesis::AssetPackage.build_all + js_package_names = Dir.new("#{$asset_base_path}/javascripts").entries.delete_if { |x| ! (x =~ /\A\w+_packaged.js/) }.sort + css_package_names = Dir.new("#{$asset_base_path}/stylesheets").entries.delete_if { |x| ! (x =~ /\A\w+_packaged.css/) }.sort + css_subdir_package_names = Dir.new("#{$asset_base_path}/stylesheets/subdir").entries.delete_if { |x| ! (x =~ /\A\w+_packaged.css/) }.sort + + assert_equal 2, js_package_names.length + assert_equal 2, css_package_names.length + assert_equal 1, css_subdir_package_names.length + assert js_package_names[0].match(/\Abase_packaged.js\z/) + assert js_package_names[1].match(/\Asecondary_packaged.js\z/) + assert css_package_names[0].match(/\Abase_packaged.css\z/) + assert css_package_names[1].match(/\Asecondary_packaged.css\z/) + assert css_subdir_package_names[0].match(/\Astyles_packaged.css\z/) + end + + def test_js_names_from_sources + package_names = Synthesis::AssetPackage.targets_from_sources("javascripts", ["prototype", "effects", "noexist1", "controls", "foo", "noexist2"]) + assert_equal 4, package_names.length + assert package_names[0].match(/\Abase_packaged\z/) + assert_equal package_names[1], "noexist1" + assert package_names[2].match(/\Asecondary_packaged\z/) + assert_equal package_names[3], "noexist2" + end + + def test_css_names_from_sources + package_names = Synthesis::AssetPackage.targets_from_sources("stylesheets", ["header", "screen", "noexist1", "foo", "noexist2"]) + assert_equal 4, package_names.length + assert package_names[0].match(/\Abase_packaged\z/) + assert_equal package_names[1], "noexist1" + assert package_names[2].match(/\Asecondary_packaged\z/) + assert_equal package_names[3], "noexist2" + end + + def test_should_return_merge_environments_when_set + Synthesis::AssetPackage.merge_environments = ["staging", "production"] + assert_equal ["staging", "production"], Synthesis::AssetPackage.merge_environments + end + + def test_should_only_return_production_merge_environment_when_not_set + assert_equal ["production"], Synthesis::AssetPackage.merge_environments + end + + +end diff --git a/vendor/plugins/asset_packager/test/asset_packages.yml b/vendor/plugins/asset_packager/test/asset_packages.yml new file mode 100644 index 0000000..37287bd --- /dev/null +++ b/vendor/plugins/asset_packager/test/asset_packages.yml @@ -0,0 +1,20 @@ +javascripts: +- base: + - prototype + - effects + - controls + - dragdrop +- secondary: + - foo + - bar + - application +stylesheets: +- base: + - screen + - header +- secondary: + - foo + - bar +- subdir/styles: + - foo + - bar diff --git a/vendor/plugins/asset_packager/test/assets/javascripts/application.js b/vendor/plugins/asset_packager/test/assets/javascripts/application.js new file mode 100755 index 0000000..fe45776 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/application.js @@ -0,0 +1,2 @@ +// Place your application-specific JavaScript functions and classes here +// This file is automatically included by javascript_include_tag :defaults diff --git a/vendor/plugins/asset_packager/test/assets/javascripts/bar.js b/vendor/plugins/asset_packager/test/assets/javascripts/bar.js new file mode 100755 index 0000000..3a65f10 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/bar.js @@ -0,0 +1,4 @@ +bar bar bar +bar bar bar +bar bar bar + diff --git a/vendor/plugins/asset_packager/test/assets/javascripts/controls.js b/vendor/plugins/asset_packager/test/assets/javascripts/controls.js new file mode 100755 index 0000000..de0261e --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/controls.js @@ -0,0 +1,815 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005 Jon Tirsen (http://www.tirsen.com) +// Contributors: +// Richard Livsey +// Rahul Bhargava +// Rob Wills +// +// See scriptaculous.js for full license. + +// 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. + +var Autocompleter = {} +Autocompleter.Base = function() {}; +Autocompleter.Base.prototype = { + baseInitialize: function(element, update, options) { + this.element = $(element); + this.update = $(update); + this.hasFocus = false; + this.changed = false; + this.active = false; + this.index = 0; + this.entryCount = 0; + + 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); + + this.observer = null; + + this.element.setAttribute('autocomplete','off'); + + Element.hide(this.update); + + Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); + Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); + }, + + show: function() { + if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); + if(!this.iefix && + (navigator.appVersion.indexOf('MSIE')>0) && + (navigator.userAgent.indexOf('Opera')<0) && + (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); + 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(); + if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); + return; + case Event.KEY_DOWN: + this.markNext(); + this.render(); + if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); + return; + } + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || + (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return; + + 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; + }, + + markNext: function() { + if(this.index < this.entryCount-1) this.index++ + else this.index = 0; + }, + + 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 = document.getElementsByClassName(this.options.select, selectedElement) || []; + if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); + } else + value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + + var lastTokenPos = this.findLastToken(); + if (lastTokenPos != -1) { + var newValue = this.element.value.substr(0, lastTokenPos + 1); + var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); + if (whitespace) + newValue += whitespace[0]; + this.element.value = newValue + value; + } else { + this.element.value = 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.firstChild); + + if(this.update.firstChild && this.update.firstChild.childNodes) { + this.entryCount = + this.update.firstChild.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; + 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; + if(this.getToken().length>=this.options.minChars) { + this.startIndicator(); + this.getUpdatedChoices(); + } else { + this.active = false; + this.hide(); + } + }, + + getToken: function() { + var tokenPos = this.findLastToken(); + if (tokenPos != -1) + var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); + else + var ret = this.element.value; + + return /\n/.test(ret) ? '' : ret; + }, + + findLastToken: function() { + var lastTokenPos = -1; + + for (var i=0; i lastTokenPos) + lastTokenPos = thisTokenPos; + } + return lastTokenPos; + } +} + +Ajax.Autocompleter = Class.create(); +Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { + 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() { + 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.Local.prototype = Object.extend(new 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 +// +// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor + +// 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(); +Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; +Ajax.InPlaceEditor.prototype = { + initialize: function(element, url, options) { + this.url = url; + this.element = $(element); + + this.options = Object.extend({ + okButton: true, + okText: "ok", + cancelLink: true, + cancelText: "cancel", + savingText: "Saving...", + clickToEditText: "Click to edit", + okText: "ok", + rows: 1, + onComplete: function(transport, element) { + new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); + }, + onFailure: function(transport) { + alert("Error communicating with the server: " + transport.responseText.stripTags()); + }, + callback: function(form) { + return Form.serialize(form); + }, + handleLineBreaks: true, + loadingText: 'Loading...', + savingClassName: 'inplaceeditor-saving', + loadingClassName: 'inplaceeditor-loading', + formClassName: 'inplaceeditor-form', + highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, + highlightendcolor: "#FFFFFF", + externalControl: null, + submitOnBlur: false, + ajaxOptions: {}, + evalScripts: false + }, options || {}); + + if(!this.options.formId && this.element.id) { + this.options.formId = this.element.id + "-inplaceeditor"; + if ($(this.options.formId)) { + // there's already a form with that name, don't specify an id + this.options.formId = null; + } + } + + if (this.options.externalControl) { + this.options.externalControl = $(this.options.externalControl); + } + + this.originalBackground = Element.getStyle(this.element, 'background-color'); + if (!this.originalBackground) { + this.originalBackground = "transparent"; + } + + this.element.title = this.options.clickToEditText; + + this.onclickListener = this.enterEditMode.bindAsEventListener(this); + this.mouseoverListener = this.enterHover.bindAsEventListener(this); + this.mouseoutListener = this.leaveHover.bindAsEventListener(this); + Event.observe(this.element, 'click', this.onclickListener); + Event.observe(this.element, 'mouseover', this.mouseoverListener); + Event.observe(this.element, 'mouseout', this.mouseoutListener); + if (this.options.externalControl) { + Event.observe(this.options.externalControl, 'click', this.onclickListener); + Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); + Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); + } + }, + enterEditMode: function(evt) { + if (this.saving) return; + if (this.editing) return; + this.editing = true; + this.onEnterEditMode(); + if (this.options.externalControl) { + Element.hide(this.options.externalControl); + } + Element.hide(this.element); + this.createForm(); + this.element.parentNode.insertBefore(this.form, this.element); + Field.scrollFreeActivate(this.editField); + // stop the event to avoid a page refresh in Safari + if (evt) { + Event.stop(evt); + } + return false; + }, + createForm: function() { + this.form = document.createElement("form"); + this.form.id = this.options.formId; + Element.addClassName(this.form, this.options.formClassName) + this.form.onsubmit = this.onSubmit.bind(this); + + this.createEditField(); + + if (this.options.textarea) { + var br = document.createElement("br"); + this.form.appendChild(br); + } + + if (this.options.okButton) { + okButton = document.createElement("input"); + okButton.type = "submit"; + okButton.value = this.options.okText; + okButton.className = 'editor_ok_button'; + this.form.appendChild(okButton); + } + + if (this.options.cancelLink) { + cancelLink = document.createElement("a"); + cancelLink.href = "#"; + cancelLink.appendChild(document.createTextNode(this.options.cancelText)); + cancelLink.onclick = this.onclickCancel.bind(this); + cancelLink.className = 'editor_cancel'; + this.form.appendChild(cancelLink); + } + }, + hasHTMLLineBreaks: function(string) { + if (!this.options.handleLineBreaks) return false; + return string.match(/
                        /i); + }, + convertHTMLLineBreaks: function(string) { + return string.replace(/
                        /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

                        /gi, ""); + }, + createEditField: function() { + var text; + if(this.options.loadTextURL) { + text = this.options.loadingText; + } else { + text = this.getText(); + } + + var obj = this; + + if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { + this.options.textarea = false; + var textField = document.createElement("input"); + textField.obj = this; + textField.type = "text"; + textField.name = "value"; + textField.value = text; + textField.style.backgroundColor = this.options.highlightcolor; + textField.className = 'editor_field'; + var size = this.options.size || this.options.cols || 0; + if (size != 0) textField.size = size; + if (this.options.submitOnBlur) + textField.onblur = this.onSubmit.bind(this); + this.editField = textField; + } else { + this.options.textarea = true; + var textArea = document.createElement("textarea"); + textArea.obj = this; + textArea.name = "value"; + textArea.value = this.convertHTMLLineBreaks(text); + textArea.rows = this.options.rows; + textArea.cols = this.options.cols || 40; + textArea.className = 'editor_field'; + if (this.options.submitOnBlur) + textArea.onblur = this.onSubmit.bind(this); + this.editField = textArea; + } + + if(this.options.loadTextURL) { + this.loadExternalText(); + } + this.form.appendChild(this.editField); + }, + getText: function() { + return this.element.innerHTML; + }, + loadExternalText: function() { + Element.addClassName(this.form, this.options.loadingClassName); + this.editField.disabled = true; + new Ajax.Request( + this.options.loadTextURL, + Object.extend({ + asynchronous: true, + onComplete: this.onLoadedExternalText.bind(this) + }, this.options.ajaxOptions) + ); + }, + onLoadedExternalText: function(transport) { + Element.removeClassName(this.form, this.options.loadingClassName); + this.editField.disabled = false; + this.editField.value = transport.responseText.stripTags(); + }, + onclickCancel: function() { + this.onComplete(); + this.leaveEditMode(); + return false; + }, + onFailure: function(transport) { + this.options.onFailure(transport); + if (this.oldInnerHTML) { + this.element.innerHTML = this.oldInnerHTML; + this.oldInnerHTML = null; + } + return false; + }, + onSubmit: function() { + // onLoading resets these so we need to save them away for the Ajax call + var form = this.form; + var value = this.editField.value; + + // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... + // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... + // to be displayed indefinitely + this.onLoading(); + + if (this.options.evalScripts) { + new Ajax.Request( + this.url, Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this), + asynchronous:true, + evalScripts:true + }, this.options.ajaxOptions)); + } else { + new Ajax.Updater( + { success: this.element, + // don't update on failure (this could be an option) + failure: null }, + this.url, Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this) + }, this.options.ajaxOptions)); + } + // stop the event to avoid a page refresh in Safari + if (arguments.length > 1) { + Event.stop(arguments[0]); + } + return false; + }, + onLoading: function() { + this.saving = true; + this.removeForm(); + this.leaveHover(); + this.showSaving(); + }, + showSaving: function() { + this.oldInnerHTML = this.element.innerHTML; + this.element.innerHTML = this.options.savingText; + Element.addClassName(this.element, this.options.savingClassName); + this.element.style.backgroundColor = this.originalBackground; + Element.show(this.element); + }, + removeForm: function() { + if(this.form) { + if (this.form.parentNode) Element.remove(this.form); + this.form = null; + } + }, + enterHover: function() { + if (this.saving) return; + this.element.style.backgroundColor = this.options.highlightcolor; + if (this.effect) { + this.effect.cancel(); + } + Element.addClassName(this.element, this.options.hoverClassName) + }, + leaveHover: function() { + if (this.options.backgroundColor) { + this.element.style.backgroundColor = this.oldBackground; + } + Element.removeClassName(this.element, this.options.hoverClassName) + if (this.saving) return; + this.effect = new Effect.Highlight(this.element, { + startcolor: this.options.highlightcolor, + endcolor: this.options.highlightendcolor, + restorecolor: this.originalBackground + }); + }, + leaveEditMode: function() { + Element.removeClassName(this.element, this.options.savingClassName); + this.removeForm(); + this.leaveHover(); + this.element.style.backgroundColor = this.originalBackground; + Element.show(this.element); + if (this.options.externalControl) { + Element.show(this.options.externalControl); + } + this.editing = false; + this.saving = false; + this.oldInnerHTML = null; + this.onLeaveEditMode(); + }, + onComplete: function(transport) { + this.leaveEditMode(); + this.options.onComplete.bind(this)(transport, this.element); + }, + onEnterEditMode: function() {}, + onLeaveEditMode: function() {}, + dispose: function() { + if (this.oldInnerHTML) { + this.element.innerHTML = this.oldInnerHTML; + } + this.leaveEditMode(); + Event.stopObserving(this.element, 'click', this.onclickListener); + Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); + Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); + if (this.options.externalControl) { + Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); + Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); + Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); + } + } +}; + +Ajax.InPlaceCollectionEditor = Class.create(); +Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); +Object.extend(Ajax.InPlaceCollectionEditor.prototype, { + createEditField: function() { + if (!this.cached_selectTag) { + var selectTag = document.createElement("select"); + var collection = this.options.collection || []; + var optionTag; + collection.each(function(e,i) { + optionTag = document.createElement("option"); + optionTag.value = (e instanceof Array) ? e[0] : e; + if(this.options.value==optionTag.value) optionTag.selected = true; + optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); + selectTag.appendChild(optionTag); + }.bind(this)); + this.cached_selectTag = selectTag; + } + + this.editField = this.cached_selectTag; + if(this.options.loadTextURL) this.loadExternalText(); + this.form.appendChild(this.editField); + this.options.callback = function(form, value) { + return "value=" + encodeURIComponent(value); + } + } +}); + +// Delayed observer, like Form.Element.Observer, +// but waits for delay after last key input +// Ideal for live-search fields + +Form.Element.DelayedObserver = Class.create(); +Form.Element.DelayedObserver.prototype = { + 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/plugins/asset_packager/test/assets/javascripts/dragdrop.js b/vendor/plugins/asset_packager/test/assets/javascripts/dragdrop.js new file mode 100755 index 0000000..a01b7be --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/dragdrop.js @@ -0,0 +1,913 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// +// See scriptaculous.js for full license. + +/*--------------------------------------------------------------------------*/ + +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((typeof containment == 'object') && + (containment.constructor == Array)) { + 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 affected = []; + + if(this.last_active) this.deactivate(this.last_active); + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) + affected.push(drop); + }); + + if(affected.length>0) { + drop = Droppables.findDeepestChild(affected); + Position.within(drop.element, point[0], point[1]); + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + + Droppables.activate(drop); + } + }, + + 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); + }, + + 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) { + 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.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); + }); + }, + + _cacheObserverCallbacks: function() { + ['onStart','onEnd','onDrag'].each( function(eventName) { + Draggables[eventName+'Count'] = Draggables.observers.select( + function(o) { return o[eventName]; } + ).length; + }); + } +} + +/*--------------------------------------------------------------------------*/ + +var Draggable = Class.create(); +Draggable.prototype = { + initialize: function(element) { + var options = Object.extend({ + handle: false, + starteffect: function(element) { + new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7}); + }, + reverteffect: function(element, top_offset, left_offset) { + var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; + element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur}); + }, + endeffect: function(element) { + new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); + }, + zindex: 1000, + revert: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } + }, arguments[1] || {}); + + this.element = $(element); + + if(options.handle && (typeof options.handle == 'string')) { + var h = Element.childrenWithClassName(this.element, options.handle, true); + if(h.length>0) this.handle = h[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); + + Element.makePositioned(this.element); // fix IE + + this.delta = this.currentDelta(); + 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(Event.isLeftClick(event)) { + // abort on form elements, fixes a Firefox issue + var src = Event.element(event); + if(src.tagName && ( + src.tagName=='INPUT' || + src.tagName=='SELECT' || + src.tagName=='OPTION' || + src.tagName=='BUTTON' || + src.tagName=='TEXTAREA')) return; + + if(this.element._revert) { + this.element._revert.cancel(); + this.element._revert = null; + } + + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var pos = Position.cumulativeOffset(this.element); + this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging = true; + + if(this.options.zindex) { + this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + this.element.style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + Position.absolutize(this.element); + this.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); + 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; + p[1] += this.options.scroll.scrollTop; + 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(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + + Event.stop(event); + }, + + finishDrag: function(event, success) { + this.dragging = false; + + if(this.options.ghosting) { + Position.relativize(this.element); + Element.remove(this._clone); + this._clone = null; + } + + if(success) Droppables.fire(event, this.element); + Draggables.notify('onEnd', this, event); + + var revert = this.options.revert; + if(revert && typeof revert == 'function') revert = revert(this.element); + + var d = this.currentDelta(); + if(revert && this.options.reverteffect) { + this.options.reverteffect(this.element, + d[1]-this.delta[1], d[0]-this.delta[0]); + } 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 = Position.cumulativeOffset(this.element); + var d = this.currentDelta(); + pos[0] -= d[0]; pos[1] -= d[1]; + + if(this.options.scroll && (this.options.scroll != window)) { + 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(typeof this.options.snap == 'function') { + p = this.options.snap(p[0],p[1]); + } else { + if(this.options.snap instanceof Array) { + p = p.map( function(v, i) { + return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) + } else { + p = p.map( function(v) { + return Math.round(v/this.options.snap)*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) { + 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); + 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 }; + } +} + +/*--------------------------------------------------------------------------*/ + +var SortableObserver = Class.create(); +SortableObserver.prototype = { + 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 = { + sortables: {}, + + _findRootElement: function(element) { + while (element.tagName != "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){ + var s = Sortable.options(element); + + 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, + hoverclass: null, + ghosting: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: /^[^_]*_(.*)$/, + 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, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, + 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 + //greedy: !options.dropOnEmpty + } + + 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); + } + + (this.findElements(element, options) || []).each( function(e) { + // handles are per-draggable + var handle = options.handle ? + Element.childrenWithClassName(e, 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.id] = 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}); + 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) Element.hide(Sortable._marker); + }, + + 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') || document.createElement('DIV'); + Element.hide(Sortable._marker); + Element.addClassName(Sortable._marker, 'dropmarker'); + Sortable._marker.style.position = 'absolute'; + document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); + } + var offsets = Position.cumulativeOffset(dropon); + Sortable._marker.style.left = offsets[0] + 'px'; + Sortable._marker.style.top = offsets[1] + 'px'; + + if(position=='after') + if(sortable.overlap == 'horizontal') + Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; + else + Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; + + Element.show(Sortable._marker); + }, + + _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: new Array, + position: parent.children.length, + container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) + } + + /* 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; + }, + + /* Finds the first element of the given tag type within a parent element. + Used for finding the first LI[ST] within a L[IST]I[TEM].*/ + _findChildrenElement: function (element, containerTag) { + if (element && element.hasChildNodes) + for (var i = 0; i < element.childNodes.length; ++i) + if (element.childNodes[i].tagName == containerTag) + return element.childNodes[i]; + + return null; + }, + + 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: new Array, + 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) + "=" + + 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) { + if (type == 'vertical' || type == 'height') + return element.offsetHeight; + else + return element.offsetWidth; +} \ No newline at end of file diff --git a/vendor/plugins/asset_packager/test/assets/javascripts/effects.js b/vendor/plugins/asset_packager/test/assets/javascripts/effects.js new file mode 100755 index 0000000..9274005 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/effects.js @@ -0,0 +1,958 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// See scriptaculous.js for full license. + +// 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(element, {fontSize: (percent/100) + 'em'}); + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); +} + +Element.getOpacity = function(element){ + var opacity; + if (opacity = Element.getStyle(element, 'opacity')) + return parseFloat(opacity); + if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) + if(opacity[1]) return parseFloat(opacity[1]) / 100; + return 1.0; +} + +Element.setOpacity = function(element, value){ + element= $(element); + if (value == 1){ + Element.setStyle(element, { opacity: + (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? + 0.999999 : null }); + if(/MSIE/.test(navigator.userAgent)) + Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); + } else { + if(value < 0.00001) value = 0; + Element.setStyle(element, {opacity: value}); + if(/MSIE/.test(navigator.userAgent)) + Element.setStyle(element, + { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + + 'alpha(opacity='+value*100+')' }); + } +} + +Element.getInlineOpacity = function(element){ + return $(element).style.opacity || ''; +} + +Element.childrenWithClassName = function(element, className, findFirst) { + var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)"); + var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { + return (c.className && c.className.match(classNameRegExp)); + }); + if(!results) results = []; + return results; +} + +Element.forceRerendering = function(element) { + try { + element = $(element); + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + +/*--------------------------------------------------------------------------*/ + +Array.prototype.call = function() { + var args = arguments; + this.each(function(f){ f.apply(this, args) }); +} + +/*--------------------------------------------------------------------------*/ + +var Effect = { + tagifyText: function(element) { + var tagifyStyle = 'position:relative'; + if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; + element = $(element); + $A(element.childNodes).each( function(child) { + if(child.nodeType==3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + Builder.node('span',{style: tagifyStyle}, + character == ' ' ? String.fromCharCode(160) : character), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if(((typeof element == 'object') || + (typeof element == 'function')) && + (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) { + element = $(element); + effect = (effect || 'appear').toLowerCase(); + var options = Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 } + }, arguments[2] || {}); + Effect[element.visible() ? + Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); + } +}; + +var Effect2 = Effect; // deprecated + +/* ------------- transitions ------------- */ + +Effect.Transitions = {} + +Effect.Transitions.linear = function(pos) { + return pos; +} +Effect.Transitions.sinoidal = function(pos) { + return (-Math.cos(pos*Math.PI)/2) + 0.5; +} +Effect.Transitions.reverse = function(pos) { + return 1-pos; +} +Effect.Transitions.flicker = function(pos) { + return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; +} +Effect.Transitions.wobble = function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; +} +Effect.Transitions.pulse = function(pos) { + return (Math.floor(pos*10) % 2 == 0 ? + (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); +} +Effect.Transitions.none = function(pos) { + return 0; +} +Effect.Transitions.full = function(pos) { + return 1; +} + +/* ------------- core effects ------------- */ + +Effect.ScopedQueue = Class.create(); +Object.extend(Object.extend(Effect.ScopedQueue.prototype, 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 = (typeof effect.options.queue == 'string') ? + 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 '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), 40); + }, + 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(); + this.effects.invoke('loop', timePos); + } +}); + +Effect.Queues = { + instances: $H(), + get: function(queueName) { + if(typeof queueName != 'string') return queueName; + + if(!this.instances[queueName]) + this.instances[queueName] = new Effect.ScopedQueue(); + + return this.instances[queueName]; + } +} +Effect.Queue = Effect.Queues.get('global'); + +Effect.DefaultOptions = { + transition: Effect.Transitions.sinoidal, + duration: 1.0, // seconds + fps: 25.0, // max. 25fps due to Effect.Queue implementation + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' +} + +Effect.Base = function() {}; +Effect.Base.prototype = { + position: null, + start: function(options) { + this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); + this.currentFrame = 0; + this.state = 'idle'; + this.startOn = this.options.delay*1000; + this.finishOn = this.startOn + (this.options.duration*1000); + this.event('beforeStart'); + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).add(this); + }, + loop: function(timePos) { + if(timePos >= 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.finishOn - this.startOn); + var frame = Math.round(pos * this.options.fps * this.options.duration); + if(frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + } + }, + render: function(pos) { + if(this.state == 'idle') { + this.state = 'running'; + this.event('beforeSetup'); + if(this.setup) this.setup(); + this.event('afterSetup'); + } + if(this.state == 'running') { + if(this.options.transition) pos = this.options.transition(pos); + pos *= (this.options.to-this.options.from); + pos += this.options.from; + this.position = pos; + this.event('beforeUpdate'); + if(this.update) this.update(pos); + this.event('afterUpdate'); + } + }, + cancel: function() { + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + '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() { + return '#'; + } +} + +Effect.Parallel = Class.create(); +Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { + 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.Opacity = Class.create(); +Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + // make this work on IE on elements without 'layout' + if(/MSIE/.test(navigator.userAgent) && (!this.element.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(); +Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + var options = Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || {}); + this.start(options); + }, + setup: function() { + // Bug in Opera: Opera returns the "real" position of a static element or + // relative element that does not have top/left explicitly set. + // ==> Always set top and left for position relative elements in your stylesheets + // (to 0 if you do not need them) + this.element.makePositioned(); + this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); + this.originalTop = parseFloat(this.element.getStyle('top') || '0'); + if(this.options.mode == 'absolute') { + // absolute movement, so we need to calc deltaX and deltaY + 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 + 'px', + top: this.options.y * position + this.originalTop + '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(); +Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { + initialize: function(element, percent) { + this.element = $(element) + 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','%'].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 + 'px'; + if(this.options.scaleY) d.height = height + '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(); +Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + 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 = { + 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+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); + }, + finish: function() { + this.element.setStyle(Object.extend(this.oldStyle, { + backgroundColor: this.options.restorecolor + })); + } +}); + +Effect.ScrollTo = Class.create(); +Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + this.start(arguments[1] || {}); + }, + setup: function() { + Position.prepare(); + var offsets = Position.cumulativeOffset(this.element); + if(this.options.offset) offsets[1] += this.options.offset; + var max = window.innerHeight ? + window.height - window.innerHeight : + document.body.scrollHeight - + (document.documentElement.clientHeight ? + document.documentElement.clientHeight : document.body.clientHeight); + this.scrollStart = Position.deltaY; + this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; + }, + update: function(position) { + Position.prepare(); + window.scrollTo(Position.deltaX, + this.scrollStart + (position*this.delta)); + } +}); + +/* ------------- 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(); + effect.element.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); + effect.element.show(); + }}, arguments[1] || {}); + return new Effect.Opacity(element,options); +} + +Effect.Puff = function(element) { + element = $(element); + var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') }; + 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) { + effect.effects[0].element.setStyle({position: 'absolute'}); }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide(); + effect.effects[0].element.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(); + effect.element.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(); + effect.element.setStyle({height: '0px'}); + effect.element.show(); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + } + }, arguments[1] || {}) + ); +} + +Effect.SwitchOff = function(element) { + element = $(element); + var oldOpacity = element.getInlineOpacity(); + return new Effect.Appear(element, { + 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(); + effect.element.makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide(); + effect.element.undoClipping(); + effect.element.undoPositioned(); + effect.element.setStyle({opacity: oldOpacity}); + } + }) + } + }); +} + +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(); + effect.effects[0].element.undoPositioned(); + effect.effects[0].element.setStyle(oldStyle); + } + }, arguments[1] || {})); +} + +Effect.Shake = function(element) { + element = $(element); + var oldStyle = { + top: element.getStyle('top'), + left: element.getStyle('left') }; + return new Effect.Move(element, + { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { + effect.element.undoPositioned(); + effect.element.setStyle(oldStyle); + }}) }}) }}) }}) }}) }}); +} + +Effect.SlideDown = function(element) { + element = $(element); + element.cleanWhitespace(); + // SlideDown need to have the content of the element wrapped in a container element with fixed height! + var oldInnerBottom = $(element.firstChild).getStyle('bottom'); + 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.makePositioned(); + effect.element.firstChild.makePositioned(); + if(window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping(); + effect.element.setStyle({height: '0px'}); + effect.element.show(); }, + afterUpdateInternal: function(effect) { + effect.element.firstChild.setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + // IE will crash if child is undoPositioned first + if(/MSIE/.test(navigator.userAgent)){ + effect.element.undoPositioned(); + effect.element.firstChild.undoPositioned(); + }else{ + effect.element.firstChild.undoPositioned(); + effect.element.undoPositioned(); + } + effect.element.firstChild.setStyle({bottom: oldInnerBottom}); } + }, arguments[1] || {}) + ); +} + +Effect.SlideUp = function(element) { + element = $(element); + element.cleanWhitespace(); + var oldInnerBottom = $(element.firstChild).getStyle('bottom'); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + scaleMode: 'box', + scaleFrom: 100, + restoreAfterFinish: true, + beforeStartInternal: function(effect) { + effect.element.makePositioned(); + effect.element.firstChild.makePositioned(); + if(window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping(); + effect.element.show(); }, + afterUpdateInternal: function(effect) { + effect.element.firstChild.setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); }, + afterFinishInternal: function(effect) { + effect.element.hide(); + effect.element.undoClipping(); + effect.element.firstChild.undoPositioned(); + effect.element.undoPositioned(); + effect.element.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(effect.element); }, + afterFinishInternal: function(effect) { + effect.element.hide(effect.element); + effect.element.undoClipping(effect.element); } + }); +} + +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(); + effect.element.makeClipping(); + effect.element.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'}); + effect.effects[0].element.show(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.undoClipping(); + effect.effects[0].element.undoPositioned(); + effect.effects[0].element.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(); + effect.effects[0].element.makeClipping(); }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide(); + effect.effects[0].element.undoClipping(); + effect.effects[0].element.undoPositioned(); + effect.effects[0].element.setStyle(oldStyle); } + }, options) + ); +} + +Effect.Pulsate = function(element) { + element = $(element); + var options = arguments[1] || {}; + var oldOpacity = element.getInlineOpacity(); + var transition = options.transition || Effect.Transitions.sinoidal; + var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; + reverser.bind(transition); + return new Effect.Opacity(element, + Object.extend(Object.extend({ duration: 3.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(element); + 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(); + effect.element.undoClipping(); + effect.element.setStyle(oldStyle); + } }); + }}, arguments[1] || {})); +}; + +['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', + 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( + function(f) { Element.Methods[f] = Element[f]; } +); + +Element.Methods.visualEffect = function(element, effect, options) { + s = effect.gsub(/_/, '-').camelize(); + effect_class = s.charAt(0).toUpperCase() + s.substring(1); + new Effect[effect_class](element, options); + return $(element); +}; + +Element.addMethods(); \ No newline at end of file diff --git a/vendor/plugins/asset_packager/test/assets/javascripts/foo.js b/vendor/plugins/asset_packager/test/assets/javascripts/foo.js new file mode 100755 index 0000000..7e4cd9a --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/foo.js @@ -0,0 +1,4 @@ +foo foo foo +foo foo foo +foo foo foo + diff --git a/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js b/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js new file mode 100755 index 0000000..0caf9cd --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js @@ -0,0 +1,2006 @@ +/* Prototype JavaScript framework, version 1.5.0_rc0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.0_rc0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + } +} +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += (replacement(match) || '').toString(); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + (object[match[3]] || '').toString(); + }); + } +} + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +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(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + 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 = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version, + 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', this.options.contentType); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval('(' + this.header('X-JSON') + ')'); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + 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.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $() { + var results = [], element; + for (var i = 0; i < arguments.length; i++) { + element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + results.push(Element.extend(element)); + } + return results.length < 2 ? results[0] : results; +} + +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(Element.extend(child)); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) + var Element = new Object(); + +Element.extend = function(element) { + if (!element) return; + if (_nativeExtensions) return element; + + if (!element._extended && element.tagName && element != window) { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + element[property] = cache.findOrStore(value); + } + } + + element._extended = true; + return element; +} + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +} + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + replace: function(element, html) { + element = $(element); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + childOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (var name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + 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 = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +} + +Object.extend(Element, Element.Methods); + +var _nativeExtensions = false; + +if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + var HTMLElement = {} + HTMLElement.prototype = document.createElement('div').__proto__; +} + +Element.addMethods = function(methods) { + Object.extend(Element.Methods, methods || {}); + + if(typeof HTMLElement != 'undefined') { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + HTMLElement.prototype[property] = cache.findOrStore(value); + } + _nativeExtensions = true; + } +} + +Element.addMethods(); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + var tagName = this.element.tagName.toLowerCase(); + if (tagName == 'tbody' || tagName == 'tr') { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
                        '; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +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(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Selector = Class.create(); +Selector.prototype = { + initialize: function(expression) { + this.params = {classNames: []}; + this.expression = expression.toString().strip(); + this.parseExpression(); + this.compileMatcher(); + }, + + parseExpression: function() { + function abort(message) { throw 'Parse error in selector: ' + message; } + + if (this.expression == '') abort('empty expression'); + + var params = this.params, expr = this.expression, match, modifier, clause, rest; + while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { + params.attributes = params.attributes || []; + params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); + expr = match[1]; + } + + if (expr == '*') return this.params.wildcard = true; + + while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { + modifier = match[1], clause = match[2], rest = match[3]; + switch (modifier) { + case '#': params.id = clause; break; + case '.': params.classNames.push(clause); break; + case '': + case undefined: params.tagName = clause.toUpperCase(); break; + default: abort(expr.inspect()); + } + expr = rest; + } + + if (expr.length > 0) abort(expr.inspect()); + }, + + buildMatchExpression: function() { + var params = this.params, conditions = [], clause; + + if (params.wildcard) + conditions.push('true'); + if (clause = params.id) + conditions.push('element.id == ' + clause.inspect()); + if (clause = params.tagName) + conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); + if ((clause = params.classNames).length > 0) + for (var i = 0; i < clause.length; i++) + conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')'); + if (clause = params.attributes) { + clause.each(function(attribute) { + var value = 'element.getAttribute(' + attribute.name.inspect() + ')'; + var splitValueBy = function(delimiter) { + return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; + } + + switch (attribute.operator) { + case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; + case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; + case '|=': conditions.push( + splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() + ); break; + case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; + case '': + case undefined: conditions.push(value + ' != null'); break; + default: throw 'Unknown operator ' + attribute.operator + ' in selector'; + } + }); + } + + return conditions.join(' && '); + }, + + compileMatcher: function() { + this.match = new Function('element', 'if (!element.tagName) return false; \ + return ' + this.buildMatchExpression()); + }, + + findElements: function(scope) { + var element; + + if (element = $(this.params.id)) + if (this.match(element)) + if (!scope || Element.childOf(element, scope)) + return [element]; + + scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); + + var results = []; + for (var i = 0; i < scope.length; i++) + if (this.match(element = scope[i])) + results.push(Element.extend(element)); + + return results; + }, + + toString: function() { + return this.expression; + } +} + +function $$() { + return $A(arguments).map(function(expression) { + return expression.strip().split(/\s+/).inject([null], function(results, expr) { + var selector = new Selector(expr); + return results.map(selector.findElements.bind(selector)).flatten(); + }); + }).flatten(); +} +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + element = $(element); + element.focus(); + if (element.select) + element.select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (var tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) + return inputs; + + var matchingInputs = new Array(); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || + (name && input.name != name)) + continue; + matchingInputs.push(input); + } + + return matchingInputs; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disabled = 'true'; + } + }, + + enable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.disabled = ''; + } + }, + + findFirstElement: function(form) { + return Form.getElements(form).find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + Field.activate(Form.findFirstElement(form)); + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) { + var key = encodeURIComponent(parameter[0]); + if (key.length == 0) return; + + if (parameter[1].constructor != Array) + parameter[1] = [parameter[1]]; + + return parameter[1].map(function(value) { + return key + '=' + encodeURIComponent(value); + }).join('&'); + } + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'submit': + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + return Form.Element.Serializers[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var value = '', opt, index = element.selectedIndex; + if (index >= 0) { + opt = element.options[index]; + value = opt.value || opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = []; + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) + value.push(opt.value || opt.text); + } + return [element.name, value]; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + 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() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(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, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +if (navigator.appVersion.match(/\bMSIE\b/)) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + 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 = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.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); + }, + + // within must be called directly before + 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; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._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';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} \ No newline at end of file diff --git a/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css b/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css new file mode 100644 index 0000000..6f56128 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css @@ -0,0 +1,16 @@ +#bar1 { + background: #fff; + color: #000; + text-align: center; +} +#bar2 { + background: #fff; + color: #000; + text-align: center; +} +#bar3 { + background: #fff; + color: #000; + text-align: center; +} + diff --git a/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css b/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css new file mode 100644 index 0000000..66941f9 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css @@ -0,0 +1,16 @@ +#foo1 { + background: #fff; + color: #000; + text-align: center; +} +#foo2 { + background: #fff; + color: #000; + text-align: center; +} +#foo3 { + background: #fff; + color: #000; + text-align: center; +} + diff --git a/vendor/plugins/asset_packager/test/assets/stylesheets/header.css b/vendor/plugins/asset_packager/test/assets/stylesheets/header.css new file mode 100755 index 0000000..473902e --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/stylesheets/header.css @@ -0,0 +1,16 @@ +#header1 { + background: #fff; + color: #000; + text-align: center; +} +#header2 { + background: #fff; + color: #000; + text-align: center; +} +#header3 { + background: #fff; + color: #000; + text-align: center; +} + diff --git a/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css b/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css new file mode 100755 index 0000000..0d66fd4 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css @@ -0,0 +1,16 @@ +#screen1 { + background: #fff; + color: #000; + text-align: center; +} +#screen2 { + background: #fff; + color: #000; + text-align: center; +} +#screen3 { + background: #fff; + color: #000; + text-align: center; +} + diff --git a/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css b/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css new file mode 100644 index 0000000..6f56128 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css @@ -0,0 +1,16 @@ +#bar1 { + background: #fff; + color: #000; + text-align: center; +} +#bar2 { + background: #fff; + color: #000; + text-align: center; +} +#bar3 { + background: #fff; + color: #000; + text-align: center; +} + diff --git a/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css b/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css new file mode 100644 index 0000000..66941f9 --- /dev/null +++ b/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css @@ -0,0 +1,16 @@ +#foo1 { + background: #fff; + color: #000; + text-align: center; +} +#foo2 { + background: #fff; + color: #000; + text-align: center; +} +#foo3 { + background: #fff; + color: #000; + text-align: center; +} +