Skip to content
This repository
Browse code

initial commit

  • Loading branch information...
commit 8beecf3590879d2c15334263d3e26511e9bb1fd1 0 parents
Daniel Kehoe authored January 30, 2010

Showing 43 changed files with 8,273 additions and 0 deletions. Show diff stats Hide diff stats

  1. 6  .gitignore
  2. 71  README
  3. 10  Rakefile
  4. 10  app/controllers/application_controller.rb
  5. 3  app/helpers/application_helper.rb
  6. 110  config/boot.rb
  7. 41  config/environment.rb
  8. 17  config/environments/development.rb
  9. 28  config/environments/production.rb
  10. 28  config/environments/test.rb
  11. 7  config/initializers/backtrace_silencers.rb
  12. 10  config/initializers/inflections.rb
  13. 5  config/initializers/mime_types.rb
  14. 21  config/initializers/new_rails_defaults.rb
  15. 15  config/initializers/session_store.rb
  16. 5  config/locales/en.yml
  17. 43  config/routes.rb
  18. 7  db/seeds.rb
  19. 2  doc/README_FOR_APP
  20. 30  public/404.html
  21. 30  public/422.html
  22. 30  public/500.html
  23. 0  public/favicon.ico
  24. BIN  public/images/rails.png
  25. 275  public/index.html
  26. 2  public/javascripts/application.js
  27. 963  public/javascripts/controls.js
  28. 973  public/javascripts/dragdrop.js
  29. 1,128  public/javascripts/effects.js
  30. 4,320  public/javascripts/prototype.js
  31. 5  public/robots.txt
  32. 4  script/about
  33. 3  script/console
  34. 3  script/dbconsole
  35. 3  script/destroy
  36. 3  script/generate
  37. 3  script/performance/benchmarker
  38. 3  script/performance/profiler
  39. 3  script/plugin
  40. 3  script/runner
  41. 3  script/server
  42. 9  test/performance/browsing_test.rb
  43. 38  test/test_helper.rb
6  .gitignore
... ...
@@ -0,0 +1,6 @@
  1
+.DS_Store
  2
+log/*.log
  3
+tmp/**/*
  4
+config/database.yml
  5
+config/initializers/site_keys.rb
  6
+db/*.sqlite3
71  README
... ...
@@ -0,0 +1,71 @@
  1
+Subdomain-Authentication
  2
+
  3
+This is a Ruby on Rails web application that uses subdomains and provides user management and authentication. 
  4
+
  5
+Tutorial (Walkthrough)
  6
+
  7
+Each step that you must follow to create this application is documented here.
  8
+
  9
+Assumptions
  10
+
  11
+This tutorial is based on Rails 2.3. Some of the code shown here will not work in older versions of Rails. 
  12
+
  13
+This was written before the release of Rails 3.0. Things will change significantly in Rails 3.0 so this tutorial will be outdated when Rails 3.0 is released.
  14
+
  15
+Before beginning this tutorial, you need to install 
  16
+
  17
+* The Ruby language ruby (version 1.8.7 or newer)
  18
+* The RubyGems packaging system (version 1.3.5 or newer)
  19
+* A working installation of SQLite (preferred), MySQL, or PostgreSQL
  20
+* Rails (version 2.3 or newer)
  21
+
  22
+Check that current versions are installed on your computer:
  23
+
  24
+ruby -v
  25
+gem -v
  26
+rails -v
  27
+
  28
+You should have experience building a simple Rails application. Refer to http://guides.rubyonrails.org/ (Rails Guides) for help if you are a beginner.
  29
+
  30
+Create the Rails Application
  31
+
  32
+Open a terminal, navigate to a folder where you have rights to create files, and type:
  33
+
  34
+$ rails subdomain-authentication
  35
+
  36
+You may give the app a different name if you are building it for your own use. For this tutorial, we'll assume the name is "subdomain-authentication."
  37
+
  38
+This will create a Rails application that uses a SQLite database for data storage. You may also use MySQL or PostgreSQL for data storage (refer to http://guides.rubyonrails.org/getting_started.html (Getting Started with Rails)).
  39
+
  40
+After you create the application, switch to its folder to continue work directly in that application:
  41
+
  42
+$ cd subdomain-authentication
  43
+
  44
+Edit the README file to remove the standard Rails boilerplate. Add what you like (at least the name of the app).
  45
+
  46
+Set Up Source Control (Git)
  47
+
  48
+If you're creating an app for deployment into production, you'll want to set up a source control repository at this point. If you are building a throw-away app for your own education, you may skip this step.
  49
+
  50
+Check that git is installed on your computer:
  51
+
  52
+git version
  53
+
  54
+Check that your GitHub account is set up properly:
  55
+
  56
+ssh git@github.com
  57
+
  58
+Create a top, project-level .gitignore file containing:
  59
+
  60
+.DS_Store
  61
+log/*.log
  62
+tmp/**/*
  63
+config/database.yml
  64
+config/initializers/site_keys.rb
  65
+db/*.sqlite3
  66
+
  67
+Initialize git and check in your first commit:
  68
+
  69
+git init
  70
+git add .
  71
+git commit -m 'initial commit'
10  Rakefile
... ...
@@ -0,0 +1,10 @@
  1
+# Add your own tasks in files placed in lib/tasks ending in .rake,
  2
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
  3
+
  4
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
  5
+
  6
+require 'rake'
  7
+require 'rake/testtask'
  8
+require 'rake/rdoctask'
  9
+
  10
+require 'tasks/rails'
10  app/controllers/application_controller.rb
... ...
@@ -0,0 +1,10 @@
  1
+# Filters added to this controller apply to all controllers in the application.
  2
+# Likewise, all the methods added will be available for all controllers.
  3
+
  4
+class ApplicationController < ActionController::Base
  5
+  helper :all # include all helpers, all the time
  6
+  protect_from_forgery # See ActionController::RequestForgeryProtection for details
  7
+
  8
+  # Scrub sensitive parameters from your log
  9
+  # filter_parameter_logging :password
  10
+end
3  app/helpers/application_helper.rb
... ...
@@ -0,0 +1,3 @@
  1
+# Methods added to this helper will be available to all templates in the application.
  2
+module ApplicationHelper
  3
+end
110  config/boot.rb
... ...
@@ -0,0 +1,110 @@
  1
+# Don't change this file!
  2
+# Configure your app in config/environment.rb and config/environments/*.rb
  3
+
  4
+RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
  5
+
  6
+module Rails
  7
+  class << self
  8
+    def boot!
  9
+      unless booted?
  10
+        preinitialize
  11
+        pick_boot.run
  12
+      end
  13
+    end
  14
+
  15
+    def booted?
  16
+      defined? Rails::Initializer
  17
+    end
  18
+
  19
+    def pick_boot
  20
+      (vendor_rails? ? VendorBoot : GemBoot).new
  21
+    end
  22
+
  23
+    def vendor_rails?
  24
+      File.exist?("#{RAILS_ROOT}/vendor/rails")
  25
+    end
  26
+
  27
+    def preinitialize
  28
+      load(preinitializer_path) if File.exist?(preinitializer_path)
  29
+    end
  30
+
  31
+    def preinitializer_path
  32
+      "#{RAILS_ROOT}/config/preinitializer.rb"
  33
+    end
  34
+  end
  35
+
  36
+  class Boot
  37
+    def run
  38
+      load_initializer
  39
+      Rails::Initializer.run(:set_load_path)
  40
+    end
  41
+  end
  42
+
  43
+  class VendorBoot < Boot
  44
+    def load_initializer
  45
+      require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
  46
+      Rails::Initializer.run(:install_gem_spec_stubs)
  47
+      Rails::GemDependency.add_frozen_gem_path
  48
+    end
  49
+  end
  50
+
  51
+  class GemBoot < Boot
  52
+    def load_initializer
  53
+      self.class.load_rubygems
  54
+      load_rails_gem
  55
+      require 'initializer'
  56
+    end
  57
+
  58
+    def load_rails_gem
  59
+      if version = self.class.gem_version
  60
+        gem 'rails', version
  61
+      else
  62
+        gem 'rails'
  63
+      end
  64
+    rescue Gem::LoadError => load_error
  65
+      $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.)
  66
+      exit 1
  67
+    end
  68
+
  69
+    class << self
  70
+      def rubygems_version
  71
+        Gem::RubyGemsVersion rescue nil
  72
+      end
  73
+
  74
+      def gem_version
  75
+        if defined? RAILS_GEM_VERSION
  76
+          RAILS_GEM_VERSION
  77
+        elsif ENV.include?('RAILS_GEM_VERSION')
  78
+          ENV['RAILS_GEM_VERSION']
  79
+        else
  80
+          parse_gem_version(read_environment_rb)
  81
+        end
  82
+      end
  83
+
  84
+      def load_rubygems
  85
+        min_version = '1.3.2'
  86
+        require 'rubygems'
  87
+        unless rubygems_version >= min_version
  88
+          $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
  89
+          exit 1
  90
+        end
  91
+
  92
+      rescue LoadError
  93
+        $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
  94
+        exit 1
  95
+      end
  96
+
  97
+      def parse_gem_version(text)
  98
+        $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
  99
+      end
  100
+
  101
+      private
  102
+        def read_environment_rb
  103
+          File.read("#{RAILS_ROOT}/config/environment.rb")
  104
+        end
  105
+    end
  106
+  end
  107
+end
  108
+
  109
+# All that for this:
  110
+Rails.boot!
41  config/environment.rb
... ...
@@ -0,0 +1,41 @@
  1
+# Be sure to restart your server when you modify this file
  2
+
  3
+# Specifies gem version of Rails to use when vendor/rails is not present
  4
+RAILS_GEM_VERSION = '2.3.4' unless defined? RAILS_GEM_VERSION
  5
+
  6
+# Bootstrap the Rails environment, frameworks, and default configuration
  7
+require File.join(File.dirname(__FILE__), 'boot')
  8
+
  9
+Rails::Initializer.run do |config|
  10
+  # Settings in config/environments/* take precedence over those specified here.
  11
+  # Application configuration should go into files in config/initializers
  12
+  # -- all .rb files in that directory are automatically loaded.
  13
+
  14
+  # Add additional load paths for your own custom dirs
  15
+  # config.load_paths += %W( #{RAILS_ROOT}/extras )
  16
+
  17
+  # Specify gems that this application depends on and have them installed with rake gems:install
  18
+  # config.gem "bj"
  19
+  # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
  20
+  # config.gem "sqlite3-ruby", :lib => "sqlite3"
  21
+  # config.gem "aws-s3", :lib => "aws/s3"
  22
+
  23
+  # Only load the plugins named here, in the order given (default is alphabetical).
  24
+  # :all can be used as a placeholder for all plugins not explicitly named
  25
+  # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
  26
+
  27
+  # Skip frameworks you're not going to use. To use Rails without a database,
  28
+  # you must remove the Active Record framework.
  29
+  # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
  30
+
  31
+  # Activate observers that should always be running
  32
+  # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
  33
+
  34
+  # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
  35
+  # Run "rake -D time" for a list of tasks for finding time zone names.
  36
+  config.time_zone = 'UTC'
  37
+
  38
+  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
  39
+  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
  40
+  # config.i18n.default_locale = :de
  41
+end
17  config/environments/development.rb
... ...
@@ -0,0 +1,17 @@
  1
+# Settings specified here will take precedence over those in config/environment.rb
  2
+
  3
+# In the development environment your application's code is reloaded on
  4
+# every request.  This slows down response time but is perfect for development
  5
+# since you don't have to restart the webserver when you make code changes.
  6
+config.cache_classes = false
  7
+
  8
+# Log error messages when you accidentally call methods on nil.
  9
+config.whiny_nils = true
  10
+
  11
+# Show full error reports and disable caching
  12
+config.action_controller.consider_all_requests_local = true
  13
+config.action_view.debug_rjs                         = true
  14
+config.action_controller.perform_caching             = false
  15
+
  16
+# Don't care if the mailer can't send
  17
+config.action_mailer.raise_delivery_errors = false
28  config/environments/production.rb
... ...
@@ -0,0 +1,28 @@
  1
+# Settings specified here will take precedence over those in config/environment.rb
  2
+
  3
+# The production environment is meant for finished, "live" apps.
  4
+# Code is not reloaded between requests
  5
+config.cache_classes = true
  6
+
  7
+# Full error reports are disabled and caching is turned on
  8
+config.action_controller.consider_all_requests_local = false
  9
+config.action_controller.perform_caching             = true
  10
+config.action_view.cache_template_loading            = true
  11
+
  12
+# See everything in the log (default is :info)
  13
+# config.log_level = :debug
  14
+
  15
+# Use a different logger for distributed setups
  16
+# config.logger = SyslogLogger.new
  17
+
  18
+# Use a different cache store in production
  19
+# config.cache_store = :mem_cache_store
  20
+
  21
+# Enable serving of images, stylesheets, and javascripts from an asset server
  22
+# config.action_controller.asset_host = "http://assets.example.com"
  23
+
  24
+# Disable delivery errors, bad email addresses will be ignored
  25
+# config.action_mailer.raise_delivery_errors = false
  26
+
  27
+# Enable threaded mode
  28
+# config.threadsafe!
28  config/environments/test.rb
... ...
@@ -0,0 +1,28 @@
  1
+# Settings specified here will take precedence over those in config/environment.rb
  2
+
  3
+# The test environment is used exclusively to run your application's
  4
+# test suite.  You never need to work with it otherwise.  Remember that
  5
+# your test database is "scratch space" for the test suite and is wiped
  6
+# and recreated between test runs.  Don't rely on the data there!
  7
+config.cache_classes = true
  8
+
  9
+# Log error messages when you accidentally call methods on nil.
  10
+config.whiny_nils = true
  11
+
  12
+# Show full error reports and disable caching
  13
+config.action_controller.consider_all_requests_local = true
  14
+config.action_controller.perform_caching             = false
  15
+config.action_view.cache_template_loading            = true
  16
+
  17
+# Disable request forgery protection in test environment
  18
+config.action_controller.allow_forgery_protection    = false
  19
+
  20
+# Tell Action Mailer not to deliver emails to the real world.
  21
+# The :test delivery method accumulates sent emails in the
  22
+# ActionMailer::Base.deliveries array.
  23
+config.action_mailer.delivery_method = :test
  24
+
  25
+# Use SQL instead of Active Record's schema dumper when creating the test database.
  26
+# This is necessary if your schema can't be completely dumped by the schema dumper,
  27
+# like if you have constraints or database-specific column types
  28
+# config.active_record.schema_format = :sql
7  config/initializers/backtrace_silencers.rb
... ...
@@ -0,0 +1,7 @@
  1
+# Be sure to restart your server when you modify this file.
  2
+
  3
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
  4
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
  5
+
  6
+# You can also remove all the silencers if you're trying do debug a problem that might steem from framework code.
  7
+# Rails.backtrace_cleaner.remove_silencers!
10  config/initializers/inflections.rb
... ...
@@ -0,0 +1,10 @@
  1
+# Be sure to restart your server when you modify this file.
  2
+
  3
+# Add new inflection rules using the following format 
  4
+# (all these examples are active by default):
  5
+# ActiveSupport::Inflector.inflections do |inflect|
  6
+#   inflect.plural /^(ox)$/i, '\1en'
  7
+#   inflect.singular /^(ox)en/i, '\1'
  8
+#   inflect.irregular 'person', 'people'
  9
+#   inflect.uncountable %w( fish sheep )
  10
+# end
5  config/initializers/mime_types.rb
... ...
@@ -0,0 +1,5 @@
  1
+# Be sure to restart your server when you modify this file.
  2
+
  3
+# Add new mime types for use in respond_to blocks:
  4
+# Mime::Type.register "text/richtext", :rtf
  5
+# Mime::Type.register_alias "text/html", :iphone
21  config/initializers/new_rails_defaults.rb
... ...
@@ -0,0 +1,21 @@
  1
+# Be sure to restart your server when you modify this file.
  2
+
  3
+# These settings change the behavior of Rails 2 apps and will be defaults
  4
+# for Rails 3. You can remove this initializer when Rails 3 is released.
  5
+
  6
+if defined?(ActiveRecord)
  7
+  # Include Active Record class name as root for JSON serialized output.
  8
+  ActiveRecord::Base.include_root_in_json = true
  9
+
  10
+  # Store the full class name (including module namespace) in STI type column.
  11
+  ActiveRecord::Base.store_full_sti_class = true
  12
+end
  13
+
  14
+ActionController::Routing.generate_best_match = false
  15
+
  16
+# Use ISO 8601 format for JSON serialized times and dates.
  17
+ActiveSupport.use_standard_json_time_format = true
  18
+
  19
+# Don't escape HTML entities in JSON, leave that for the #json_escape helper.
  20
+# if you're including raw json in an HTML page.
  21
+ActiveSupport.escape_html_entities_in_json = false
15  config/initializers/session_store.rb
... ...
@@ -0,0 +1,15 @@
  1
+# Be sure to restart your server when you modify this file.
  2
+
  3
+# Your secret key for verifying cookie session data integrity.
  4
+# If you change this key, all old sessions will become invalid!
  5
+# Make sure the secret is at least 30 characters and all random, 
  6
+# no regular words or you'll be exposed to dictionary attacks.
  7
+ActionController::Base.session = {
  8
+  :key         => '_subdomain-authentication_session',
  9
+  :secret      => 'c079a73fd074e66cc72b2bd4519316d47a3c736d1ae398598d9e42f7ce4fac13e0d77c50cd84f2058c9915bc93840a2f91a48aa3e8e8c929e657d64babd106f2'
  10
+}
  11
+
  12
+# Use the database for sessions instead of the cookie-based default,
  13
+# which shouldn't be used to store highly confidential information
  14
+# (create the session table with "rake db:sessions:create")
  15
+# ActionController::Base.session_store = :active_record_store
5  config/locales/en.yml
... ...
@@ -0,0 +1,5 @@
  1
+# Sample localization file for English. Add more files in this directory for other locales.
  2
+# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
  3
+
  4
+en:
  5
+  hello: "Hello world"
43  config/routes.rb
... ...
@@ -0,0 +1,43 @@
  1
+ActionController::Routing::Routes.draw do |map|
  2
+  # The priority is based upon order of creation: first created -> highest priority.
  3
+
  4
+  # Sample of regular route:
  5
+  #   map.connect 'products/:id', :controller => 'catalog', :action => 'view'
  6
+  # Keep in mind you can assign values other than :controller and :action
  7
+
  8
+  # Sample of named route:
  9
+  #   map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
  10
+  # This route can be invoked with purchase_url(:id => product.id)
  11
+
  12
+  # Sample resource route (maps HTTP verbs to controller actions automatically):
  13
+  #   map.resources :products
  14
+
  15
+  # Sample resource route with options:
  16
+  #   map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
  17
+
  18
+  # Sample resource route with sub-resources:
  19
+  #   map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
  20
+  
  21
+  # Sample resource route with more complex sub-resources
  22
+  #   map.resources :products do |products|
  23
+  #     products.resources :comments
  24
+  #     products.resources :sales, :collection => { :recent => :get }
  25
+  #   end
  26
+
  27
+  # Sample resource route within a namespace:
  28
+  #   map.namespace :admin do |admin|
  29
+  #     # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
  30
+  #     admin.resources :products
  31
+  #   end
  32
+
  33
+  # You can have the root of your site routed with map.root -- just remember to delete public/index.html.
  34
+  # map.root :controller => "welcome"
  35
+
  36
+  # See how all your routes lay out with "rake routes"
  37
+
  38
+  # Install the default routes as the lowest priority.
  39
+  # Note: These default routes make all actions in every controller accessible via GET requests. You should
  40
+  # consider removing or commenting them out if you're using named routes and resources.
  41
+  map.connect ':controller/:action/:id'
  42
+  map.connect ':controller/:action/:id.:format'
  43
+end
7  db/seeds.rb
... ...
@@ -0,0 +1,7 @@
  1
+# This file should contain all the record creation needed to seed the database with its default values.
  2
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
  3
+#
  4
+# Examples:
  5
+#   
  6
+#   cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
  7
+#   Major.create(:name => 'Daley', :city => cities.first)
2  doc/README_FOR_APP
... ...
@@ -0,0 +1,2 @@
  1
+Use this README file to introduce your application and point to useful places in the API for learning more.
  2
+Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
30  public/404.html
... ...
@@ -0,0 +1,30 @@
  1
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3
+
  4
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5
+
  6
+<head>
  7
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  8
+  <title>The page you were looking for doesn't exist (404)</title>
  9
+	<style type="text/css">
  10
+		body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
  11
+		div.dialog {
  12
+			width: 25em;
  13
+			padding: 0 4em;
  14
+			margin: 4em auto 0 auto;
  15
+			border: 1px solid #ccc;
  16
+			border-right-color: #999;
  17
+			border-bottom-color: #999;
  18
+		}
  19
+		h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
  20
+	</style>
  21
+</head>
  22
+
  23
+<body>
  24
+  <!-- This file lives in public/404.html -->
  25
+  <div class="dialog">
  26
+    <h1>The page you were looking for doesn't exist.</h1>
  27
+    <p>You may have mistyped the address or the page may have moved.</p>
  28
+  </div>
  29
+</body>
  30
+</html>
30  public/422.html
... ...
@@ -0,0 +1,30 @@
  1
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3
+
  4
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5
+
  6
+<head>
  7
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  8
+  <title>The change you wanted was rejected (422)</title>
  9
+	<style type="text/css">
  10
+		body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
  11
+		div.dialog {
  12
+			width: 25em;
  13
+			padding: 0 4em;
  14
+			margin: 4em auto 0 auto;
  15
+			border: 1px solid #ccc;
  16
+			border-right-color: #999;
  17
+			border-bottom-color: #999;
  18
+		}
  19
+		h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
  20
+	</style>
  21
+</head>
  22
+
  23
+<body>
  24
+  <!-- This file lives in public/422.html -->
  25
+  <div class="dialog">
  26
+    <h1>The change you wanted was rejected.</h1>
  27
+    <p>Maybe you tried to change something you didn't have access to.</p>
  28
+  </div>
  29
+</body>
  30
+</html>
30  public/500.html
... ...
@@ -0,0 +1,30 @@
  1
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3
+
  4
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5
+
  6
+<head>
  7
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  8
+  <title>We're sorry, but something went wrong (500)</title>
  9
+	<style type="text/css">
  10
+		body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
  11
+		div.dialog {
  12
+			width: 25em;
  13
+			padding: 0 4em;
  14
+			margin: 4em auto 0 auto;
  15
+			border: 1px solid #ccc;
  16
+			border-right-color: #999;
  17
+			border-bottom-color: #999;
  18
+		}
  19
+		h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
  20
+	</style>
  21
+</head>
  22
+
  23
+<body>
  24
+  <!-- This file lives in public/500.html -->
  25
+  <div class="dialog">
  26
+    <h1>We're sorry, but something went wrong.</h1>
  27
+    <p>We've been notified about this issue and we'll take a look at it shortly.</p>
  28
+  </div>
  29
+</body>
  30
+</html>
0  public/favicon.ico
No changes.
BIN  public/images/rails.png
275  public/index.html
... ...
@@ -0,0 +1,275 @@
  1
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3
+<html>
  4
+  <head>
  5
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  6
+    <title>Ruby on Rails: Welcome aboard</title>
  7
+    <style type="text/css" media="screen">
  8
+      body {
  9
+        margin: 0;
  10
+        margin-bottom: 25px;
  11
+        padding: 0;
  12
+        background-color: #f0f0f0;
  13
+        font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
  14
+        font-size: 13px;
  15
+        color: #333;
  16
+      }
  17
+      
  18
+      h1 {
  19
+        font-size: 28px;
  20
+        color: #000;
  21
+      }
  22
+      
  23
+      a  {color: #03c}
  24
+      a:hover {
  25
+        background-color: #03c;
  26
+        color: white;
  27
+        text-decoration: none;
  28
+      }
  29
+      
  30
+      
  31
+      #page {
  32
+        background-color: #f0f0f0;
  33
+        width: 750px;
  34
+        margin: 0;
  35
+        margin-left: auto;
  36
+        margin-right: auto;
  37
+      }
  38
+      
  39
+      #content {
  40
+        float: left;
  41
+        background-color: white;
  42
+        border: 3px solid #aaa;
  43
+        border-top: none;
  44
+        padding: 25px;
  45
+        width: 500px;
  46
+      }
  47
+      
  48
+      #sidebar {
  49
+        float: right;
  50
+        width: 175px;
  51
+      }
  52
+
  53
+      #footer {
  54
+        clear: both;
  55
+      }
  56
+      
  57
+
  58
+      #header, #about, #getting-started {
  59
+        padding-left: 75px;
  60
+        padding-right: 30px;
  61
+      }
  62
+
  63
+
  64
+      #header {
  65
+        background-image: url("images/rails.png");
  66
+        background-repeat: no-repeat;
  67
+        background-position: top left;
  68
+        height: 64px;
  69
+      }
  70
+      #header h1, #header h2 {margin: 0}
  71
+      #header h2 {
  72
+        color: #888;
  73
+        font-weight: normal;
  74
+        font-size: 16px;
  75
+      }
  76
+      
  77
+      
  78
+      #about h3 {
  79
+        margin: 0;
  80
+        margin-bottom: 10px;
  81
+        font-size: 14px;
  82
+      }
  83
+      
  84
+      #about-content {
  85
+        background-color: #ffd;
  86
+        border: 1px solid #fc0;
  87
+        margin-left: -11px;
  88
+      }
  89
+      #about-content table {
  90
+        margin-top: 10px;
  91
+        margin-bottom: 10px;
  92
+        font-size: 11px;
  93
+        border-collapse: collapse;
  94
+      }
  95
+      #about-content td {
  96
+        padding: 10px;
  97
+        padding-top: 3px;
  98
+        padding-bottom: 3px;
  99
+      }
  100
+      #about-content td.name  {color: #555}
  101
+      #about-content td.value {color: #000}
  102
+      
  103
+      #about-content.failure {
  104
+        background-color: #fcc;
  105
+        border: 1px solid #f00;
  106
+      }
  107
+      #about-content.failure p {
  108
+        margin: 0;
  109
+        padding: 10px;
  110
+      }
  111
+      
  112
+      
  113
+      #getting-started {
  114
+        border-top: 1px solid #ccc;
  115
+        margin-top: 25px;
  116
+        padding-top: 15px;
  117
+      }
  118
+      #getting-started h1 {
  119
+        margin: 0;
  120
+        font-size: 20px;
  121
+      }
  122
+      #getting-started h2 {
  123
+        margin: 0;
  124
+        font-size: 14px;
  125
+        font-weight: normal;
  126
+        color: #333;
  127
+        margin-bottom: 25px;
  128
+      }
  129
+      #getting-started ol {
  130
+        margin-left: 0;
  131
+        padding-left: 0;
  132
+      }
  133
+      #getting-started li {
  134
+        font-size: 18px;
  135
+        color: #888;
  136
+        margin-bottom: 25px;
  137
+      }
  138
+      #getting-started li h2 {
  139
+        margin: 0;
  140
+        font-weight: normal;
  141
+        font-size: 18px;
  142
+        color: #333;
  143
+      }
  144
+      #getting-started li p {
  145
+        color: #555;
  146
+        font-size: 13px;
  147
+      }
  148
+      
  149
+      
  150
+      #search {
  151
+        margin: 0;
  152
+        padding-top: 10px;
  153
+        padding-bottom: 10px;
  154
+        font-size: 11px;
  155
+      }
  156
+      #search input {
  157
+        font-size: 11px;
  158
+        margin: 2px;
  159
+      }
  160
+      #search-text {width: 170px}
  161
+      
  162
+      
  163
+      #sidebar ul {
  164
+        margin-left: 0;
  165
+        padding-left: 0;
  166
+      }
  167
+      #sidebar ul h3 {
  168
+        margin-top: 25px;
  169
+        font-size: 16px;
  170
+        padding-bottom: 10px;
  171
+        border-bottom: 1px solid #ccc;
  172
+      }
  173
+      #sidebar li {
  174
+        list-style-type: none;
  175
+      }
  176
+      #sidebar ul.links li {
  177
+        margin-bottom: 5px;
  178
+      }
  179
+      
  180
+    </style>
  181
+    <script type="text/javascript" src="javascripts/prototype.js"></script>
  182
+    <script type="text/javascript" src="javascripts/effects.js"></script>
  183
+    <script type="text/javascript">
  184
+      function about() {
  185
+        if (Element.empty('about-content')) {
  186
+          new Ajax.Updater('about-content', 'rails/info/properties', {
  187
+            method:     'get',
  188
+            onFailure:  function() {Element.classNames('about-content').add('failure')},
  189
+            onComplete: function() {new Effect.BlindDown('about-content', {duration: 0.25})}
  190
+          });
  191
+        } else {
  192
+          new Effect[Element.visible('about-content') ? 
  193
+            'BlindUp' : 'BlindDown']('about-content', {duration: 0.25});
  194
+        }
  195
+      }
  196
+      
  197
+      window.onload = function() {
  198
+        $('search-text').value = '';
  199
+        $('search').onsubmit = function() {
  200
+          $('search-text').value = 'site:rubyonrails.org ' + $F('search-text');
  201
+        }
  202
+      }
  203
+    </script>
  204
+  </head>
  205
+  <body>
  206
+    <div id="page">
  207
+      <div id="sidebar">
  208
+        <ul id="sidebar-items">
  209
+          <li>
  210
+            <form id="search" action="http://www.google.com/search" method="get">
  211
+              <input type="hidden" name="hl" value="en" />
  212
+              <input type="text" id="search-text" name="q" value="site:rubyonrails.org " />
  213
+              <input type="submit" value="Search" /> the Rails site
  214
+            </form>
  215
+          </li>
  216
+        
  217
+          <li>
  218
+            <h3>Join the community</h3>
  219
+            <ul class="links">
  220
+              <li><a href="http://www.rubyonrails.org/">Ruby on Rails</a></li>
  221
+              <li><a href="http://weblog.rubyonrails.org/">Official weblog</a></li>
  222
+              <li><a href="http://wiki.rubyonrails.org/">Wiki</a></li>
  223
+            </ul>
  224
+          </li>
  225
+          
  226
+          <li>
  227
+            <h3>Browse the documentation</h3>
  228
+            <ul class="links">
  229
+              <li><a href="http://api.rubyonrails.org/">Rails API</a></li>
  230
+              <li><a href="http://stdlib.rubyonrails.org/">Ruby standard library</a></li>
  231
+              <li><a href="http://corelib.rubyonrails.org/">Ruby core</a></li>
  232
+              <li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
  233
+            </ul>
  234
+          </li>
  235
+        </ul>
  236
+      </div>
  237
+
  238
+      <div id="content">
  239
+        <div id="header">
  240
+          <h1>Welcome aboard</h1>
  241
+          <h2>You&rsquo;re riding Ruby on Rails!</h2>
  242
+        </div>
  243
+
  244
+        <div id="about">
  245
+          <h3><a href="rails/info/properties" onclick="about(); return false">About your application&rsquo;s environment</a></h3>
  246
+          <div id="about-content" style="display: none"></div>
  247
+        </div>
  248
+        
  249
+        <div id="getting-started">
  250
+          <h1>Getting started</h1>
  251
+          <h2>Here&rsquo;s how to get rolling:</h2>
  252
+          
  253
+          <ol>          
  254
+            <li>
  255
+              <h2>Use <tt>script/generate</tt> to create your models and controllers</h2>
  256
+              <p>To see all available options, run it without parameters.</p>
  257
+            </li>
  258
+            
  259
+            <li>
  260
+              <h2>Set up a default route and remove or rename this file</h2>
  261
+              <p>Routes are set up in config/routes.rb.</p>
  262
+            </li>
  263
+
  264
+            <li>
  265
+              <h2>Create your database</h2>
  266
+              <p>Run <tt>rake db:migrate</tt> to create your database. If you're not using SQLite (the default), edit <tt>config/database.yml</tt> with your username and password.</p>
  267
+            </li>
  268
+          </ol>
  269
+        </div>
  270
+      </div>
  271
+      
  272
+      <div id="footer">&nbsp;</div>
  273
+    </div>
  274
+  </body>
  275
+</html>
2  public/javascripts/application.js
... ...
@@ -0,0 +1,2 @@
  1
+// Place your application-specific JavaScript functions and classes here
  2
+// This file is automatically included by javascript_include_tag :defaults
963  public/javascripts/controls.js
... ...
@@ -0,0 +1,963 @@
  1
+// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
  2
+//           (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
  3
+//           (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
  4
+// Contributors:
  5
+//  Richard Livsey
  6
+//  Rahul Bhargava
  7
+//  Rob Wills
  8
+//
  9
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
  10
+// For details, see the script.aculo.us web site: http://script.aculo.us/
  11
+
  12
+// Autocompleter.Base handles all the autocompletion functionality
  13
+// that's independent of the data source for autocompletion. This
  14
+// includes drawing the autocompletion menu, observing keyboard
  15
+// and mouse events, and similar.
  16
+//
  17
+// Specific autocompleters need to provide, at the very least,
  18
+// a getUpdatedChoices function that will be invoked every time
  19
+// the text inside the monitored textbox changes. This method
  20
+// should get the text for which to provide autocompletion by
  21
+// invoking this.getToken(), NOT by directly accessing
  22
+// this.element.value. This is to allow incremental tokenized
  23
+// autocompletion. Specific auto-completion logic (AJAX, etc)
  24
+// belongs in getUpdatedChoices.
  25
+//
  26
+// Tokenized incremental autocompletion is enabled automatically
  27
+// when an autocompleter is instantiated with the 'tokens' option
  28
+// in the options parameter, e.g.:
  29
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
  30
+// will incrementally autocomplete with a comma as the token.
  31
+// Additionally, ',' in the above example can be replaced with
  32
+// a token array, e.g. { tokens: [',', '\n'] } which
  33
+// enables autocompletion on multiple tokens. This is most
  34
+// useful when one of the tokens is \n (a newline), as it
  35
+// allows smart autocompletion after linebreaks.
  36
+
  37
+if(typeof Effect == 'undefined')
  38
+  throw("controls.js requires including script.aculo.us' effects.js library");
  39
+
  40
+var Autocompleter = { };
  41
+Autocompleter.Base = Class.create({
  42
+  baseInitialize: function(element, update, options) {
  43
+    element          = $(element);
  44
+    this.element     = element;
  45
+    this.update      = $(update);
  46
+    this.hasFocus    = false;
  47
+    this.changed     = false;
  48
+    this.active      = false;
  49
+    this.index       = 0;
  50
+    this.entryCount  = 0;
  51
+    this.oldElementValue = this.element.value;
  52
+
  53
+    if(this.setOptions)
  54
+      this.setOptions(options);
  55
+    else
  56
+      this.options = options || { };
  57
+
  58
+    this.options.paramName    = this.options.paramName || this.element.name;
  59
+    this.options.tokens       = this.options.tokens || [];
  60
+    this.options.frequency    = this.options.frequency || 0.4;
  61
+    this.options.minChars     = this.options.minChars || 1;
  62
+    this.options.onShow       = this.options.onShow ||
  63
+      function(element, update){
  64
+        if(!update.style.position || update.style.position=='absolute') {
  65
+          update.style.position = 'absolute';
  66
+          Position.clone(element, update, {
  67
+            setHeight: false,
  68
+            offsetTop: element.offsetHeight
  69
+          });
  70
+        }
  71
+        Effect.Appear(update,{duration:0.15});
  72
+      };
  73
+    this.options.onHide = this.options.onHide ||
  74
+      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
  75
+
  76
+    if(typeof(this.options.tokens) == 'string')
  77
+      this.options.tokens = new Array(this.options.tokens);
  78
+    // Force carriage returns as token delimiters anyway
  79
+    if (!this.options.tokens.include('\n'))
  80
+      this.options.tokens.push('\n');
  81
+
  82
+    this.observer = null;
  83
+
  84
+    this.element.setAttribute('autocomplete','off');
  85
+
  86
+    Element.hide(this.update);
  87
+
  88
+    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
  89
+    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
  90
+  },
  91
+
  92
+  show: function() {
  93
+    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
  94
+    if(!this.iefix &&
  95
+      (Prototype.Browser.IE) &&
  96
+      (Element.getStyle(this.update, 'position')=='absolute')) {
  97
+      new Insertion.After(this.update,
  98
+       '<iframe id="' + this.update.id + '_iefix" '+
  99
+       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
  100
+       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
  101
+      this.iefix = $(this.update.id+'_iefix');
  102
+    }
  103
+    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
  104
+  },
  105
+
  106
+  fixIEOverlapping: function() {
  107
+    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
  108
+    this.iefix.style.zIndex = 1;
  109
+    this.update.style.zIndex = 2;
  110
+    Element.show(this.iefix);
  111
+  },
  112
+
  113
+  hide: function() {
  114
+    this.stopIndicator();
  115
+    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
  116
+    if(this.iefix) Element.hide(this.iefix);
  117
+  },
  118
+
  119
+  startIndicator: function() {
  120
+    if(this.options.indicator) Element.show(this.options.indicator);
  121
+  },
  122
+
  123
+  stopIndicator: function() {
  124
+    if(this.options.indicator) Element.hide(this.options.indicator);
  125
+  },
  126
+
  127
+  onKeyPress: function(event) {
  128
+    if(this.active)
  129
+      switch(event.keyCode) {
  130
+       case Event.KEY_TAB:
  131
+       case Event.KEY_RETURN:
  132
+         this.selectEntry();
  133
+         Event.stop(event);
  134
+       case Event.KEY_ESC:
  135
+         this.hide();
  136
+         this.active = false;
  137
+         Event.stop(event);
  138
+         return;
  139
+       case Event.KEY_LEFT:
  140
+       case Event.KEY_RIGHT:
  141
+         return;
  142
+       case Event.KEY_UP:
  143
+         this.markPrevious();
  144
+         this.render();
  145
+         Event.stop(event);
  146
+         return;
  147
+       case Event.KEY_DOWN:
  148
+         this.markNext();
  149
+         this.render();
  150
+         Event.stop(event);
  151
+         return;
  152
+      }
  153
+     else
  154
+       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
  155
+         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
  156
+
  157
+    this.changed = true;
  158
+    this.hasFocus = true;
  159
+
  160
+    if(this.observer) clearTimeout(this.observer);
  161
+      this.observer =
  162
+        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
  163
+  },
  164
+
  165
+  activate: function() {
  166
+    this.changed = false;
  167
+    this.hasFocus = true;
  168
+    this.getUpdatedChoices();
  169
+  },
  170
+
  171
+  onHover: function(event) {
  172
+    var element = Event.findElement(event, 'LI');
  173
+    if(this.index != element.autocompleteIndex)
  174
+    {
  175
+        this.index = element.autocompleteIndex;
  176
+        this.render();
  177
+    }
  178
+    Event.stop(event);
  179
+  },
  180
+
  181
+  onClick: function(event) {
  182
+    var element = Event.findElement(event, 'LI');
  183
+    this.index = element.autocompleteIndex;
  184
+    this.selectEntry();
  185
+    this.hide();
  186
+  },
  187
+
  188
+  onBlur: function(event) {
  189
+    // needed to make click events working
  190
+    setTimeout(this.hide.bind(this), 250);
  191
+    this.hasFocus = false;
  192
+    this.active = false;
  193
+  },
  194
+
  195
+  render: function() {
  196
+    if(this.entryCount > 0) {
  197
+      for (var i = 0; i < this.entryCount; i++)
  198
+        this.index==i ?
  199
+          Element.addClassName(this.getEntry(i),"selected") :
  200
+          Element.removeClassName(this.getEntry(i),"selected");
  201
+      if(this.hasFocus) {
  202
+        this.show();
  203
+        this.active = true;
  204
+      }
  205
+    } else {
  206
+      this.active = false;
  207
+      this.hide();
  208
+    }
  209
+  },
  210
+
  211
+  markPrevious: function() {
  212
+    if(this.index > 0) this.index--;
  213
+      else this.index = this.entryCount-1;
  214
+    this.getEntry(this.index).scrollIntoView(true);
  215
+  },
  216
+
  217
+  markNext: function() {
  218
+    if(this.index < this.entryCount-1) this.index++;
  219
+      else this.index = 0;
  220
+    this.getEntry(this.index).scrollIntoView(false);
  221
+  },
  222
+
  223
+  getEntry: function(index) {
  224
+    return this.update.firstChild.childNodes[index];
  225
+  },
  226
+
  227
+  getCurrentEntry: function() {
  228
+    return this.getEntry(this.index);
  229
+  },
  230
+
  231
+  selectEntry: function() {
  232
+    this.active = false;
  233
+    this.updateElement(this.getCurrentEntry());
  234
+  },
  235
+
  236
+  updateElement: function(selectedElement) {
  237
+    if (this.options.updateElement) {
  238
+      this.options.updateElement(selectedElement);
  239
+      return;
  240
+    }
  241
+    var value = '';
  242
+    if (this.options.select) {
  243
+      var nodes = $(selectedElement).select('.' + this.options.select) || [];
  244
+      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
  245
+    } else
  246
+      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
  247
+
  248
+    var bounds = this.getTokenBounds();
  249
+    if (bounds[0] != -1) {
  250
+      var newValue = this.element.value.substr(0, bounds[0]);
  251
+      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
  252
+      if (whitespace)
  253
+        newValue += whitespace[0];
  254
+      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
  255
+    } else {
  256
+      this.element.value = value;
  257
+    }
  258
+    this.oldElementValue = this.element.value;
  259
+    this.element.focus();
  260
+
  261
+    if (this.options.afterUpdateElement)
  262
+      this.options.afterUpdateElement(this.element, selectedElement);
  263
+  },
  264
+
  265
+  updateChoices: function(choices) {
  266
+    if(!this.changed && this.hasFocus) {
  267
+      this.update.innerHTML = choices;
  268
+      Element.cleanWhitespace(this.update);
  269
+      Element.cleanWhitespace(this.update.down());
  270
+
  271
+      if(this.update.firstChild && this.update.down().childNodes) {
  272
+        this.entryCount =
  273
+          this.update.down().childNodes.length;
  274
+        for (var i = 0; i < this.entryCount; i++) {
  275
+          var entry = this.getEntry(i);
  276
+          entry.autocompleteIndex = i;
  277
+          this.addObservers(entry);
  278
+        }
  279
+      } else {
  280
+        this.entryCount = 0;
  281
+      }
  282
+
  283
+      this.stopIndicator();
  284
+      this.index = 0;
  285
+
  286
+      if(this.entryCount==1 && this.options.autoSelect) {
  287
+        this.selectEntry();
  288
+        this.hide();
  289
+      } else {
  290
+        this.render();
  291
+      }