commit 50fd1b0dd594c89ebd25af5fdc80bfbe7d031410 Author: penguinc Date: Fri Sep 8 05:57:50 2006 +0000 Initial revision diff --git a/README b/README new file mode 100644 index 0000000..cd9d0ff --- /dev/null +++ b/README @@ -0,0 +1,153 @@ +== Welcome to Rails + +Rails is a web-application and persistence framework that includes everything +needed to create database-backed web-applications according to the +Model-View-Control pattern of separation. This pattern splits the view (also +called the presentation) into "dumb" templates that are primarily responsible +for inserting pre-built data in between HTML tags. The model contains the +"smart" domain objects (such as Account, Product, Person, Post) that holds all +the business logic and knows how to persist themselves to a database. The +controller handles the incoming requests (such as Save New Account, Update +Product, Show Post) by manipulating the model and directing data to the view. + +In Rails, the model is handled by what's called an object-relational mapping +layer entitled Active Record. This layer allows you to present the data from +database rows as objects and embellish these data objects with business logic +methods. You can read more about Active Record in +link:files/vendor/rails/activerecord/README.html. + +The controller and view are handled by the Action Pack, which handles both +layers by its two parts: Action View and Action Controller. These two layers +are bundled in a single package due to their heavy interdependence. This is +unlike the relationship between the Active Record and Action Pack that is much +more separate. Each of these packages can be used independently outside of +Rails. You can read more about Action Pack in +link:files/vendor/rails/actionpack/README.html. + + +== Getting started + +1. Run the WEBrick servlet: ruby script/server (run with --help for options) + ...or if you have lighttpd installed: ruby script/lighttpd (it's faster) +2. Go to http://localhost:3000/ and get "Congratulations, you've put Ruby on Rails!" +3. Follow the guidelines on the "Congratulations, you've put Ruby on Rails!" screen + + +== Example for Apache conf + + + ServerName rails + DocumentRoot /path/application/public/ + ErrorLog /path/application/log/server.log + + + Options ExecCGI FollowSymLinks + AllowOverride all + Allow from all + Order allow,deny + + + +NOTE: Be sure that CGIs can be executed in that directory as well. So ExecCGI +should be on and ".cgi" should respond. All requests from 127.0.0.1 go +through CGI, so no Apache restart is necessary for changes. All other requests +go through FCGI (or mod_ruby), which requires a restart to show changes. + + +== Debugging Rails + +Have "tail -f" commands running on both the server.log, production.log, and +test.log files. Rails will automatically display debugging and runtime +information to these files. Debugging info will also be shown in the browser +on requests from 127.0.0.1. + + +== Breakpoints + +Breakpoint support is available through the script/breakpointer client. This +means that you can break out of execution at any point in the code, investigate +and change the model, AND then resume execution! Example: + + class WeblogController < ActionController::Base + def index + @posts = Post.find_all + breakpoint "Breaking out from the list" + end + end + +So the controller will accept the action, run the first line, then present you +with a IRB prompt in the breakpointer window. Here you can do things like: + +Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint' + + >> @posts.inspect + => "[#nil, \"body\"=>nil, \"id\"=>\"1\"}>, + #\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]" + >> @posts.first.title = "hello from a breakpoint" + => "hello from a breakpoint" + +...and even better is that you can examine how your runtime objects actually work: + + >> f = @posts.first + => #nil, "body"=>nil, "id"=>"1"}> + >> f. + Display all 152 possibilities? (y or n) + +Finally, when you're ready to resume execution, you press CTRL-D + + +== Console + +You can interact with the domain model by starting the console through script/console. +Here you'll have all parts of the application configured, just like it is when the +application is running. You can inspect domain models, change values, and save to the +database. Starting the script without arguments will launch it in the development environment. +Passing an argument will specify a different environment, like console production. + + +== Description of contents + +app + Holds all the code that's specific to this particular application. + +app/controllers + Holds controllers that should be named like weblog_controller.rb for + automated URL mapping. All controllers should descend from + ActionController::Base. + +app/models + Holds models that should be named like post.rb. + Most models will descend from ActiveRecord::Base. + +app/views + Holds the template files for the view that should be named like + weblog/index.rhtml for the WeblogController#index action. All views use eRuby + syntax. This directory can also be used to keep stylesheets, images, and so on + that can be symlinked to public. + +app/helpers + Holds view helpers that should be named like weblog_helper.rb. + +config + Configuration files for the Rails environment, the routing map, the database, and other dependencies. + +components + Self-contained mini-applications that can bundle together controllers, models, and views. + +lib + Application specific libraries. Basically, any kind of custom code that doesn't + belong under controllers, models, or helpers. This directory is in the load path. + +public + The directory available for the web server. Contains subdirectories for images, stylesheets, + and javascripts. Also contains the dispatchers and the default HTML files. + +script + Helper scripts for automation and generation. + +test + Unit and functional tests along with fixtures. + +vendor + External libraries that the application depends on. Also includes the plugins subdirectory. + This directory is in the load path. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..cffd19f --- /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/switchtower.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' \ No newline at end of file diff --git a/app/controllers/activity_controller.rb b/app/controllers/activity_controller.rb new file mode 100644 index 0000000..ad85134 --- /dev/null +++ b/app/controllers/activity_controller.rb @@ -0,0 +1,19 @@ +class ActivityController < ApplicationController + + append_before_filter :verify_identity + append_before_filter :add_refresh_link, :only => [ 'index' ] + append_before_filter :find_fund, :only => [ 'index' ] + + ## + # This method will display a list of the purchases for the fund, starting + # with the oldest. Also handily paginated by default. Lookit, four lines! + # + def index + unless @fund.nil? + @purchase_pages, @purchases = paginate :ledger, :order => + "ledgers.post_date DESC, ledgers.created_at DESC", + :conditions => [ 'ledgers.fund_id = ?', @fund.id ], + :joins => "LEFT JOIN baristas ON ledgers.barista_id = baristas.id" + end + end +end \ No newline at end of file diff --git a/app/controllers/application.rb b/app/controllers/application.rb new file mode 100644 index 0000000..b40d018 --- /dev/null +++ b/app/controllers/application.rb @@ -0,0 +1,124 @@ +class ApplicationController < ActionController::Base + + append_before_filter :session_setup + append_before_filter :link_setup + + layout 'grindable' + + ## + # Method to determine if a user is authenticated. This might be more + # complicated in the future. + # + def authenticated? + session[:authenticated] == true + end + + ## + # A filter check to ensure that the person using the fund is authenticated + # in some way or another... + # + def verify_identity + # escape check + return true if authenticated? + + # make 'em authenticate before continuing + session[:return_to] = request.request_uri + # nice one, bruddah. it's a route helper. + redirect_to login_url + end + + ## + # Sends the user to the default url. This could either be stored in the + # sesion or in the home_url method. + # + def goto_default_redirect_url + if session[:return_to].nil? + redirect_to home_url + else + redirect_to session[:return_to] + session[:return_to] = nil + end + end + + ## + # Redirects to the index action, useful since it is used in lots of places + # + def goto_index + redirect_to :action => 'index' + end + + ## + # Adds a related link to refresh the current action + # + def add_refresh_link + add_related_link 'Refresh' + end + + ## + # This will add a submenu item to be displayed + # + def add_related_link(*args) + @related_links.push [ *args ] + end + + ## + # This will add a submenu item for a javascript function + # + def add_related_function(what, where) + @related_functions.push [ what, where ] + end + + ## + # Adds an AJAX call to the submenu list + # + def add_remote_function(*args) + @related_remote.push [ *args ] + end + + ## + # Ensures that the method in question was called from a form, ie. POST + # + def ensure_post + return false unless request.post? + true + end + + ## + # Just like ensure_post only for AJAX requests... + # + def ensure_xhr + return false unless request.xhr? + true + end + + ## + # This configures the @fund variable for several methods as a before_filter. + # + def find_fund + return unless session[:barista] and session[:barista][:fund_id] + @fund = Fund.find session[:barista][:fund_id].to_i unless + session[:barista].nil? + end + + private + + ## + # This should ensure a minimum session environment + # + def session_setup + if session[:authenticated].nil? + session[:barista] = nil + session[:authenticated] = false + end + true + end + + ## + # Creates the environment for the submenu of links + # + def link_setup + @related_links ||= [] + @related_functions ||= [] + @related_remote ||= [] + end +end \ No newline at end of file diff --git a/app/controllers/barista_controller.rb b/app/controllers/barista_controller.rb new file mode 100644 index 0000000..e5e400e --- /dev/null +++ b/app/controllers/barista_controller.rb @@ -0,0 +1,79 @@ +class BaristaController < ApplicationController + + append_before_filter :ensure_post, :only => [ 'add', 'delete', 'edit' ] + append_before_filter :add_refresh_link, :only => [ 'index' ] + append_before_filter :find_fund, :only => [ 'index' ] + + ## + # Lists all of the baristas in the system + # + def index + @pages, @baristas = paginate :baristas, :order => 'baristas.name ASC', + :per_page => 10, :include => 'fund' + add_related_function 'Create Barista', + ("dojo.widget.byId('baristaDialog').show();" + + "dojo.byId('barista_name').focus()") + end + + ## + # Adds a new barista to the system. + # + def add + b = Barista.new params['barista'] + + begin + b.save! + flash[:info] = 'Successfully created a new barista!' + rescue => exception + flash[:error] = "Failed to create the barista: #{exception.to_s}" + end + + goto_index + end + + def delete + # not implemented yet + end + + def edit + # nothing to edit, only the password really. and there's none of that now + end + + ## + # This method will identify the user -- basically an authenticate. + # + def identify + # user should probably not be here if they are already authenticated + goto_default_redirect_url if authenticated? + + if request.post? + # mirror mirror on the wall, who is da funkiest of them all? + user_to_auth = Barista.find :first, :conditions => [ "name = ?", + params[:name] ] + + if user_to_auth.nil? + # busted + flash.now[:error] = "You're going to have to try harder than that." + else + # ballin' + session[:authenticated] = true + session[:barista] = user_to_auth + flash[:info] = "Welcome to the Grindable!" + + # shot callin' + goto_default_redirect_url + end + end + end + + ## + # This method should reset the user state to basic -- a deauthenticate. + # + def anonymize + # blank out all knowledge of the user + reset_session + + # go home + goto_default_redirect_url + end +end diff --git a/app/controllers/cafe_controller.rb b/app/controllers/cafe_controller.rb new file mode 100644 index 0000000..e56b5a4 --- /dev/null +++ b/app/controllers/cafe_controller.rb @@ -0,0 +1,121 @@ +class CafeController < ApplicationController + + append_before_filter :verify_identity + append_before_filter :ensure_post, :only => [ 'make_contribution', + 'make_purchase', 'milk_purchased' ] + append_before_filter :add_refresh_link, :only => [ 'index' ] + append_before_filter :find_fund, :only => [ 'index', 'make_contribution', + 'make_purchase' ] + append_before_filter :find_next_milk_purchaser, :only => [ 'index' ] + + ## + # The main coffee page. + # + def index + unless @fund.nil? + add_related_function 'Make Contribution', + "dojo.widget.byId('contributionDialog').show()" + add_related_function 'Make Purchase', + "dojo.widget.byId('purchaseDialog').show()" + add_related_function 'Milk Purchased', + "dojo.byId('milk_form').submit()" unless @fund.contribution == 0.0 + end + end + + ## + # The method to confirm you bought milk. + # + def milk_purchased + l = Ledger.new + l.fund_id = session[:barista][:fund_id] + l.barista_id = session[:barista][:id] + l.comment = 'MILK' + l.post_date = Date.today + begin + l.save! + session[:barista].update_attribute 'milk_last_bought_at', Time.now + flash[:info] = 'You just purchased milk!' + rescue => exception + flash[:error] = 'There was a problem: #{exception.to_s}' + end + goto_index + end + + ## + # The method to make a contribution to the fund. + # + def make_contribution + # this is one of the more complicated procedures in the app + new_contribution = Ledger.new + # set the contribution amount from the fund + if @fund.contribution.nil? or @fund.contribution == 0 + new_contribution.credit_amount = params[:contribution].to_f rescue 0.0 + else + new_contribution.credit_amount = @fund.contribution + end + # update the fund balance + @fund.make_contribution new_contribution.credit_amount + new_contribution.barista_id = params[:contribution][:barista_id] + new_contribution.fund_id = session[:barista][:fund_id] + new_contribution.comment = 'CONTRIBUTION' + new_contribution.post_date = Date.today + + begin + new_contribution.save! + quantity = params[:contribution][:quantity].to_i + if quantity > 1 + (2..quantity).each do |q| + c = Ledger.new + c.attributes = new_contribution.attributes + c.post_date = new_contribution.post_date >> 1 + c.save! + end + end + session[:barista].save! + @fund.save! + flash[:info] = + "Successfully contributed to the fund #{@fund.name}!" + rescue => exception + flash[:error] = "Failed to properly work: #{exception.to_s}" + end + + goto_index + end + + ## + # The method for making a purchase out of general funds. + # + def make_purchase + new_purchase = Ledger.new + new_purchase.debit_amount = params[:amount] + new_purchase.comment = params[:comment] + new_purchase.barista_id = session[:barista][:id] + new_purchase.fund_id = session[:barista][:fund_id] + new_purchase.post_date = Date.today + @fund.make_purchase new_purchase.debit_amount + + begin + new_purchase.save! + session[:barista].save! + @fund.save! + flash[:info] = "Successfully purchased ... supplies!" + rescue => exception + flash[:error] = "Failed to work properly: #{exception.to_s}" + end + + goto_index + end + + private + + ## + # A simple helper to find the next person to buy milk. + # + def find_next_milk_purchaser + return if @fund.nil? + @next_milk_purchaser = Barista.find :first, + :order => "milk_last_bought_at ASC", + :conditions => [ 'fund_id = ?', @fund.id ] + end + +end diff --git a/app/controllers/fund_controller.rb b/app/controllers/fund_controller.rb new file mode 100644 index 0000000..07260a7 --- /dev/null +++ b/app/controllers/fund_controller.rb @@ -0,0 +1,68 @@ +class FundController < ApplicationController + + in_place_edit_for :fund, :contribution + + append_before_filter :ensure_post, :only => [ 'add', 'delete', 'use' ] + append_before_filter :add_refresh_link, :only => [ 'index' ] + + def index + @funds = Fund.find :all, :include => [ 'baristas' ] + add_related_function 'Add Fund', "dojo.widget.byId('fundDialog').show()" + end + + def add + allowed_parameters = [ 'name', 'contribution' ] + params.delete_if { |key, value| !allowed_parameters.include? key } + + begin + fund = Fund.new params + fund.contribution = 0.0 if params[:contribution].nil? or + params[:contribution].empty? + fund.balance = 0.0 + fund.save! + flash[:info] = 'Word, success!' + rescue => exception + flash[:error] = 'There was a problem saving the fund: ' + + exception.to_s + end + + redirect_to :action => 'index' + end + + def delete + fund = Fund.find params[:id].to_i + if fund.nil? + flash[:error] = 'That fund does not exist!' + else + old_name = fund[:name] + begin + fund.destroy + flash[:info] = "The fund #{old_name} has been deleted." + rescue => exception + flash[:error] = "Encountered a problem while removing the fund: " + + exception.to_s + end + end + + goto_index + end + + def use + fund = Fund.find params[:id].to_i + if fund.nil? + flash[:error] = 'That fund does not exist!' + else + session[:barista][:fund_id] = params[:id] + begin + session[:barista].save! + session[:barista].reload + rescue => exception + flash[:error] = "Failed while updating the user: #{exception.to_s}" + else + flash[:info] = 'Successfully updated the user fund.' + end + end + + goto_index + end +end diff --git a/app/helpers/activity_helper.rb b/app/helpers/activity_helper.rb new file mode 100644 index 0000000..3dcc7c6 --- /dev/null +++ b/app/helpers/activity_helper.rb @@ -0,0 +1,2 @@ +module ActivityHelper +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100755 index 0000000..85b994a --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,21 @@ +# Methods added to this helper will be available to all templates in the application. +module ApplicationHelper + + def escape_preserving_linefeeds(text) + h(text).gsub(/\n/, '
') + end + + def escape_preserving_linefeeds_and_html(text) + text.gsub(/\n/, '
') + end + + def display_amount(amount) + return '' if amount.nil? + sprintf("$%0.2f", amount) + end + + def display_date(date) + return '' if date.nil? + "#{date.month}-#{date.day}-#{date.year}" + end +end diff --git a/app/helpers/barista_helper.rb b/app/helpers/barista_helper.rb new file mode 100644 index 0000000..8570b8c --- /dev/null +++ b/app/helpers/barista_helper.rb @@ -0,0 +1,2 @@ +module BaristaHelper +end diff --git a/app/helpers/cafe_helper.rb b/app/helpers/cafe_helper.rb new file mode 100644 index 0000000..43d40db --- /dev/null +++ b/app/helpers/cafe_helper.rb @@ -0,0 +1,2 @@ +module CafeHelper +end diff --git a/app/helpers/fund_helper.rb b/app/helpers/fund_helper.rb new file mode 100644 index 0000000..1a16ef9 --- /dev/null +++ b/app/helpers/fund_helper.rb @@ -0,0 +1,2 @@ +module FundHelper +end diff --git a/app/models/barista.rb b/app/models/barista.rb new file mode 100644 index 0000000..7df5714 --- /dev/null +++ b/app/models/barista.rb @@ -0,0 +1,37 @@ +class Barista < ActiveRecord::Base + has_many :ledgers, :order => "created_at ASC" + + belongs_to :fund + validates_presence_of :fund + + validates_length_of :name, :within => 6..64 + + def self.for_select(fund_id = nil) + if fund_id.nil? + arr = self.find :all, :order => 'name ASC', :select => 'id, name' + else + arr = self.find :all, :order => 'name ASC', :select => 'id, name', + :conditions => [ 'fund_id = ?', fund_id ] + end + + arr.collect do |b| + [ b.name, b.id.to_s ] + end + end + + def paid_this_month? + this_month = Date.new(Date.today.year, Date.today.month, 1) + next_month = (this_month >> 1) - 1 + variables = { :this_month => this_month, :next_month => next_month, + :fund_id => self.fund_id } + query_str = [] + query_str << 'post_date >= :this_month' + query_str << 'post_date <= :next_month' + query_str << 'credit_amount IS NOT NULL' + query_str << 'fund_id = :fund_id' + + return false if (self.ledgers.find :first, + :conditions => [ query_str.join(' AND '), variables ]).nil? + true + end +end \ No newline at end of file diff --git a/app/models/fund.rb b/app/models/fund.rb new file mode 100644 index 0000000..c12e419 --- /dev/null +++ b/app/models/fund.rb @@ -0,0 +1,23 @@ +class Fund < ActiveRecord::Base + + validates_numericality_of :balance, :contribution + validates_uniqueness_of :name + has_many :baristas + has_many :ledgers, :dependent => true + + def make_contribution(amount) + self[:balance] += amount + end + + def make_purchase(amount) + self[:balance] -= amount + end + + def self.for_select + self.find(:all, :select => 'id, name').collect { |f| [ f.name, f.id.to_s ] } + end + + def before_destroy + raise "Fund still has baristas!" unless self.baristas.empty? + end +end diff --git a/app/models/ledger.rb b/app/models/ledger.rb new file mode 100644 index 0000000..4b1f01a --- /dev/null +++ b/app/models/ledger.rb @@ -0,0 +1,6 @@ +class Ledger < ActiveRecord::Base + belongs_to :barista + belongs_to :fund + + validates_numericality_of :debit_amount, :credit_amount, :allow_nil => true +end diff --git a/app/views/activity/_purchase.rhtml b/app/views/activity/_purchase.rhtml new file mode 100644 index 0000000..9618d21 --- /dev/null +++ b/app/views/activity/_purchase.rhtml @@ -0,0 +1,13 @@ +<% @fund_counter ||= 0 -%> +<% if @fund_counter % 2 == 0 -%> + +<% else -%> + +<% end -%> + <%= purchase.comment -%> + <%= purchase.name -%> + <%= display_date purchase.post_date -%> + <%= display_amount purchase.debit_amount -%> + <%= display_amount purchase.credit_amount -%> + +<% @fund_counter += 1 -%> \ No newline at end of file diff --git a/app/views/activity/index.rhtml b/app/views/activity/index.rhtml new file mode 100644 index 0000000..de6ab0c --- /dev/null +++ b/app/views/activity/index.rhtml @@ -0,0 +1,26 @@ +<% @content_title = "Fund Activity :: #{@fund.name rescue 'None!'}" -%> + +<%= render :partial => 'shared/menu' %> + +<% unless @fund.nil? -%> +
+ + + + + + + + + +<%= render :partial => "purchase", :collection => @purchases %> + +
CommentBaristaDate-+


+
+ +
<%= pagination_links @purchase_pages %>
+<% else -%> +
+

Visit the <%= link_to 'Fund Controller', :controller => 'fund' -%> to configure funds and change your associated fund.

+
+<% end -%> \ No newline at end of file diff --git a/app/views/barista/_barista.rhtml b/app/views/barista/_barista.rhtml new file mode 100644 index 0000000..cb86e97 --- /dev/null +++ b/app/views/barista/_barista.rhtml @@ -0,0 +1,11 @@ +<% @fund_counter ||= 0 -%> +<% if @fund_counter % 2 == 0 -%> + +<% else -%> + +<% end -%> + <%= barista.name -%> + <%= barista.fund.name rescue 'None' -%> + <%= display_date barista.created_on -%> + +<% @fund_counter += 1 -%> \ No newline at end of file diff --git a/app/views/barista/identify.rhtml b/app/views/barista/identify.rhtml new file mode 100644 index 0000000..48b2f73 --- /dev/null +++ b/app/views/barista/identify.rhtml @@ -0,0 +1,8 @@ +<% @content_title = 'Identification required' -%> + +
+ <%= form_tag :action => :identify %> +

Name: <%= text_field_tag "name", nil, :size => 32, :maxlength => 64, :class => "inputBox" %>

+

<%= submit_tag "Login", :class => "inputBox" %>

+ <%= end_form_tag %> +
\ No newline at end of file diff --git a/app/views/barista/index.rhtml b/app/views/barista/index.rhtml new file mode 100644 index 0000000..e7237ce --- /dev/null +++ b/app/views/barista/index.rhtml @@ -0,0 +1,37 @@ +<% @content_title = 'Barista Summary' -%> + +<%= render :partial => 'shared/menu' %> + +
+ + + + + + + +<%= render :partial => "barista", :collection => @baristas %> + +
NameFundDate Joined


+
+ +
<%= pagination_links @pages %>
+ + + + +<% + @dojo_map ||= {} + @dojo_map['baristaDialog'] = ['dialog', '{bgColor: "black", bgOpacity: "0.5"}'] +%> \ No newline at end of file diff --git a/app/views/cafe/index.rhtml b/app/views/cafe/index.rhtml new file mode 100644 index 0000000..00c0a3b --- /dev/null +++ b/app/views/cafe/index.rhtml @@ -0,0 +1,91 @@ +<% @content_title = 'Grindable Home' -%> + +<%= render :partial => 'shared/menu' %> + +
+

Fund details

+ <% if @fund.nil? -%> +

You have no associated fund!

+

Visit the <%= link_to 'Fund Controller', :controller => 'fund' -%> to configure funds and change your associated fund.

+ <% else -%> +
    +
  • Fund name: <%= h(@fund.name) -%>
  • +
  • Total fund balance is: <%= display_amount @fund.balance -%>
  • + <% unless @fund.contribution == 0.0 -%> +
  • Monthly contribution: <%= display_amount @fund.contribution -%>
  • + <% end -%> +
+ <% unless @fund.contribution == 0.0 -%> + <% if session[:barista].paid_this_month? -%> +

You have paid this month's contribution.

+ <% else -%> +

You have not paid this month

+ <% end -%> + <% end -%> + <% end -%> +
+ +<% unless @fund.nil? or @fund.contribution == 0.0 -%> +
+

Milk Purchases

+ +<%= form_tag({ :action => 'milk_purchased' }, { :id => 'milk_form' }) -%> +<%= end_form_tag -%> +<% unless session[:barista].milk_last_bought_at.nil? -%> +

You last bought milk <%= time_ago_in_words session[:barista].milk_last_bought_at -%> ago.

+<% else -%> +

You have never bought milk!

+<% end -%> + +<% unless @next_milk_purchaser.id == session[:barista].id -%> +

The next person to buy milk will be: <%= h(@next_milk_purchaser.name) -%>

+<% else -%> +

You will have to buy milk next.

+<% end -%> +
+<% end -%> + +<% unless @fund.nil? -%> + + + + + +<% + @dojo_map ||= {} + @dojo_map['contributionDialog'] = ['dialog', '{bgColor: "black", bgOpacity: "0.5"}'] + @dojo_map['purchaseDialog'] = ['dialog', '{bgColor: "black", bgOpacity: "0.5"}'] +%> +<% end -%> \ No newline at end of file diff --git a/app/views/fund/_fund_line.rhtml b/app/views/fund/_fund_line.rhtml new file mode 100644 index 0000000..6c57c42 --- /dev/null +++ b/app/views/fund/_fund_line.rhtml @@ -0,0 +1,14 @@ +<% @fund_counter ||= 0 -%> +<% if @fund_counter % 2 == 0 -%> + +<% else -%> + +<% end -%> + <%= link_to image_tag('go-home-16.png', :alt => 'Use', :title => 'Use this fund'), { :action => 'use', :id => @fund.id }, :post => true -%> + <%= link_to image_tag('edit-delete-16.png', :alt => 'Delete', :title => 'Delete Fund'), { :action => 'delete', :id => @fund.id }, :post => true -%> + <%= @fund.name -%> + <%= display_amount @fund.balance -%> + <%= in_place_editor_field :fund, :contribution -%> + <%= @fund.baristas.size -%> + +<% @fund_counter += 1 -%> \ No newline at end of file diff --git a/app/views/fund/index.rhtml b/app/views/fund/index.rhtml new file mode 100644 index 0000000..5568148 --- /dev/null +++ b/app/views/fund/index.rhtml @@ -0,0 +1,35 @@ +<% @content_title = 'Fund Summary' -%> + +<%= render :partial => "shared/menu" %> + +
+ + + + + + + + + + + <% @funds.each do |@fund| -%> + <%= render :partial => 'fund_line' %> + <% end -%> + +
UseDeleteNameBalanceContributionSize


+
+ + + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlComboButtonTemplate.html b/public/javascripts/dojo/src/widget/templates/HtmlComboButtonTemplate.html new file mode 100644 index 0000000..809c92a --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlComboButtonTemplate.html @@ -0,0 +1,18 @@ +
+ +
+
+ + +
+ +
+ + + +
+ +
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlContextMenuTemplate.html b/public/javascripts/dojo/src/widget/templates/HtmlContextMenuTemplate.html new file mode 100644 index 0000000..8c85c54 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlContextMenuTemplate.html @@ -0,0 +1,3 @@ +
    +
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlDatePicker.css b/public/javascripts/dojo/src/widget/templates/HtmlDatePicker.css new file mode 100644 index 0000000..c39c22e --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlDatePicker.css @@ -0,0 +1,143 @@ +.calendarContainer { +/* border:1px solid #566f8f;*/ +} + +.calendarBodyContainer { + width:160px; + background: #7591bc url("images/dpBg.gif") top left repeat-x; +} + +.calendarBodyContainer thead tr td { + color:#293a4b; + font:bold 0.75em Helvetica, Arial, Verdana, sans-serif; + text-align:center; + padding:0.25em; + background: url("images/dpHorizLine.gif") bottom left repeat-x; +} + +.calendarBodyContainer tbody tr td { + color:#fff; + font:bold 0.7em Helvetica, Arial, Verdana, sans-serif; + text-align:center; + padding:0.4em; + background: url("images/dpVertLine.gif") top right repeat-y; + cursor:pointer; + cursor:hand; +} + + +.monthWrapper { + padding-bottom:2px; + background: url("images/dpHorizLine.gif") bottom left repeat-x; +} + +.monthContainer { + width:100%; +} + +.monthLabelContainer { + text-align:center; + font:bold 0.75em Helvetica, Arial, Verdana, sans-serif; + background: url("images/dpMonthBg.png") repeat-x top left !important; + color:#293a4b; + padding:0.25em; +} + +.monthCurve { + width:12px; +} + +.monthCurveTL { + background: url("images/dpCurveTL.png") no-repeat top left !important; +} + +.monthCurveTR { + background: url("images/dpCurveTR.png") no-repeat top right !important; +} + + +.yearWrapper { + background: url("images/dpHorizLineFoot.gif") top left repeat-x; + padding-top:2px; +} + +.yearContainer { + width:100%; +} + +.yearContainer td { + background:url("images/dpYearBg.png") top left repeat-x; +} + +.yearContainer .yearLabel { + margin:0; + padding:0.45em 0 0.45em 0; + color:#fff; + font:bold 0.75em Helvetica, Arial, Verdana, sans-serif; + text-align:center; +} + +.curveBL { + background: url("images/dpCurveBL.png") bottom left no-repeat !important; + width:9px !important; + padding:0; + margin:0; +} + +.curveBR { + background: url("images/dpCurveBR.png") bottom right no-repeat !important; + width:9px !important; + padding:0; + margin:0; +} + + +.previousMonth { + background-color:#6782a8 !important; +} + +.currentMonth { +} + +.nextMonth { + background-color:#6782a8 !important; +} + +.currentDate { + text-decoration:underline; + font-style:italic; +} + +.selectedItem { + background-color:#fff !important; + color:#6782a8 !important; +} + +.yearLabel .selectedYear { + padding:0.2em; + background-color:#9ec3fb !important; +} + +.nextYear, .previousYear { + cursor:pointer;cursor:hand; + margin:0 0.55em; +} + +.incrementControl { + cursor:pointer;cursor:hand; + width:1em; +} + +.increase { + float:right; +} + +.decrease { + float:left; +} + +.lastColumn { + background-image:none !important; +} + + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlDatePicker.html b/public/javascripts/dojo/src/widget/templates/HtmlDatePicker.html new file mode 100644 index 0000000..c4d15be --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlDatePicker.html @@ -0,0 +1,141 @@ +
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + ↓ + + + ↓ + + + ↑ + + + ↑ + + July +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + +
+

+ + + +

+
+
+ +
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlDialog.html b/public/javascripts/dojo/src/widget/templates/HtmlDialog.html new file mode 100644 index 0000000..e7b8050 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlDialog.html @@ -0,0 +1,13 @@ +
+ + + +
+ + + +
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlDocPane.css b/public/javascripts/dojo/src/widget/templates/HtmlDocPane.css new file mode 100644 index 0000000..e824775 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlDocPane.css @@ -0,0 +1,49 @@ +.dojoDocPane { padding:1em; font: 1em Georgia,Times,"Times New Roman",serif; } + +.dojoDocPane .container{ } + +.dojoDocPane .dialog{ } +.dojoDocPane .dialog .container{ padding: 0.5em; background: #fff; border: 2px solid #333; } +.dojoDocPane .dialog .docDialog{ background: transparent; width: 20em; } +.dojoDocPane .dialog .docDialog h2{ margin-top: 0; padding-top: 0; } +.dojoDocPane .dialog .docDialog input { float: right; margin-right: 1em; } +.dojoDocPane .dialog .docDialog p{ clear: both; } +#dojoDocUserName, #dojoDocPassword { width: 10em; } + +.dojoDocPane .nav{ } +.dojoDocPane .nav span{ } + +.dojoDocPane .detail{ } +.dojoDocPane .detail h1{ } +.dojoDocPane .detail h1 span.fn{ } +.dojoDocPane .detail .description{ } +.dojoDocPane .detail .params{ } +.dojoDocPane .detail .params .row{ } +.dojoDocPane .detail .params .row span{ } +.dojoDocPane .detail .variables{ } +.dojoDocPane .detail .variables .row{ } +.dojoDocPane .detail .signature{ } +.dojoDocPane .detail .signature .source{ white-space: pre; font: 0.8em Monaco, Courier, "Courier New", monospace; } +.dojoDocPane .detail .signature .source .return{ color:#369; } +.dojoDocPane .detail .signature .source .function{ color: #98543F; font-weight: bold; } +.dojoDocPane .detail .signature .source .params{ } +.dojoDocPane .detail .signature .source .params .type{ font-style: italic; color: #d17575; } +.dojoDocPane .detail .signature .source .params .name{ color: #d14040; } + +.dojoDocPane .result{ } +.dojoDocPane .result h1{ } +.dojoDocPane .result .row{ } +.dojoDocPane .result .row .summary{ } + +.dojoDocPane .package{ } +.dojoDocPane .package h1{ } +.dojoDocPane .package .row{ } +.dojoDocPane .package .row .summary{ } +.dojoDocPane .package .description{ } +.dojoDocPane .package .methods{ } +.dojoDocPane .package .methods h2{ } +.dojoDocPane .package .methods .row{ } +.dojoDocPane .package .methods .row .description{ } +.dojoDocPane .package .requires{ } +.dojoDocPane .package .requires h2{ } +.dojoDocPane .package .requires .row{ } diff --git a/public/javascripts/dojo/src/widget/templates/HtmlDocPane.html b/public/javascripts/dojo/src/widget/templates/HtmlDocPane.html new file mode 100644 index 0000000..06134e8 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlDocPane.html @@ -0,0 +1,79 @@ +
+
+ +
+
+
+

Log In

+

+

+

+

+
+
+
+ + + +
+

Detail: dojo.select

+
Description
+
+

Parameters

+
+ optional + type + variable + - +
+
+
+

Variables

+
+ variable - +
+
+
+

Signature

+
+ returnType + foo + ( + type + paramName + ) +
+
+
+ +
+

Search Results: 0 matches

+
+ dojo.fnLink + - summary +
+
+ +
+

Package: + dojo.package + [edit] + [save] +

+
Description
+
+

Methods

+
+ method + - +
+
+
+

Requires

+
+

Environment

+ +
+
+
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlDropDownButtonTemplate.html b/public/javascripts/dojo/src/widget/templates/HtmlDropDownButtonTemplate.html new file mode 100644 index 0000000..a14822e --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlDropDownButtonTemplate.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbar.css b/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbar.css new file mode 100644 index 0000000..abdf7df --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbar.css @@ -0,0 +1,138 @@ +.StyleDropdownContainer { + position: absolute; + z-index: 1000; + overflow: auto; + cursor: default; + width: 250px; + height: 250px; + background-color: white; + border: 1px solid black; +} + +.ColorDropdownContainer { + position: absolute; + z-index: 1000; + overflow: auto; + cursor: default; + width: 250px; + height: 150px; + background-color: white; + border: 1px solid black; +} + +.EditorToolbarDomNode { + background-image: url(buttons/bg-fade.png); + background-repeat: repeat-x; + background-position: 0px -50px; +} + +.EditorToolbarSmallBg { + background-image: url(images/toolbar-bg.gif); + background-repeat: repeat-x; + background-position: 0px 0px; +} + +/* +body { + background:url(images/blank.gif) fixed; +}*/ + +.IEFixedToolbar { + position:absolute; + /* top:0; */ + top: expression(eval((document.documentElement||document.body).scrollTop)); +} + +div.bigIcon { + width: 40px; + height: 40px; + /* background-color: white; */ + /* border: 1px solid #a6a7a3; */ + font-family: Verdana, Trebuchet, Tahoma, Arial; +} + +.iconContainer { + font-family: Verdana, Trebuchet, Tahoma, Arial; + font-size: 13px; + float: left; + height: 18px; + display: block; + /* background-color: white; */ + /* border: 1px solid white; */ + /* border: 1px solid #a6a7a3; */ + padding-right: 3px; + cursor: pointer; + border: 1px solid transparent; + _border: none; +} + +span.icon { + display: block; + text-align: center; + min-width: 18px; + width: 18px; + height: 18px; + /* background-color: #a6a7a3; */ + background-repeat: no-repeat; + background-image: url(buttons/aggregate.gif); +} + + +span.icon[class~=icon] { +} + +.headingContainer { + width: 150px; + height: 30px; + margin: 0px; + /* padding-left: 5px; */ + overflow: hidden; + line-height: 25px; + border-bottom: 1px solid black; + border-top: 1px solid white; +} + +.EditorToolbarDomNode select { + font-size: 14px; +} + +.sep { width: 5px; min-width: 5px; max-width: 5px; background-position: 0px 0px} +.backcolor { background-position: -18px 0px} +.bold { background-position: -36px 0px} +.cancel { background-position: -54px 0px} +.copy { background-position: -72px 0px} +.createlink { background-position: -90px 0px} +.cut { background-position: -108px 0px} +.delete { background-position: -126px 0px} +.forecolor { background-position: -144px 0px} +.hilitecolor { background-position: -162px 0px} +.indent { background-position: -180px 0px} +.inserthorizontalrule { background-position: -198px 0px} +.insertimage { background-position: -216px 0px} +.insertorderedlist { background-position: -234px 0px} +.inserttable { background-position: -252px 0px} +.insertunorderedlist { background-position: -270px 0px} +.italic { background-position: -288px 0px} +.justifycenter { background-position: -306px 0px} +.justifyfull { background-position: -324px 0px} +.justifyleft { background-position: -342px 0px} +.justifyright { background-position: -360px 0px} +.left_to_right { background-position: -378px 0px} +.list_bullet_indent { background-position: -396px 0px} +.list_bullet_outdent { background-position: -414px 0px} +.list_num_indent { background-position: -432px 0px} +.list_num_outdent { background-position: -450px 0px} +.outdent { background-position: -468px 0px} +.paste { background-position: -486px 0px} +.redo { background-position: -504px 0px} +.removeformat { background-position: -522px 0px} +.right_to_left { background-position: -540px 0px} +.save { background-position: -558px 0px} +.space { background-position: -576px 0px} +.strikethrough { background-position: -594px 0px} +.subscript { background-position: -612px 0px} +.superscript { background-position: -630px 0px} +.underline { background-position: -648px 0px} +.undo { background-position: -666px 0px} +.wikiword { background-position: -684px 0px} + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbar.html b/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbar.html new file mode 100644 index 0000000..4e32fba --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbar.html @@ -0,0 +1,152 @@ +
+ + + + + + + + + + + + +
+
+ + W + +
+
+
+ + S + +
+ +
+ + +   copy + + + +   + + +   + + +   + + +   + + +   + + +   + +
+ + +   paste + + + +   undo + + +   redo + +
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbarOneline.html b/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbarOneline.html new file mode 100644 index 0000000..2927e22 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlEditorToolbarOneline.html @@ -0,0 +1,274 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +   + + + + +   + + + + + +   + + + + +   + + + + + + + + + +   + + + + + + + +   + + + + +   + + + + +   + + + + +   + + + + +   + + + + + + + + + +   + + + + +   + + + + + + + + + +   + + + + +   + + + + + + + + + +   + + + + + +   + + + + + + + + + + +   + + + + +   + + + + +   + + + + +   + + + + +  
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlFisheyeList.css b/public/javascripts/dojo/src/widget/templates/HtmlFisheyeList.css new file mode 100644 index 0000000..749141e --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlFisheyeList.css @@ -0,0 +1,27 @@ +.dojoHtmlFisheyeListItemLabel { + font-family: Arial, Helvetica, sans-serif; + background-color: #eee; + border: 2px solid #666; + padding: 2px; + text-align: center; + position: absolute; + display: none; +} + +.dojoHtmlFisheyeListItemLabel.selected { + display: block; +} + +.dojoHtmlFisheyeListItemImage { + border: 0px; + position: absolute; +} + +.dojoHtmlFisheyeListItem { + position: absolute; + z-index: 2; +} + +.dojoHtmlFisheyeListBar { + position: relative; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlFloatingPane.css b/public/javascripts/dojo/src/widget/templates/HtmlFloatingPane.css new file mode 100644 index 0000000..1042a19 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlFloatingPane.css @@ -0,0 +1,118 @@ + +/********** Outer Window ***************/ + +.dojoFloatingPane { + /* essential css */ + position: absolute; + overflow: visible; /* so drop shadow is displayed */ + z-index: 10; + + /* styling css */ + border: 1px solid; + border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight; + background-color: ThreeDFace; +} + + +/********** Title Bar ****************/ + +.dojoFloatingPaneTitleBar { + vertical-align: top; + margin: 2px 2px 2px 2px; + z-index: 10; + background-color: #7596c6; + cursor: default; + overflow: hidden; + border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight; + vertical-align: middle; +} + +.dojoFloatingPaneTitleText { + float: left; + padding: 2px 4px 2px 2px; + white-space: nowrap; + color: CaptionText; + font: small-caption; +} + +.dojoTitleBarIcon { + float: left; + height: 22px; + width: 22px; + vertical-align: middle; + margin-right: 5px; + margin-left: 5px; +} + +.dojoFloatingPaneActions{ + float: right; + position: absolute; + right: 2px; + top: 2px; + vertical-align: middle; +} + + +.dojoFloatingPaneActionItem { + vertical-align: middle; + margin-right: 1px; + height: 22px; + width: 22px; +} + + +.dojoFloatingPaneTitleBarIcon { + /* essential css */ + float: left; + + /* styling css */ + margin-left: 2px; + margin-right: 4px; + height: 22px; +} + +/* minimize/maximize icons are specified by CSS only */ +.dojoFloatingPaneMinimizeIcon, +.dojoFloatingPaneMaximizeIcon, +.dojoFloatingPaneRestoreIcon, +.dojoFloatingPaneCloseIcon { + vertical-align: middle; + height: 22px; + width: 22px; + float: right; +} +.dojoFloatingPaneMinimizeIcon { + background-image: url(images/floatingPaneMinimize.gif); +} +.dojoFloatingPaneMaximizeIcon { + background-image: url(images/floatingPaneMaximize.gif); +} +.dojoFloatingPaneRestoreIcon { + background-image: url(images/floatingPaneRestore.gif); +} +.dojoFloatingPaneCloseIcon { + background-image: url(images/floatingPaneClose.gif); +} + +/* bar at bottom of window that holds resize handle */ +.dojoFloatingPaneResizebar { + z-index: 10; + height: 13px; + background-color: ThreeDFace; +} + +/************* Client Area ***************/ + +.dojoFloatingPaneClient { + position: relative; + z-index: 10; + border: 1px solid; + border-color: ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow; + margin: 2px; + background-color: ThreeDFace; + padding: 8px; + font-family: Verdana, Helvetica, Garamond, sans-serif; + font-size: 12px; + overflow: auto; +} + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlFloatingPane.html b/public/javascripts/dojo/src/widget/templates/HtmlFloatingPane.html new file mode 100644 index 0000000..07e81ed --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlFloatingPane.html @@ -0,0 +1,18 @@ +
+ + +
+ + +
\ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlInlineEditBox.css b/public/javascripts/dojo/src/widget/templates/HtmlInlineEditBox.css new file mode 100644 index 0000000..f4dde8b --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlInlineEditBox.css @@ -0,0 +1,24 @@ +.editLabel { + font-size : small; + padding : 0 5px; + display : none; +} + +.editableRegion { + background-color : #ffc !important; + cursor : pointer; + _cursor : hand; +} + +.editableRegion .editLabel { + display : inline; +} + +.editableTextareaRegion .editLabel { + display : block; +} + +.inlineEditBox { + /*background-color : #ffc;*/ + display : inline; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlInlineEditBox.html b/public/javascripts/dojo/src/widget/templates/HtmlInlineEditBox.html new file mode 100644 index 0000000..7eb0227 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlInlineEditBox.html @@ -0,0 +1,6 @@ + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlMenu2.css b/public/javascripts/dojo/src/widget/templates/HtmlMenu2.css new file mode 100644 index 0000000..fb83d78 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlMenu2.css @@ -0,0 +1,179 @@ + +.dojoPopupMenu2 { + position: absolute; + border: 1px solid #7298d0; + background:#a9ccfe url(images/soriaMenuBg.gif) repeat-x bottom left !important; + padding: 1px; + margin-top: 1px; + margin-bottom: 1px; +} + +.dojoMenuItem2, .dojoMenuItem2 span span { + white-space: nowrap; + font: menu; + margin: 0; +} + +.dojoMenuItem2 span { + margin: 0; + padding-right:5px; +} + +.dojoMenuItem2Hover { + background-color: #D2E4FD; + cursor:pointer; + cursor:hand; +} + +.dojoMenuItem2Icon { + position: relative; + background-position: center center; + background-repeat: no-repeat; + z-index: 1; + width: 16px; + height: 16px; +} + +.dojoMenuItem2Label { + position: relative; + vertical-align: middle; + z-index: 1; +} + +/* main label text */ +.dojoMenuItem2Label span { + position: relative; + vertical-align: middle; + z-index: 2; +} + +/* label shadow text */ +.dojoMenuItem2Label span span { + position: absolute; + display: none; + left: 1px; + top: 1px; + z-index: -2; +} + +.dojoMenuItem2Accel { + position: relative; + vertical-align: middle; + z-index: 1; +} + +/* accelerator string */ +.dojoMenuItem2Accel span { + position: relative; + vertical-align: middle; + z-index: 2; +} + +/* accelerator string shadow */ +.dojoMenuItem2Accel span span { + position: absolute; + display: none; + left: 1px; + top: 1px; + z-index: -2; +} + +.dojoMenuItem2Disabled .dojoMenuItem2Label span, +.dojoMenuItem2Disabled .dojoMenuItem2Accel span { + color: #607a9e; +} + +.dojoMenuItem2Disabled .dojoMenuItem2Label span span, +.dojoMenuItem2Disabled .dojoMenuItem2Accel span span { + display: block; +} + +.dojoMenuItem2Hover .dojoMenuItem2Label span span, +.dojoMenuItem2Hover .dojoMenuItem2Accel span span { + display: none; +} + +.dojoMenuItem2Submenu { + position: relative; + background-position: center center; + background-repeat: no-repeat; + background-image: url(images/submenu_off.gif); + width: 5px; + height: 9px; +} +.dojoMenuItem2Hover .dojoMenuItem2Submenu { + background-image: url(images/submenu_on.gif); +} + +.dojoMenuSeparator2 { + font-size: 1px; + margin: 0; +} + +.dojoMenuSeparator2Top { + height: 50%; + border-bottom: 1px solid #7996c1; + margin: 0px 2px; + font-size: 1px; +} + +.dojoMenuSeparator2Bottom { + height: 50%; + border-top: 1px solid #e3eeff; + margin: 0px 2px; + font-size: 1px; +} + +.dojoMenuBar2 { + /*position: relative;*/ + background:#a9ccfe url(images/soriaBarBg.gif) repeat-x bottom left; + border-bottom:1px solid #405067; + border-top:1px solid #708bb3; +} + +.dojoMenuBar2Client { + padding: 1px; +} + +.dojoMenuBarItem2 { + white-space: nowrap; + font: menu; + margin: 0; + position: relative; + vertical-align: middle; + z-index: 1; + padding: 3px 8px; +} + +.dojoMenuBarItem2 span { + margin: 0; + position: relative; + z-index: 2; + cursor:pointer; + cursor:hand; +} + +.dojoMenuBarItem2 span span { + position: absolute; + display: none; + left: 1px; + top: 1px; + z-index: -2; +} + +.dojoMenuBarItem2Hover { + background-color:#d2e4fd; +} + +.dojoMenuBarItem2Disabled span { + color: #4f6582; +} + +.dojoMenuBarItem2Disabled span span { + display: block; +} + +.dojoMenuBarItem2Hover span span, +.dojoMenuBarItem2Hover span span { + display: none; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlMenuItemTemplate.html b/public/javascripts/dojo/src/widget/templates/HtmlMenuItemTemplate.html new file mode 100644 index 0000000..36249b1 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlMenuItemTemplate.html @@ -0,0 +1,2 @@ +
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlMonthlyCalendar.css b/public/javascripts/dojo/src/widget/templates/HtmlMonthlyCalendar.css new file mode 100644 index 0000000..c646902 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlMonthlyCalendar.css @@ -0,0 +1,91 @@ +.datePickerContainer { + margin:0.5em 2em 0.5em 0; + /*width:10em;*/ + float:left; +} + +.previousMonth { + background-color:#bbbbbb; +} + +.currentMonth { + background-color:#8f8f8f; +} + +.nextMonth { + background-color:#eeeeee; +} + +.currentDate { + text-decoration:underline; + font-style:italic; +} + +.selectedItem { + background-color:#3a3a3a; + color:#ffffff; +} + +.calendarContainer { + border-collapse:collapse; + border-spacing:0; + border-bottom:1px solid #e6e6e6; + overflow: hidden; + text-align: right; +} + +.calendarContainer thead{ + border-bottom:1px solid #e6e6e6; +} + +.calendarContainer tbody * td { + height: 100px; + border: 1px solid gray; +} + +.calendarContainer td { + width: 100px; + padding: 2px; + vertical-align: top; +} + +.monthLabel { + font-size:0.9em; + font-weight:400; + margin:0; + text-align:center; +} + +.monthLabel .month { + padding:0 0.4em 0 0.4em; +} + +.yearLabel { + font-size:0.9em; + font-weight:400; + margin:0.25em 0 0 0; + text-align:right; + color:#a3a3a3; +} + +.yearLabel .selectedYear { + color:#000; + padding:0 0.2em; +} + +.nextYear, .previousYear { + cursor:pointer;cursor:hand; +} + +.incrementControl { + cursor:pointer;cursor:hand; + width:1em; +} + +.dojoMonthlyCalendarEvent { + font-size:0.7em; + overflow: hidden; + font-color: grey; + white-space: nowrap; + text-align: left; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlMonthlyCalendar.html b/public/javascripts/dojo/src/widget/templates/HtmlMonthlyCalendar.html new file mode 100644 index 0000000..98ab4a6 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlMonthlyCalendar.html @@ -0,0 +1,110 @@ +
+

+ + + ↑ + + July + + ↓ + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SundayMondayTuesdayWednesdayThursdayFridaySaturday
+

+ + + +

+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlResizableTextarea.css b/public/javascripts/dojo/src/widget/templates/HtmlResizableTextarea.css new file mode 100644 index 0000000..8f0cf23 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlResizableTextarea.css @@ -0,0 +1,15 @@ +div.statusBar { + background-color: ThreeDFace; + height: 28px; + padding: 1px; + overflow: hidden; + font-size: 12px; +} + +div.statusPanel { + background-color: ThreeDFace; + border: 1px solid; + border-color: ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow; + margin: 1px; + padding: 2px 6px; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlResizableTextarea.html b/public/javascripts/dojo/src/widget/templates/HtmlResizableTextarea.html new file mode 100644 index 0000000..88827f7 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlResizableTextarea.html @@ -0,0 +1,14 @@ +
+
+
+
+
+
drag to resize
+
+
+
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlResizeHandle.css b/public/javascripts/dojo/src/widget/templates/HtmlResizeHandle.css new file mode 100644 index 0000000..661a86a --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlResizeHandle.css @@ -0,0 +1,12 @@ +.dojoHtmlResizeHandle { + float: right; + position: absolute; + right: 2px; + bottom: 2px; + width: 13px; + height: 13px; + z-index: 20; + cursor: nw-resize; + background-image: url(grabCorner.gif); + line-height: 0px; +} \ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlShow.css b/public/javascripts/dojo/src/widget/templates/HtmlShow.css new file mode 100644 index 0000000..6378bf1 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlShow.css @@ -0,0 +1,59 @@ +@media screen { + html, body { + margin: 0px; + padding: 0px; + width: 100%; + } + body { + display: none; + } + h1 { + font-size: 50px; + } + p, li { + font-size: 30px; + } + .dojoShowNav { + background: #369; + overflow: hidden; + position: absolute; + height: 5px; + bottom: 0px; + left: 0px; + width: 100%; + text-align: center; + } + .dojoShowNav input { + margin: 0px; + } + .dojoShowHider { + height: 5px; + overflow: hidden; + width: 100%; + } + .dojoShowPrint { + position: absolute; + left: 5px; + top: 0px; + } +} +@media print { + .dojoShow { + display: none !important; + } + .dojoShowPrint { + display: block !important; + } + .dojoShowPrintSlide { + border: 1px solid #aaa; + padding: 10px; + margin-bottom: 15px; + } + .dojoShowPrintSlide, ul { + page-break-inside: avoid; + } + h1 { + margin-top: 0; + page-break-after: avoid; + } +} \ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlShow.html b/public/javascripts/dojo/src/widget/templates/HtmlShow.html new file mode 100644 index 0000000..c7610fe --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlShow.html @@ -0,0 +1,11 @@ +
+
+
+
+ < + + > +
+
\ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlShowSlide.css b/public/javascripts/dojo/src/widget/templates/HtmlShowSlide.css new file mode 100644 index 0000000..6e55c82 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlShowSlide.css @@ -0,0 +1,12 @@ +.dojoShowSlideTitle { + height: 100px; + background: #369; +} +.dojoShowSlideTitle h1 { + margin-top: 0; + line-height: 100px; + margin-left: 30px; +} +.dojoShowSlideBody { + margin: 15px; +} \ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlShowSlide.html b/public/javascripts/dojo/src/widget/templates/HtmlShowSlide.html new file mode 100644 index 0000000..5a49586 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlShowSlide.html @@ -0,0 +1,6 @@ +
+
+

Title

+
+
+
\ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSimpleDropdownButtons.css b/public/javascripts/dojo/src/widget/templates/HtmlSimpleDropdownButtons.css new file mode 100644 index 0000000..e72afbd --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSimpleDropdownButtons.css @@ -0,0 +1,100 @@ +ul.dojoSimpleDropdownButtons { + margin : 0; + padding : 5px 0; +} + +ul.dojoSimpleDropdownButtons li { + display : inline; + margin-right : 5px; + padding : 2px 0; +} + +ul.dojoSimpleDropdownButtons li a { + padding : 2px 9px; + border : 2px outset #ccc; + border-right-width : 1px; + background : #f4f4f4; + color : #333; + text-decoration : none; +} + +ul.dojoSimpleDropdownButtons li ul { + display : none; +} + +ul.dojoSimpleDropdownButtons li a.disabled { + color : #999; + cursor : default; +} + +ul.dojoSimpleDropdownButtons li .downArrow { + display : inline; + padding : 2px 4px; + border : 2px outset #ccc; + border-left : 0; + background : #f4f4f4 url(images/dropdownButtonsArrow.gif) no-repeat 4px 9px; + text-decoration : none; + color : black; + cursor : pointer; + _cursor : hand; +} + +ul.dojoSimpleDropdownButtons li .downArrow.disabled { + background-image : url(images/dropdownButtonsArrow-disabled.gif); + cursor : default; +} + +ul.dojoSimpleDropdownButtons li a:hover, +ul.dojoSimpleDropdownButtons li span.downArrow:hover { + color : black; + background-color : #ddd; +} + +ul.dojoSimpleDropdownButtons li .downArrow.pressed, ul.dojoSimpleDropdownButtons li .downArrow:focus { + border-style : inset; + background-position : 5px 10px; + padding : 2px 4px; +} + +ul.dojoSimpleDropdownButtons li a.disabled:hover, +ul.dojoSimpleDropdownButtons li span.downArrow.disabled:hover { + color : #999; + background-color : #f4f4f4; +} + +ul.dojoSimpleDropdownButtons li a:focus { + padding : 3px 8px 1px 10px; + color : #333; + border-style : inset; +} + +/* Menu + ******************** */ +ul.dojoSimpleDropdownButtonsMenu { + position : absolute; + margin : 0; + _margin : -2px; + padding : 0; + display : none; + border : 1px solid #aaa; + background : #f4f4f4; + list-style : none; + z-index : 99; +} + +ul.dojoSimpleDropdownButtonsMenu li { + _display : inline; +} + +ul.dojoSimpleDropdownButtonsMenu a { + display : block; + padding : 2px 5px; + color : #333; + text-decoration : none; +} + +ul.dojoSimpleDropdownButtonsMenu a:hover { + background : #ddd; + color : black; +} + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSlideShow.css b/public/javascripts/dojo/src/widget/templates/HtmlSlideShow.css new file mode 100644 index 0000000..02e97cd --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSlideShow.css @@ -0,0 +1,9 @@ +.slideShowImg { + position: absolute; + left: 0px; + top: 0px; + border: 2px solid #4d4d4d; + padding: 0px; + margin: 0px; +} + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSlideShow.html b/public/javascripts/dojo/src/widget/templates/HtmlSlideShow.html new file mode 100644 index 0000000..93b836b --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSlideShow.html @@ -0,0 +1,15 @@ +
+
+ +
+
+ + +
+
\ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSlider.css b/public/javascripts/dojo/src/widget/templates/HtmlSlider.css new file mode 100644 index 0000000..7407aac --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSlider.css @@ -0,0 +1,61 @@ +.sliderMain { + border: 0px !important; + border-spacing: 0px !important; + line-height: 0px !important; + padding: 0px !important; + display: -moz-inline-table !important; + display: inline !important; + -moz-user-focus: normal !important; +} + +.sliderComponent { + border: 0px; + padding: 0px; + margin: 0px; +} + +.sliderHandle { + top: 0px; + left: 0px; + z-index: 1000; + position: absolute !important; +} + +.sliderOutsetButton { + border-style: outset; + border-width: 0px 1px 1px 0px; + border-color: black; +} + +.sliderInsetButton { + border-style: inset; + border-width: 1px 0px 0px 1px; + border-color: black; +} + +.sliderButtonY { + margin: 0px; + padding: 0px; + z-index: 900; +} + +.sliderButtonX { + margin: 0px; + padding: 0px; + z-index: 900; +} + +.sliderBackground { + z-index: 0; + display: block !important; + position: relative !important; +} + +.sliderProgressBackground { + z-index: 800; + position: absolute !important; + clip: rect(0px,0px,0px,0px); +} + +.sliderBackgroundSizeOnly { +} \ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSlider.html b/public/javascripts/dojo/src/widget/templates/HtmlSlider.html new file mode 100644 index 0000000..3280820 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSlider.html @@ -0,0 +1,54 @@ +
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSliderHorizontal.html b/public/javascripts/dojo/src/widget/templates/HtmlSliderHorizontal.html new file mode 100644 index 0000000..0b6da69 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSliderHorizontal.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSliderVertical.html b/public/javascripts/dojo/src/widget/templates/HtmlSliderVertical.html new file mode 100644 index 0000000..d077d33 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSliderVertical.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSpinner.css b/public/javascripts/dojo/src/widget/templates/HtmlSpinner.css new file mode 100644 index 0000000..7c22315 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSpinner.css @@ -0,0 +1,34 @@ +/* inline the table holding the and buttons (method varies by browser) */ +.ie .dojoSpinner, .safari .dojoSpinner { + display: inline; +} + +.moz .dojoSpinner { + display: -moz-inline-box; +} + +.opera .dojoSpinner { + display: inline-table; +} + +/* generic stuff for the table */ +.dojoSpinner td { + padding:0px; + margin:0px; + vertical-align: middle; +} +table.dojoSpinner { + border:0px; + border-spacing:0px; + line-height:0px; + padding:0px; + margin: 0px; + vertical-align: middle; +} + +/* the buttons */ +.dojoSpinner img { + display: block; + border-width:0px 1px 1px 0px; + border-style:outset; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSpinner.html b/public/javascripts/dojo/src/widget/templates/HtmlSpinner.html new file mode 100644 index 0000000..07b15ea --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSpinner.html @@ -0,0 +1,24 @@ + + + + + +
+ + + + +
${this.invalidMessage}${this.missingMessage}${this.rangeMessage}
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlSplitContainer.css b/public/javascripts/dojo/src/widget/templates/HtmlSplitContainer.css new file mode 100644 index 0000000..43b54bb --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlSplitContainer.css @@ -0,0 +1,39 @@ +.dojoSplitContainer{ + position: relative; + overflow: hidden; +} + +.dojoSplitPane{ + position: absolute; +} + +.dojoSplitContainerSizerH, +.dojoSplitContainerSizerV { + font-size: 1px; + cursor: move; + cursor: w-resize; + background-color: ThreeDFace; + border: 1px solid; + border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight; + margin: 0; +} + +.dojoSplitContainerSizerV { + cursor: n-resize; +} + +.dojoSplitContainerVirtualSizerH, +.dojoSplitContainerVirtualSizerV { + font-size: 1px; + cursor: move; + cursor: w-resize; + background-color: ThreeDShadow; + -moz-opacity: 0.5; + opacity: 0.5; + filter: Alpha(Opacity=50); + margin: 0; +} + +.dojoSplitContainerVirtualSizerV { + cursor: n-resize; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTabContainer.css b/public/javascripts/dojo/src/widget/templates/HtmlTabContainer.css new file mode 100644 index 0000000..e15bd8f --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTabContainer.css @@ -0,0 +1,181 @@ +.dojoTabContainer { + position : relative; +} + +.dojoTabPaneWrapper { + position : relative; + border : 1px solid #6290d2; + clear: both; + _zoom: 1; /* force IE6 layout mode so top border doesnt disappear */ +} + +.dojoTabLabels-top { + position : absolute; + top : 0px; + left : 0px; + overflow : visible; + margin-bottom : -1px; + width : 100%; + z-index: 2; /* so the bottom of the tab label will cover up the border of dojoTabPaneWrapper */ +} + +.dojoTabNoLayout.dojoTabLabels-top { + position : relative; +} + +.dojoTabNoLayout.dojoTabLabels-top .dojoTabPaneTab { + margin-bottom: -1px; + _margin-bottom: 0px; /* IE filter so top border lines up correctly */ +} + +.dojoTabPaneTab { + position : relative; + float : left; + padding-left : 9px; + border-bottom : 1px solid #6290d2; + background : url(images/tab_left.gif) no-repeat left top; + cursor: pointer; + white-space: nowrap; + z-index: 3; +} + +.dojoTabPaneTab div { + display : block; + padding : 4px 15px 4px 6px; + background : url(images/tab_top_right.gif) no-repeat right top; + color : #333; + font-size : 90%; +} + +.dojoTabPanePaneClose { + position : absolute; + bottom : 0px; + right : 6px; + height : 12px; + width : 12px; + background : url(images/tab_close.gif) no-repeat right top; +} + +.dojoTabPanePaneCloseHover { + background-image : url(images/tab_close_h.gif); +} + +.dojoTabPaneTabClose { + display : inline-block; + height : 12px; + width : 12px; + padding : 0 12px 0 0; + margin : 0 -10px 0 10px; + background : url(images/tab_close.gif) no-repeat right top; + cursor : default; +} + +.dojoTabPaneTabCloseHover { + background-image : url(images/tab_close_h.gif); +} + +.dojoTabPaneTab.current { + padding-bottom : 1px; + border-bottom : 0; + background-position : 0 -150px; +} + +.dojoTabPaneTab.current div { + padding-bottom : 5px; + margin-bottom : -1px; + background-position : 100% -150px; +} + +/* bottom tabs */ + +.dojoTabLabels-bottom { + position : absolute; + bottom : 0px; + left : 0px; + overflow : visible; + margin-top : -1px; + width : 100%; + z-index: 2; +} + +.dojoTabNoLayout.dojoTabLabels-bottom { + position : relative; +} + +.dojoTabLabels-bottom .dojoTabPaneTab { + border-top : 1px solid #6290d2; + border-bottom : 0; + background : url(images/tab_bot_left.gif) no-repeat left bottom; +} + +.dojoTabLabels-bottom .dojoTabPaneTab div { + background : url(images/tab_bot_right.gif) no-repeat right bottom; +} + +.dojoTabLabels-bottom .dojoTabPaneTab.current { + border-top : 0; + background : url(images/tab_bot_left_curr.gif) no-repeat left bottom; +} + +.dojoTabLabels-bottom .dojoTabPaneTab.current div { + padding-top : 4px; + background : url(images/tab_bot_right_curr.gif) no-repeat right bottom; +} + +/* right-h tabs */ + +.dojoTabLabels-right-h { + position : absolute; + top : 0px; + right : 0px; + overflow : visible; + margin-left : -1px; + z-index: 2; +} + +.dojoTabLabels-right-h .dojoTabPaneTab { + padding-left : 0; + border-left : 1px solid #6290d2; + border-bottom : 0; + background : url(images/tab_bot_right.gif) no-repeat right bottom; + float : none; +} + +.dojoTabLabels-right-h .dojoTabPaneTab div { + padding : 4px 15px 4px 15px; +} + +.dojoTabLabels-right-h .dojoTabPaneTab.current { + border-left : 0; + border-bottom : 1px solid #6290d2; +} + +/* left-h tabs */ + +.dojoTabLabels-left-h { + position : absolute; + top : 0px; + left : 0px; + overflow : visible; + margin-right : -1px; + z-index: 2; +} + +.dojoTabLabels-left-h .dojoTabPaneTab { + border-right : 1px solid #6290d2; + border-bottom : 0; + float : none; + background : url(images/tab_top_left.gif) no-repeat left top; +} + +.dojoTabLabels-left-h .dojoTabPaneTab.current { + border-right : 0; + border-bottom : 1px solid #6290d2; + padding-bottom : 0; + background : url(images/tab_top_left.gif) no-repeat 0 -150px; +} + +.dojoTabLabels-left-h .dojoTabPaneTab div { + background : 0; + border-bottom : 1px solid #6290d2; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTabContainer.html b/public/javascripts/dojo/src/widget/templates/HtmlTabContainer.html new file mode 100644 index 0000000..2a978f1 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTabContainer.html @@ -0,0 +1,4 @@ +
+
+
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTaskBar.css b/public/javascripts/dojo/src/widget/templates/HtmlTaskBar.css new file mode 100644 index 0000000..5f55a7c --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTaskBar.css @@ -0,0 +1,29 @@ +.dojoTaskBarItem { + display: inline-block; + background-color: ThreeDFace; + border: outset 2px; + margin-right: 5px; + cursor: pointer; + height: 35px; + width: 100px; + font-size: 10pt; + white-space: nowrap; + text-align: center; + float: left; + overflow: hidden; +} + +.dojoTaskBarItem img { + vertical-align: middle; + margin-right: 5px; + margin-left: 5px; + height: 32px; + width: 32px; +} + +.dojoTaskBarItem a { + color: black; + text-decoration: none; +} + + diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTaskBarItemTemplate.html b/public/javascripts/dojo/src/widget/templates/HtmlTaskBarItemTemplate.html new file mode 100644 index 0000000..aeb19d6 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTaskBarItemTemplate.html @@ -0,0 +1,2 @@ +
+
\ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTimePicker.css b/public/javascripts/dojo/src/widget/templates/HtmlTimePicker.css new file mode 100644 index 0000000..00bc2e9 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTimePicker.css @@ -0,0 +1,179 @@ +/*Time Picker */ +.timePickerContainer { + width:10em; + font-family:Tahoma, Myriad, Helvetica, Arial, Verdana, sans-serif; + font-size:16px; +} + +.timeContainer { + border-collapse:collapse; + border-spacing:0; +} + +.timeContainer thead { + color:#293a4b; + font-size:0.9em; + font-weight:700; +} + +.timeContainer thead td { + padding:0.25em; + font-size:0.80em; + border-bottom:1px solid #6782A8; +} + +.timeCorner { + width:10px; +} + +.cornerTopLeft { + background: url("images/dpCurveTL.png") top left no-repeat; +} + +.cornerTopRight { + background: url("images/dpCurveTR.png") top right no-repeat; +} + +.timeLabelContainer { + background: url("images/dpMonthBg.png") top left repeat-x; +} + +.hours, .minutes, .timeBorder { + background: #7591bc url("images/dpBg.gif") top left repeat-x; + +} + +.hours td, .minutes td { + padding:0.2em; + text-align:center; + font-size:0.7em; + font-weight:bold; + cursor:pointer; + cursor:hand; + color:#fff; +} + +.minutes { + border-left:1px solid #f5d1db; +} + +.hours { + border-right:1px solid #6782A8; +} + +.hourSelector { + border-right:1px solid #6782A8; + padding:5px; + padding-right:10px; +} + +.minutesSelector { + padding:5px; + border-left:1px solid #f5c7d4; + text-align:center; +} + +.minutesHeading { + padding-left:9px !important; +} + +.timeOptions { + background-color:#F9C9D7; +} + +.timeContainer .cornerBottomLeft, .timeContainer .cornerBottomRight, .timeContainer .timeOptions { + border-top:1px solid #6782A8; +} + +.timeContainer .cornerBottomLeft { + background: url("images/dpCurveBL.png") bottom left no-repeat !important; + width:9px !important; + padding:0; + margin:0; +} + +.timeContainer .cornerBottomRight { + background: url("images/dpCurveBR.png") bottom right no-repeat !important; + width:9px !important; + padding:0; + margin:0; +} + +.timeOptions { + color:#fff; + background:url("images/dpYearBg.png") top left repeat-x; + +} + +.selectedItem { + background-color:#fff; + color:#6782a8 !important; +} + +.timeOptions .selectedItem { + color:#fff !important; + background-color:#9ec3fb !important; +} + +.anyTimeContainer { + text-align:center; + font-weight:bold; + font-size:0.7em; + padding:0.1em; + cursor:pointer; + cursor:hand; + color:#fff !important; +} + +.amPmContainer { + width:100%; +} + +.amPmContainer td { + text-align:center; + font-size:0.7em; + font-weight:bold; + cursor:pointer; + cursor:hand; + color:#fff; +} + + + +/*.timePickerContainer { + margin:1.75em 0 0.5em 0; + width:10em; + float:left; +} + +.timeContainer { + border-collapse:collapse; + border-spacing:0; +} + +.timeContainer thead td{ + border-bottom:1px solid #e6e6e6; + padding:0 0.4em 0.2em 0.4em; +} + +.timeContainer td { + font-size:0.9em; + padding:0 0.25em 0 0.25em; + text-align:left; + cursor:pointer;cursor:hand; +} + +.timeContainer td.minutesHeading { + border-left:1px solid #e6e6e6; + border-right:1px solid #e6e6e6; +} + +.timeContainer .minutes { + border-left:1px solid #e6e6e6; + border-right:1px solid #e6e6e6; +} + +.selectedItem { + background-color:#3a3a3a; + color:#ffffff; +}*/ diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTimePicker.html b/public/javascripts/dojo/src/widget/templates/HtmlTimePicker.html new file mode 100644 index 0000000..9458bc0 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTimePicker.html @@ -0,0 +1,98 @@ +
+ + + + + + + + + + + + + + + + + + + + + +
 HourMinute 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
126
17
28
39
410
511
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
0030
0535
1040
1545
2050
2555
+
  + + + + + + + +
AMPM
+
+
any
+
 
+
diff --git a/public/javascripts/dojo/src/widget/templates/HtmlToaster.css b/public/javascripts/dojo/src/widget/templates/HtmlToaster.css new file mode 100644 index 0000000..b768002 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlToaster.css @@ -0,0 +1,42 @@ +.dojoToasterClip { + position: absolute; + overflow: hidden; +} + +.dojoToasterContainer { + display: block; + position: absolute; + width: 17.5em; + z-index: 5000; + margin: 0px; + font:0.75em Tahoma, Helvetica, Verdana, Arial; +} + +.dojoToasterContent{ + padding:1em; + padding-top:0.25em; + background:#73c74a; +} + +.dojoToasterMessage{ + color:#fff; +} +.dojoToasterWarning{ } +.dojoToasterError, +.dojoToasterFatal{ + font-weight:bold; + color:#fff; +} + + +.dojoToasterWarning .dojoToasterContent{ + padding:1em; + padding-top:0.25em; + background:#d4d943; +} + +.dojoToasterError .dojoToasterContent{ + padding:1em; + padding-top:0.25em; + background:#c46600; +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlToolbar.css b/public/javascripts/dojo/src/widget/templates/HtmlToolbar.css new file mode 100644 index 0000000..b5fe8d5 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlToolbar.css @@ -0,0 +1,54 @@ +.toolbarContainer { + border-bottom : 0; + background-color : #def; + color : ButtonText; + font : Menu; + background-image: url(images/toolbar-bg.gif); +} + +.toolbar { + padding : 2px 4px; + min-height : 26px; + _height : 26px; +} + +.toolbarItem { + float : left; + padding : 1px 2px; + margin : 0 2px 1px 0; + cursor : pointer; +} + +.toolbarItem.selected, .toolbarItem.down { + margin : 1px 1px 0 1px; + padding : 0px 1px; + border : 1px solid #bbf; + background-color : #fafaff; +} + +.toolbarButton img { + vertical-align : bottom; +} + +.toolbarButton span { + line-height : 16px; + vertical-align : middle; +} + +.toolbarButton.hover { + padding : 0px 1px; + border : 1px solid #99c; +} + +.toolbarItem.disabled { + opacity : 0.3; + filter : alpha(opacity=30); + cursor : default; +} + +.toolbarSeparator { + cursor : default; +} + +.toolbarFlexibleSpace { +} diff --git a/public/javascripts/dojo/src/widget/templates/HtmlTooltipTemplate.css b/public/javascripts/dojo/src/widget/templates/HtmlTooltipTemplate.css new file mode 100644 index 0000000..030be2a --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/HtmlTooltipTemplate.css @@ -0,0 +1,10 @@ +.dojoTooltip { + border: solid black 1px; + background: beige; + color: black; + position: absolute; + font-size: small; + padding: 2px 2px 2px 2px; + z-index: 10; + display: block; +} diff --git a/public/javascripts/dojo/src/widget/templates/Menu.css b/public/javascripts/dojo/src/widget/templates/Menu.css new file mode 100644 index 0000000..1419f6d --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/Menu.css @@ -0,0 +1,60 @@ +.dojoMenu { + border:1px solid #000000; + list-style-type:none; + margin:0; + padding:0; + padding-bottom: 1px; + background-color:#f4f4f4; + font-size: 8pt; +} + +.dojoMenuSeparator { + list-style-type:none; + margin:0; + padding:1px 0; + border-bottom:1px solid #000000; + line-height:1px; + height:1px; +} + +li:hover.dojoMenuSeparator { + background-color:#e5e5e5; + cursor:default; +} + + + + +.dojoContextMenu { + position: absolute; + display: none; + border: 2px solid; + border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight; + list-style-type: none; + margin: 0; + padding: 1px; + background-color: ThreeDFace; + font-size: 8pt; +} + +.dojoMenuItem { + white-space: nowrap; + padding: 2px; + font: menu; + color: WindowText; +} + +.dojoMenuItem a { + text-decoration: none; + color: WindowText; + font: inherit; +} + +.dojoMenuItemHover { + padding: 2px; + background-color: blue; + cursor: pointer; + _cursor: hand; + background-color: Highlight; + color: HighlightText; +} \ No newline at end of file diff --git a/public/javascripts/dojo/src/widget/templates/PopUpButton.css b/public/javascripts/dojo/src/widget/templates/PopUpButton.css new file mode 100644 index 0000000..37c5581 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/PopUpButton.css @@ -0,0 +1,35 @@ +.PopUpButton { + padding : 2px 6px 2px 9px; + border : 1px outset #ccc; + background : #f4f4f4; + color : #333; + text-decoration : none; +} + +.PopUpButton .downArrow { + margin-left: 0.5em; + margin-bottom: 2px; +} + +.downArrow.disabled { + background-image : url(images/dropdownButtonsArrow-disabled.gif); + cursor : default; +} + +ul.dropdownButtons li a:hover, +ul.dropdownButtons li span.downArrow:hover { + color : black; + background-color : #ddd; +} + +ul.dropdownButtons li .downArrow.pressed, ul.dropdownButtons li .downArrow:focus { + border-style : inset; + background-position : 5px 10px; + padding : 2px 4px; +} + +ul.dropdownButtons li a.disabled:hover, +ul.dropdownButtons li span.downArrow.disabled:hover { + color : #999; + background-color : #d2e4fd; +} diff --git a/public/javascripts/dojo/src/widget/templates/RemoteTabControl.css b/public/javascripts/dojo/src/widget/templates/RemoteTabControl.css new file mode 100644 index 0000000..c9f54e6 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/RemoteTabControl.css @@ -0,0 +1,61 @@ +.dojoRemoteTabController { + position: relative; +} + +.dojoRemoteTab { + position : relative; + float : left; + padding-left : 9px; + border-bottom : 1px solid #6290d2; + background : url(images/tab_left.gif) no-repeat left top; + cursor: pointer; + white-space: nowrap; + z-index: 3; +} + +.dojoRemoteTab div { + display : block; + padding : 4px 15px 4px 6px; + background : url(images/tab_top_right.gif) no-repeat right top; + color : #333; + font-size : 90%; +} + +.dojoRemoteTabPaneClose { + position : absolute; + bottom : 0px; + right : 6px; + height : 12px; + width : 12px; + background : url(images/tab_close.gif) no-repeat right top; +} + +.dojoRemoteTabPaneCloseHover { + background-image : url(images/tab_close_h.gif); +} + +.dojoRemoteTabClose { + display : inline-block; + height : 12px; + width : 12px; + padding : 0 12px 0 0; + margin : 0 -10px 0 10px; + background : url(images/tab_close.gif) no-repeat right top; + cursor : default; +} + +.dojoRemoteTabCloseHover { + background-image : url(images/tab_close_h.gif); +} + +.dojoRemoteTab.current { + padding-bottom : 1px; + border-bottom : 0; + background-position : 0 -150px; +} + +.dojoRemoteTab.current div { + padding-bottom : 5px; + margin-bottom : -1px; + background-position : 100% -150px; +} diff --git a/public/javascripts/dojo/src/widget/templates/Textbox.html b/public/javascripts/dojo/src/widget/templates/Textbox.html new file mode 100644 index 0000000..3b586fa --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/Textbox.html @@ -0,0 +1,5 @@ + + + diff --git a/public/javascripts/dojo/src/widget/templates/TitlePane.html b/public/javascripts/dojo/src/widget/templates/TitlePane.html new file mode 100644 index 0000000..4d57fe5 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/TitlePane.html @@ -0,0 +1,4 @@ +
+
+
+
diff --git a/public/javascripts/dojo/src/widget/templates/Tree.css b/public/javascripts/dojo/src/widget/templates/Tree.css new file mode 100644 index 0000000..0af721d --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/Tree.css @@ -0,0 +1,29 @@ +.dojoTree { + font: caption; + font-size: 11px; + font-weight: normal; + overflow: auto; +} + +.dojoTreeNodeLabel { + padding: 1px 2px; + color: WindowText; + cursor: default; +} + +.dojoTreeNodeLabel:hover { + text-decoration: underline; +} + +.dojoTreeNodeLabelSelected { + background-color: Highlight; + color: HighlightText; +} + +.dojoTree div { + white-space: nowrap; +} + +.dojoTree img { + vertical-align: middle; +} diff --git a/public/javascripts/dojo/src/widget/templates/TreeDocIcon.css b/public/javascripts/dojo/src/widget/templates/TreeDocIcon.css new file mode 100644 index 0000000..2ff33f3 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/TreeDocIcon.css @@ -0,0 +1,63 @@ + +/* CSS for TreeDocIconExtension */ + + +/* long vertical line under docIcon, connecting w/ children */ +.TreeChildrenYes.TreeExpandOpen .TreeContent { + background-image : url('../templates/images/TreeV3/i_long.gif'); + background-repeat : no-repeat; + background-position: 0px 9px; +} + +/* close has higher priority */ +.TreeChildrenYes.TreeExpandClosed .TreeContent { + background-image : url(); +} + +/* higher priotity: same length and appear after background-definition */ +.TreeChildrenNo.TreeExpandLeaf .TreeContent { + background-image : url(); +} + +.TreeChildrenNo.TreeExpandClosed .TreeContent { + background-image : url(); +} + +.TreeChildrenNo.TreeExpandOpen .TreeContent { + background-image : url(); +} + + +/* highest priority */ +.TreeIconDocument { + background-image: url('../templates/images/TreeV3/document.gif'); +} + +.TreeExpandOpen .TreeIconFolder { + background-image: url('../templates/images/TreeV3/open.gif'); +} + +.TreeExpandClosed .TreeIconFolder { + background-image: url('../templates/images/TreeV3/closed.gif'); +} + +/* generic class for docIcon */ +.TreeIcon { + width: 18px; + height: 18px; + float: left; + display: inline; + background-repeat : no-repeat; +} + +/* add padding to make some space in content for docIcon */ +.TreeContent { + padding-left: 18px; +} + +/* IE workaround */ +.TreeContentIE { + padding-left: 0px; +} + + diff --git a/public/javascripts/dojo/src/widget/templates/TreeV3.css b/public/javascripts/dojo/src/widget/templates/TreeV3.css new file mode 100644 index 0000000..6e598c5 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/TreeV3.css @@ -0,0 +1,79 @@ + + + + +/* indent for all tree children excepts root */ +.TreeNode { + background-image : url('../templates/images/TreeV3/i.gif'); + background-position : top left; + background-repeat : repeat-y; + margin-left: 19px; +} +.TreeNode.TreeIsRoot { + margin-left: 0; +} + +/* left vertical line (grid) for all nodes */ +.TreeNode.TreeIsLast { + background-image: url('../templates/images/TreeV3/i_half.gif'); + background-repeat : no-repeat; +} + + +.TreeExpandOpen .TreeExpand { + background-image: url('../templates/images/TreeV3/expand_minus.gif'); +} + +/* closed is higher priority than open */ +.TreeExpandClosed .TreeExpand { + background-image: url('../templates/images/TreeV3/expand_plus.gif'); +} + +/* highest priority */ +.TreeExpandLeaf .TreeExpand { + background-image: url('../templates/images/TreeV3/expand_leaf.gif'); +} + + +.TreeContent { + min-height: 18px; + min-width: 18px; + margin-left:18px; + cursor: default; + /* can't make inline - multiline bugs */ +} + +.TreeContentIE { + height: 18px; +} + +.TreeContentSafari { + height: 18px; +} + + + +.TreeExpand { + width: 18px; + height: 18px; + float: left; + display: inline; + background-repeat : no-repeat; +} + +/* same style as IE selection */ +.TreeNodeEmphased { + background-color: Highlight; + color: HighlightText; +} + +.TreeExpand.TreeExpandLoading { + background-image: url('../templates/images/TreeV3/expand_loading.gif'); +} + + +.TreeContent .RichTextEditable, .TreeContent .RichTextEditable iframe { + background-color: #ffc; + color: black; +} + diff --git a/public/javascripts/dojo/src/widget/templates/ValidationTextbox.html b/public/javascripts/dojo/src/widget/templates/ValidationTextbox.html new file mode 100644 index 0000000..d4213d5 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/ValidationTextbox.html @@ -0,0 +1,8 @@ + + + ${this.invalidMessage} + ${this.missingMessage} + ${this.rangeMessage} + diff --git a/public/javascripts/dojo/src/widget/templates/Wizard.css b/public/javascripts/dojo/src/widget/templates/Wizard.css new file mode 100644 index 0000000..ff12ef9 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/Wizard.css @@ -0,0 +1,72 @@ +.WizardContainer { + background: #EEEEEE; + border: #798EC5 1px solid; + padding: 2px; +} + +.WizardTitle { + color: #003366; + padding: 8px 5px 15px 2px; + font-weight: bold; + font-size: x-small; + font-style: normal; + font-family: Verdana, Arial, Helvetica; + text-align: left; +} + +.WizardText { + color: #000033; + font-weight: normal; + font-size: xx-small; + font-family: Verdana, Arial, Helvetica; + padding: 2 50; text-align: justify; +} + +.WizardLightText { + color: #666666; + font-weight: normal; + font-size: xx-small; + font-family: verdana, arial, helvetica; + padding: 2px 50px; + text-align: justify; +} + +.WizardButtonHolder { + text-align: right; + padding: 10px 5px; +} + +.WizardButton { + color: #ffffff; + background: #798EC5; + font-size: xx-small; + font-family: verdana, arial, helvetica, sans-serif; + border-right: #000000 1px solid; + border-bottom: #000000 1px solid; + border-left: #666666 1px solid; + border-top: #666666 1px solid; + padding-right: 4px; + padding-left: 4px; + text-decoration: none; height: 18px; +} + +.WizardButton:hover { + cursor: pointer; +} + +.WizardButtonDisabled { + color: #eeeeee; + background-color: #999999; + font-size: xx-small; + FONT-FAMILY: verdana, arial, helvetica, sans-serif; + border-right: #000000 1px solid; + border-bottom: #000000 1px solid; + border-left: #798EC5 1px solid; + border-top: #798EC5 1px solid; + padding-right: 4px; + padding-left: 4px; + text-decoration: none; + height: 18px; +} + + diff --git a/public/javascripts/dojo/src/widget/templates/Wizard.html b/public/javascripts/dojo/src/widget/templates/Wizard.html new file mode 100644 index 0000000..a91474f --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/Wizard.html @@ -0,0 +1,11 @@ +
+
+
+
+ + + + +
+
+ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/aggregate.gif b/public/javascripts/dojo/src/widget/templates/buttons/aggregate.gif new file mode 100644 index 0000000..7fe7052 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/aggregate.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/backcolor.gif b/public/javascripts/dojo/src/widget/templates/buttons/backcolor.gif new file mode 100644 index 0000000..ef4d2fb Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/backcolor.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/bg-fade.png b/public/javascripts/dojo/src/widget/templates/buttons/bg-fade.png new file mode 100644 index 0000000..5d74aad Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/bg-fade.png differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/bold.gif b/public/javascripts/dojo/src/widget/templates/buttons/bold.gif new file mode 100644 index 0000000..738ec1a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/bold.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/cancel.gif b/public/javascripts/dojo/src/widget/templates/buttons/cancel.gif new file mode 100644 index 0000000..6bc9973 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/cancel.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/copy.gif b/public/javascripts/dojo/src/widget/templates/buttons/copy.gif new file mode 100644 index 0000000..4df29cc Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/copy.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/createlink.gif b/public/javascripts/dojo/src/widget/templates/buttons/createlink.gif new file mode 100644 index 0000000..c214076 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/createlink.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/cut.gif b/public/javascripts/dojo/src/widget/templates/buttons/cut.gif new file mode 100644 index 0000000..9bdbf4a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/cut.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/delete.gif b/public/javascripts/dojo/src/widget/templates/buttons/delete.gif new file mode 100644 index 0000000..dee61c2 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/delete.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/forecolor.gif b/public/javascripts/dojo/src/widget/templates/buttons/forecolor.gif new file mode 100644 index 0000000..db60b27 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/forecolor.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/hilitecolor.gif b/public/javascripts/dojo/src/widget/templates/buttons/hilitecolor.gif new file mode 100644 index 0000000..ef4d2fb Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/hilitecolor.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/indent.gif b/public/javascripts/dojo/src/widget/templates/buttons/indent.gif new file mode 100644 index 0000000..efd4dec Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/indent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/inserthorizontalrule.gif b/public/javascripts/dojo/src/widget/templates/buttons/inserthorizontalrule.gif new file mode 100644 index 0000000..6115b55 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/inserthorizontalrule.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/insertimage.gif b/public/javascripts/dojo/src/widget/templates/buttons/insertimage.gif new file mode 100644 index 0000000..7f22be3 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/insertimage.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/insertorderedlist.gif b/public/javascripts/dojo/src/widget/templates/buttons/insertorderedlist.gif new file mode 100644 index 0000000..6c2031a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/insertorderedlist.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/inserttable.gif b/public/javascripts/dojo/src/widget/templates/buttons/inserttable.gif new file mode 100644 index 0000000..93a77f5 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/inserttable.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/insertunorderedlist.gif b/public/javascripts/dojo/src/widget/templates/buttons/insertunorderedlist.gif new file mode 100644 index 0000000..c600730 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/insertunorderedlist.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/italic.gif b/public/javascripts/dojo/src/widget/templates/buttons/italic.gif new file mode 100644 index 0000000..13ab00c Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/italic.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/justifycenter.gif b/public/javascripts/dojo/src/widget/templates/buttons/justifycenter.gif new file mode 100644 index 0000000..39c93e1 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/justifycenter.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/justifyfull.gif b/public/javascripts/dojo/src/widget/templates/buttons/justifyfull.gif new file mode 100644 index 0000000..9c9d859 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/justifyfull.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/justifyleft.gif b/public/javascripts/dojo/src/widget/templates/buttons/justifyleft.gif new file mode 100644 index 0000000..dbb859e Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/justifyleft.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/justifyright.gif b/public/javascripts/dojo/src/widget/templates/buttons/justifyright.gif new file mode 100644 index 0000000..f156278 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/justifyright.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/left_to_right.gif b/public/javascripts/dojo/src/widget/templates/buttons/left_to_right.gif new file mode 100644 index 0000000..2cbac68 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/left_to_right.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/list_bullet_indent.gif b/public/javascripts/dojo/src/widget/templates/buttons/list_bullet_indent.gif new file mode 100644 index 0000000..56306cf Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/list_bullet_indent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/list_bullet_outdent.gif b/public/javascripts/dojo/src/widget/templates/buttons/list_bullet_outdent.gif new file mode 100644 index 0000000..7350525 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/list_bullet_outdent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/list_num_indent.gif b/public/javascripts/dojo/src/widget/templates/buttons/list_num_indent.gif new file mode 100644 index 0000000..f73741a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/list_num_indent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/list_num_outdent.gif b/public/javascripts/dojo/src/widget/templates/buttons/list_num_outdent.gif new file mode 100644 index 0000000..7ee50e5 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/list_num_outdent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/outdent.gif b/public/javascripts/dojo/src/widget/templates/buttons/outdent.gif new file mode 100644 index 0000000..40cb465 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/outdent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/paste.gif b/public/javascripts/dojo/src/widget/templates/buttons/paste.gif new file mode 100644 index 0000000..f236cbe Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/paste.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/redo.gif b/public/javascripts/dojo/src/widget/templates/buttons/redo.gif new file mode 100644 index 0000000..aff00e7 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/redo.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/removeformat.gif b/public/javascripts/dojo/src/widget/templates/buttons/removeformat.gif new file mode 100644 index 0000000..30bb618 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/removeformat.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/right_to_left.gif b/public/javascripts/dojo/src/widget/templates/buttons/right_to_left.gif new file mode 100644 index 0000000..0662cd2 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/right_to_left.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/save.gif b/public/javascripts/dojo/src/widget/templates/buttons/save.gif new file mode 100644 index 0000000..61dc4e1 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/save.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/sep.gif b/public/javascripts/dojo/src/widget/templates/buttons/sep.gif new file mode 100644 index 0000000..60b65f6 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/sep.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/space.gif b/public/javascripts/dojo/src/widget/templates/buttons/space.gif new file mode 100644 index 0000000..5bfd67a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/space.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/strikethrough.gif b/public/javascripts/dojo/src/widget/templates/buttons/strikethrough.gif new file mode 100644 index 0000000..e941ffd Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/strikethrough.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/subscript.gif b/public/javascripts/dojo/src/widget/templates/buttons/subscript.gif new file mode 100644 index 0000000..173d340 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/subscript.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/superscript.gif b/public/javascripts/dojo/src/widget/templates/buttons/superscript.gif new file mode 100644 index 0000000..9eb24da Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/superscript.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/underline.gif b/public/javascripts/dojo/src/widget/templates/buttons/underline.gif new file mode 100644 index 0000000..8323876 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/underline.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/undo.gif b/public/javascripts/dojo/src/widget/templates/buttons/undo.gif new file mode 100644 index 0000000..382eba0 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/undo.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/buttons/wikiword.gif b/public/javascripts/dojo/src/widget/templates/buttons/wikiword.gif new file mode 100644 index 0000000..24741d1 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/buttons/wikiword.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/check.gif b/public/javascripts/dojo/src/widget/templates/check.gif new file mode 100644 index 0000000..9210f85 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/check.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/decrementMonth.gif b/public/javascripts/dojo/src/widget/templates/decrementMonth.gif new file mode 100644 index 0000000..da5d869 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/decrementMonth.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/decrementWeek.gif b/public/javascripts/dojo/src/widget/templates/decrementWeek.gif new file mode 100644 index 0000000..1f2b8a0 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/decrementWeek.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/grabCorner.gif b/public/javascripts/dojo/src/widget/templates/grabCorner.gif new file mode 100644 index 0000000..31453c4 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/grabCorner.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/Tree.css b/public/javascripts/dojo/src/widget/templates/images/Tree/Tree.css new file mode 100644 index 0000000..4d47e2e --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/images/Tree/Tree.css @@ -0,0 +1,36 @@ + +.dojoTree { + font: caption; + font-size: 11px; + font-weight: normal; + overflow: auto; +} + + +.dojoTreeNodeLabelTitle { + padding-left: 2px; + color: WindowText; +} + +.dojoTreeNodeLabel { + cursor:hand; + cursor:pointer; +} + +.dojoTreeNodeLabelTitle:hover { + text-decoration: underline; +} + +.dojoTreeNodeLabelSelected { + background-color: Highlight; + color: HighlightText; +} + +.dojoTree div { + white-space: nowrap; +} + +.dojoTree img, .dojoTreeNodeLabel img { + vertical-align: middle; +} + diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/blank.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/blank.gif new file mode 100644 index 0000000..d90ab95 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/blank.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/closed.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/closed.gif new file mode 100644 index 0000000..820bd19 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/closed.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/document.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/document.gif new file mode 100644 index 0000000..3d57afb Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/document.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/minus.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/minus.gif new file mode 100644 index 0000000..f2b5863 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/minus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/plus.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/plus.gif new file mode 100644 index 0000000..bf60022 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/plus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/transparent.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/transparent.gif new file mode 100644 index 0000000..350cc27 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/transparent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_blank.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_blank.gif new file mode 100644 index 0000000..80848bb Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_blank.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_child.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_child.gif new file mode 100644 index 0000000..a9da6db Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_child.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_expand_minus.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_expand_minus.gif new file mode 100644 index 0000000..0e8f8d9 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_expand_minus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_expand_plus.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_expand_plus.gif new file mode 100644 index 0000000..00f90ae Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_expand_plus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_c.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_c.gif new file mode 100644 index 0000000..a377cea Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_c.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_l.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_l.gif new file mode 100644 index 0000000..480ae8d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_p.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_p.gif new file mode 100644 index 0000000..3d06760 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_p.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_t.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_t.gif new file mode 100644 index 0000000..029c588 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_t.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_v.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_v.gif new file mode 100644 index 0000000..dd3aa4f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_v.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_x.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_x.gif new file mode 100644 index 0000000..c49ee9c Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_x.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_y.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_y.gif new file mode 100644 index 0000000..1f3efbc Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_y.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_z.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_z.gif new file mode 100644 index 0000000..3b23b35 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_grid_z.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_loading.gif b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_loading.gif new file mode 100644 index 0000000..7b9860f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_loading.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_loading.jpg b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_loading.jpg new file mode 100644 index 0000000..7ec914b Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/Tree/treenode_loading.jpg differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/closed.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/closed.gif new file mode 100644 index 0000000..d4b6f94 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/closed.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/document.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/document.gif new file mode 100644 index 0000000..018e142 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/document.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_leaf.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_leaf.gif new file mode 100644 index 0000000..b93da0b Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_leaf.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_loading.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_loading.gif new file mode 100644 index 0000000..7b9860f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_loading.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_minus.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_minus.gif new file mode 100644 index 0000000..7f197ec Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_minus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_plus.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_plus.gif new file mode 100644 index 0000000..319d2ba Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/expand_plus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/i.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i.gif new file mode 100644 index 0000000..f7e3b60 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_bhalf.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_bhalf.gif new file mode 100644 index 0000000..fbd21d3 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_bhalf.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_half.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_half.gif new file mode 100644 index 0000000..bb9d642 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_half.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_long.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_long.gif new file mode 100644 index 0000000..771f04c Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/i_long.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/l.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/l.gif new file mode 100644 index 0000000..cb51a35 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/minus.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/minus.gif new file mode 100644 index 0000000..9786b65 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/minus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/open.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/open.gif new file mode 100644 index 0000000..2b6cb53 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/open.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/plus.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/plus.gif new file mode 100644 index 0000000..6919e94 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/plus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/t.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/t.gif new file mode 100644 index 0000000..15df5f3 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/t.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/TreeV3/x.gif b/public/javascripts/dojo/src/widget/templates/images/TreeV3/x.gif new file mode 100644 index 0000000..b93da0b Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/TreeV3/x.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/bdYearBg.1.gif b/public/javascripts/dojo/src/widget/templates/images/bdYearBg.1.gif new file mode 100644 index 0000000..e69de29 diff --git a/public/javascripts/dojo/src/widget/templates/images/bdYearBg.gif b/public/javascripts/dojo/src/widget/templates/images/bdYearBg.gif new file mode 100644 index 0000000..95ff97a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/bdYearBg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/blank.gif b/public/javascripts/dojo/src/widget/templates/images/blank.gif new file mode 100644 index 0000000..e565824 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/blank.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/combo_box_arrow.png b/public/javascripts/dojo/src/widget/templates/images/combo_box_arrow.png new file mode 100644 index 0000000..d294f55 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/combo_box_arrow.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dateIcon.gif b/public/javascripts/dojo/src/widget/templates/images/dateIcon.gif new file mode 100644 index 0000000..dc1f31c Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dateIcon.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/decrementMonth.gif b/public/javascripts/dojo/src/widget/templates/images/decrementMonth.gif new file mode 100644 index 0000000..b370e82 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/decrementMonth.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/decrementMonth.png b/public/javascripts/dojo/src/widget/templates/images/decrementMonth.png new file mode 100644 index 0000000..4495ed2 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/decrementMonth.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpBg.gif b/public/javascripts/dojo/src/widget/templates/images/dpBg.gif new file mode 100644 index 0000000..3eaccf3 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpBg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpCurveBL.png b/public/javascripts/dojo/src/widget/templates/images/dpCurveBL.png new file mode 100644 index 0000000..aecfe80 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpCurveBL.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpCurveBR.png b/public/javascripts/dojo/src/widget/templates/images/dpCurveBR.png new file mode 100644 index 0000000..b5cc369 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpCurveBR.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpCurveTL.png b/public/javascripts/dojo/src/widget/templates/images/dpCurveTL.png new file mode 100644 index 0000000..6d966b4 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpCurveTL.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpCurveTR.png b/public/javascripts/dojo/src/widget/templates/images/dpCurveTR.png new file mode 100644 index 0000000..9cfb0aa Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpCurveTR.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpHorizLine.gif b/public/javascripts/dojo/src/widget/templates/images/dpHorizLine.gif new file mode 100644 index 0000000..67bf681 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpHorizLine.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpHorizLineFoot.gif b/public/javascripts/dojo/src/widget/templates/images/dpHorizLineFoot.gif new file mode 100644 index 0000000..4499aeb Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpHorizLineFoot.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpMonthBg.gif b/public/javascripts/dojo/src/widget/templates/images/dpMonthBg.gif new file mode 100644 index 0000000..0348a91 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpMonthBg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpMonthBg.png b/public/javascripts/dojo/src/widget/templates/images/dpMonthBg.png new file mode 100644 index 0000000..6063812 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpMonthBg.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpMonthBg2.png b/public/javascripts/dojo/src/widget/templates/images/dpMonthBg2.png new file mode 100644 index 0000000..6063812 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpMonthBg2.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpVertLine.gif b/public/javascripts/dojo/src/widget/templates/images/dpVertLine.gif new file mode 100644 index 0000000..dd3af2f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpVertLine.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpYearBg.gif b/public/javascripts/dojo/src/widget/templates/images/dpYearBg.gif new file mode 100644 index 0000000..95ff97a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpYearBg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dpYearBg.png b/public/javascripts/dojo/src/widget/templates/images/dpYearBg.png new file mode 100644 index 0000000..e41f750 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dpYearBg.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dropdownButtonsArrow-disabled.gif b/public/javascripts/dojo/src/widget/templates/images/dropdownButtonsArrow-disabled.gif new file mode 100644 index 0000000..a164440 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dropdownButtonsArrow-disabled.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/dropdownButtonsArrow.gif b/public/javascripts/dojo/src/widget/templates/images/dropdownButtonsArrow.gif new file mode 100644 index 0000000..5264181 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/dropdownButtonsArrow.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/floatingPaneClose.gif b/public/javascripts/dojo/src/widget/templates/images/floatingPaneClose.gif new file mode 100644 index 0000000..4e7658e Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/floatingPaneClose.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/floatingPaneMaximize.gif b/public/javascripts/dojo/src/widget/templates/images/floatingPaneMaximize.gif new file mode 100644 index 0000000..d75cec0 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/floatingPaneMaximize.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/floatingPaneMinimize.gif b/public/javascripts/dojo/src/widget/templates/images/floatingPaneMinimize.gif new file mode 100644 index 0000000..79e0b32 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/floatingPaneMinimize.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/floatingPaneRestore.gif b/public/javascripts/dojo/src/widget/templates/images/floatingPaneRestore.gif new file mode 100644 index 0000000..dd204f5 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/floatingPaneRestore.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/hue.png b/public/javascripts/dojo/src/widget/templates/images/hue.png new file mode 100644 index 0000000..f84ec73 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/hue.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/incrementMonth.gif b/public/javascripts/dojo/src/widget/templates/images/incrementMonth.gif new file mode 100644 index 0000000..9710e3b Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/incrementMonth.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/incrementMonth.png b/public/javascripts/dojo/src/widget/templates/images/incrementMonth.png new file mode 100644 index 0000000..ef2f7b7 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/incrementMonth.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/no.gif b/public/javascripts/dojo/src/widget/templates/images/no.gif new file mode 100644 index 0000000..9021a14 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/no.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/no.svg b/public/javascripts/dojo/src/widget/templates/images/no.svg new file mode 100644 index 0000000..3350920 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/images/no.svg @@ -0,0 +1,11 @@ + + + + +]> + + + + diff --git a/public/javascripts/dojo/src/widget/templates/images/scBackground.gif b/public/javascripts/dojo/src/widget/templates/images/scBackground.gif new file mode 100644 index 0000000..22d1289 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/scBackground.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider-bg-progress-vert.gif b/public/javascripts/dojo/src/widget/templates/images/slider-bg-progress-vert.gif new file mode 100644 index 0000000..3e86c88 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider-bg-progress-vert.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider-bg-vert.gif b/public/javascripts/dojo/src/widget/templates/images/slider-bg-vert.gif new file mode 100644 index 0000000..189f4a6 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider-bg-vert.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider-bg.gif b/public/javascripts/dojo/src/widget/templates/images/slider-bg.gif new file mode 100644 index 0000000..f98175d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider-bg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider-button-horz.png b/public/javascripts/dojo/src/widget/templates/images/slider-button-horz.png new file mode 100644 index 0000000..628cb1d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider-button-horz.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider-button-vert.png b/public/javascripts/dojo/src/widget/templates/images/slider-button-vert.png new file mode 100644 index 0000000..db90bfe Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider-button-vert.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider-button.png b/public/javascripts/dojo/src/widget/templates/images/slider-button.png new file mode 100644 index 0000000..c2dfa1b Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider-button.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider.gif b/public/javascripts/dojo/src/widget/templates/images/slider.gif new file mode 100644 index 0000000..a4cf32e Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider_down_arrow.png b/public/javascripts/dojo/src/widget/templates/images/slider_down_arrow.png new file mode 100644 index 0000000..68ff366 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider_down_arrow.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider_left_arrow.png b/public/javascripts/dojo/src/widget/templates/images/slider_left_arrow.png new file mode 100644 index 0000000..9b6a63d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider_left_arrow.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider_right_arrow.png b/public/javascripts/dojo/src/widget/templates/images/slider_right_arrow.png new file mode 100644 index 0000000..3231ffd Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider_right_arrow.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/slider_up_arrow.png b/public/javascripts/dojo/src/widget/templates/images/slider_up_arrow.png new file mode 100644 index 0000000..dfa197e Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/slider_up_arrow.png differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaActive-c.gif b/public/javascripts/dojo/src/widget/templates/images/soriaActive-c.gif new file mode 100644 index 0000000..cd9d636 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaActive-c.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaActive-l.gif b/public/javascripts/dojo/src/widget/templates/images/soriaActive-l.gif new file mode 100644 index 0000000..970ee69 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaActive-l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaActive-r.gif b/public/javascripts/dojo/src/widget/templates/images/soriaActive-r.gif new file mode 100644 index 0000000..67afaf9 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaActive-r.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaBarBg.gif b/public/javascripts/dojo/src/widget/templates/images/soriaBarBg.gif new file mode 100644 index 0000000..54a7b56 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaBarBg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaButton-c.gif b/public/javascripts/dojo/src/widget/templates/images/soriaButton-c.gif new file mode 100644 index 0000000..226830f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaButton-c.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaButton-l.gif b/public/javascripts/dojo/src/widget/templates/images/soriaButton-l.gif new file mode 100644 index 0000000..fe0c0fd Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaButton-l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaButton-r.gif b/public/javascripts/dojo/src/widget/templates/images/soriaButton-r.gif new file mode 100644 index 0000000..705b053 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaButton-r.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-c.gif b/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-c.gif new file mode 100644 index 0000000..5c0ee9d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-c.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-l.gif b/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-l.gif new file mode 100644 index 0000000..fdbef1a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-r.gif b/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-r.gif new file mode 100644 index 0000000..449a8c8 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaDisabled-r.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaMenuBg.gif b/public/javascripts/dojo/src/widget/templates/images/soriaMenuBg.gif new file mode 100644 index 0000000..54a7b56 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaMenuBg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaPressed-c.gif b/public/javascripts/dojo/src/widget/templates/images/soriaPressed-c.gif new file mode 100644 index 0000000..9dd781b Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaPressed-c.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaPressed-l.gif b/public/javascripts/dojo/src/widget/templates/images/soriaPressed-l.gif new file mode 100644 index 0000000..2226c7a Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaPressed-l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/soriaPressed-r.gif b/public/javascripts/dojo/src/widget/templates/images/soriaPressed-r.gif new file mode 100644 index 0000000..cf32f8d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/soriaPressed-r.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/spinnerDecrement.gif b/public/javascripts/dojo/src/widget/templates/images/spinnerDecrement.gif new file mode 100644 index 0000000..80c9fd3 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/spinnerDecrement.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/spinnerIncrement.gif b/public/javascripts/dojo/src/widget/templates/images/spinnerIncrement.gif new file mode 100644 index 0000000..2fc237d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/spinnerIncrement.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/submenu_off.gif b/public/javascripts/dojo/src/widget/templates/images/submenu_off.gif new file mode 100644 index 0000000..ff7a2fa Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/submenu_off.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/submenu_on.gif b/public/javascripts/dojo/src/widget/templates/images/submenu_on.gif new file mode 100644 index 0000000..b750987 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/submenu_on.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_bot_left.gif b/public/javascripts/dojo/src/widget/templates/images/tab_bot_left.gif new file mode 100644 index 0000000..0dfab38 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_bot_left.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_bot_left_curr.gif b/public/javascripts/dojo/src/widget/templates/images/tab_bot_left_curr.gif new file mode 100644 index 0000000..9279d24 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_bot_left_curr.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_bot_right.gif b/public/javascripts/dojo/src/widget/templates/images/tab_bot_right.gif new file mode 100644 index 0000000..6bc0795 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_bot_right.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_bot_right_curr.gif b/public/javascripts/dojo/src/widget/templates/images/tab_bot_right_curr.gif new file mode 100644 index 0000000..a661efd Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_bot_right_curr.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_close.gif b/public/javascripts/dojo/src/widget/templates/images/tab_close.gif new file mode 100644 index 0000000..24b0cb8 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_close.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_close_h.gif b/public/javascripts/dojo/src/widget/templates/images/tab_close_h.gif new file mode 100644 index 0000000..a71004d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_close_h.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_left.gif b/public/javascripts/dojo/src/widget/templates/images/tab_left.gif new file mode 100644 index 0000000..d14099f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_left.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_left_r.gif b/public/javascripts/dojo/src/widget/templates/images/tab_left_r.gif new file mode 100644 index 0000000..0dfab38 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_left_r.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_left_r_curr.gif b/public/javascripts/dojo/src/widget/templates/images/tab_left_r_curr.gif new file mode 100644 index 0000000..9279d24 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_left_r_curr.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_right.gif b/public/javascripts/dojo/src/widget/templates/images/tab_right.gif new file mode 100644 index 0000000..fcab384 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_right.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_right_r.gif b/public/javascripts/dojo/src/widget/templates/images/tab_right_r.gif new file mode 100644 index 0000000..6bc0795 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_right_r.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_right_r_curr.gif b/public/javascripts/dojo/src/widget/templates/images/tab_right_r_curr.gif new file mode 100644 index 0000000..a661efd Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_right_r_curr.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_top_left.gif b/public/javascripts/dojo/src/widget/templates/images/tab_top_left.gif new file mode 100644 index 0000000..6cffcad Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_top_left.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/tab_top_right.gif b/public/javascripts/dojo/src/widget/templates/images/tab_top_right.gif new file mode 100644 index 0000000..fcab384 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/tab_top_right.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/toolbar-bg.gif b/public/javascripts/dojo/src/widget/templates/images/toolbar-bg.gif new file mode 100644 index 0000000..6bccd43 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/toolbar-bg.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/transparent.gif b/public/javascripts/dojo/src/widget/templates/images/transparent.gif new file mode 100644 index 0000000..350cc27 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/transparent.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_blank.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_blank.gif new file mode 100644 index 0000000..80848bb Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_blank.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_child.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_child.gif new file mode 100644 index 0000000..a9da6db Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_child.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_expand_minus.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_expand_minus.gif new file mode 100644 index 0000000..0e8f8d9 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_expand_minus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_expand_plus.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_expand_plus.gif new file mode 100644 index 0000000..00f90ae Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_expand_plus.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_c.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_c.gif new file mode 100644 index 0000000..a377cea Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_c.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_l.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_l.gif new file mode 100644 index 0000000..480ae8d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_l.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_p.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_p.gif new file mode 100644 index 0000000..3d06760 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_p.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_t.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_t.gif new file mode 100644 index 0000000..029c588 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_t.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_v.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_v.gif new file mode 100644 index 0000000..dd3aa4f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_v.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_x.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_x.gif new file mode 100644 index 0000000..c49ee9c Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_x.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_y.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_y.gif new file mode 100644 index 0000000..1f3efbc Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_y.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_grid_z.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_z.gif new file mode 100644 index 0000000..3b23b35 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_grid_z.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/treenode_node.gif b/public/javascripts/dojo/src/widget/templates/images/treenode_node.gif new file mode 100644 index 0000000..7ac7e19 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/treenode_node.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/verticalbar.gif b/public/javascripts/dojo/src/widget/templates/images/verticalbar.gif new file mode 100644 index 0000000..e2a44ab Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/verticalbar.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/images/whiteDownArrow.gif b/public/javascripts/dojo/src/widget/templates/images/whiteDownArrow.gif new file mode 100644 index 0000000..c83982f Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/images/whiteDownArrow.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/incrementMonth.gif b/public/javascripts/dojo/src/widget/templates/incrementMonth.gif new file mode 100644 index 0000000..42fe20d Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/incrementMonth.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/incrementWeek.gif b/public/javascripts/dojo/src/widget/templates/incrementWeek.gif new file mode 100644 index 0000000..76f1b25 Binary files /dev/null and b/public/javascripts/dojo/src/widget/templates/incrementWeek.gif differ diff --git a/public/javascripts/dojo/src/widget/templates/richtextframe.html b/public/javascripts/dojo/src/widget/templates/richtextframe.html new file mode 100644 index 0000000..9f3a4e4 --- /dev/null +++ b/public/javascripts/dojo/src/widget/templates/richtextframe.html @@ -0,0 +1,21 @@ + + + + + + + + + +
+ + diff --git a/public/javascripts/dojo/src/widget/validate.js b/public/javascripts/dojo/src/widget/validate.js new file mode 100644 index 0000000..370e8e9 --- /dev/null +++ b/public/javascripts/dojo/src/widget/validate.js @@ -0,0 +1,729 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.validate"); + +dojo.require("dojo.widget.*"); +dojo.require("dojo.widget.HtmlWidget"); +dojo.require("dojo.widget.Manager"); +dojo.require("dojo.widget.Parse"); +dojo.require("dojo.xml.Parse"); +dojo.require("dojo.lang"); + +dojo.require("dojo.validate.common"); +dojo.require("dojo.validate.datetime"); +dojo.require("dojo.validate.check"); +dojo.require("dojo.validate.web"); +dojo.require("dojo.validate.us"); + +dojo.widget.manager.registerWidgetPackage("dojo.widget.validate"); + +/* + ****** Textbox ****** + + This widget is a generic textbox field. + Serves as a base class to derive more specialized functionality in subclasses. + Has the following properties that can be specified as attributes in the markup. + + @attr id The textbox id attribute. + @attr className The textbox class attribute. + @attr name The textbox name attribute. + @attr value The textbox value attribute. + @attr trim Removes leading and trailing whitespace if true. Default is false. + @attr uppercase Converts all characters to uppercase if true. Default is false. + @attr lowercase Converts all characters to lowercase if true. Default is false. + @attr ucFirst Converts the first character of each word to uppercase if true. + @attr lowercase Removes all characters that are not digits if true. Default is false. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.Textbox", + dojo.widget.HtmlWidget, + { + // default values for new subclass properties + className: "", + name: "", + value: "", + type: "", + trim: false, + uppercase: false, + lowercase: false, + ucFirst: false, + digit: false, + htmlfloat: "none", + + templatePath: dojo.uri.dojoUri("src/widget/templates/Textbox.html"), + + // our DOM nodes + textbox: null, + + // Apply various filters to textbox value + filter: function() { + if (this.trim) { + this.textbox.value = this.textbox.value.replace(/(^\s*|\s*$)/g, ""); + } + if (this.uppercase) { + this.textbox.value = this.textbox.value.toUpperCase(); + } + if (this.lowercase) { + this.textbox.value = this.textbox.value.toLowerCase(); + } + if (this.ucFirst) { + this.textbox.value = this.textbox.value.replace(/\b\w+\b/g, + function(word) { return word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase(); }); + } + if (this.digit) { + this.textbox.value = this.textbox.value.replace(/\D/g, ""); + } + }, + + // event handlers, you can over-ride these in your own subclasses + onfocus: function() {}, + onblur: function() { this.filter(); }, + + // All functions below are called by create from dojo.widget.Widget + mixInProperties: function(localProperties, frag) { + dojo.widget.validate.Textbox.superclass.mixInProperties.apply(this, arguments); + if ( localProperties["class"] ) { + this.className = localProperties["class"]; + } + }, + + fillInTemplate: function() { + // apply any filters to initial value + this.filter(); + + // set table to be inlined (technique varies by browser) + if(dojo.render.html.ie){ dojo.html.addClass(this.domNode, "ie"); } + if(dojo.render.html.moz){ dojo.html.addClass(this.domNode, "moz"); } + if(dojo.render.html.opera){ dojo.html.addClass(this.domNode, "opera"); } + if(dojo.render.html.safari){ dojo.html.addClass(this.domNode, "safari"); } + } + + } +); + +/* + ****** ValidationTextbox ****** + + A subclass of Textbox. + Over-ride isValid in subclasses to perform specific kinds of validation. + Has several new properties that can be specified as attributes in the markup. + + @attr type Basic input tag type declaration. + @attr size Basic input tag size declaration. + @attr type Basic input tag maxlength declaration. + @attr required Can be true or false, default is false. + @attr validColor The color textbox is highlighted for valid input. Default is #cfc. + @attr invalidColor The color textbox is highlighted for invalid input. Default is #fcc. + @attr invalidClass Class used to format displayed text in page if necessary to override default class + @attr invalidMessage The message to display if value is invalid. + @attr missingMessage The message to display if value is missing. + @attr missingClass Override default class used for missing input data + @attr listenOnKeyPress Updates messages on each key press. Default is true. + @attr promptMessage Will not issue invalid message if field is populated with default user-prompt text +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.ValidationTextbox", + dojo.widget.validate.Textbox, + function() { + // this property isn't a primitive and needs to be created on a per-item basis. + this.flags = {}; + }, + { + // default values for new subclass properties + required: false, + validColor: "#cfc", + invalidColor: "#fcc", + rangeClass: "range", + invalidClass: "invalid", + missingClass: "missing", + size: "", + maxlength: "", + promptMessage: "", + invalidMessage: "* The value entered is not valid.", + missingMessage: "* This value is required.", + rangeMessage: "* This value out of range.", + listenOnKeyPress: true, + htmlfloat: "none", + lastCheckedValue: null, + + templatePath: dojo.uri.dojoUri("src/widget/templates/ValidationTextbox.html"), + + // new DOM nodes + invalidSpan: null, + missingSpan: null, + rangeSpan: null, + + getValue: function() { + return this.textbox.value; + }, + + setValue: function(value) { + this.textbox.value = value; + this.update(); + }, + + // Need to over-ride with your own validation code in subclasses + isValid: function() { return true; }, + + // Need to over-ride with your own validation code in subclasses + isInRange: function() { return true; }, + + // Returns true if value is all whitespace + isEmpty: function() { + return ( /^\s*$/.test(this.textbox.value) ); + }, + + // Returns true if value is required and it is all whitespace. + isMissing: function() { + return ( this.required && this.isEmpty() ); + }, + + // Called oninit, onblur, and onkeypress. + // Show missing or invalid messages if appropriate, and highlight textbox field. + update: function() { + this.lastCheckedValue = this.textbox.value; + this.missingSpan.style.display = "none"; + this.invalidSpan.style.display = "none"; + this.rangeSpan.style.display = "none"; + + var empty = this.isEmpty(); + var valid = true; + if(this.promptMessage != this.textbox.value){ + valid = this.isValid(); + } + var missing = this.isMissing(); + + // Display at most one error message + if(missing){ + this.missingSpan.style.display = ""; + }else if( !empty && !valid ){ + this.invalidSpan.style.display = ""; + }else if( !empty && !this.isInRange() ){ + this.rangeSpan.style.display = ""; + } + this.highlight(); + }, + + // Called oninit, and onblur. + highlight: function() { + // highlight textbox background + if ( this.isEmpty() ) { + this.textbox.style.backgroundColor = ""; + }else if ( this.isValid() && this.isInRange() ){ + this.textbox.style.backgroundColor = this.validColor; + }else if( this.textbox.value != this.promptMessage){ + this.textbox.style.backgroundColor = this.invalidColor; + } + }, + + onfocus: function() { + if ( !this.listenOnKeyPress) { + this.textbox.style.backgroundColor = ""; + } + }, + + onblur: function() { + this.filter(); + this.update(); + }, + + onkeyup: function(){ + if(this.listenOnKeyPress){ + //this.filter(); trim is problem if you have to type two words + this.update(); + }else if (this.textbox.value != this.lastCheckedValue){ + this.textbox.style.backgroundColor = ""; + } + }, + + // FIXME: why are there to fillInTemplate methods defined here? + fillInTemplate: function() { + dojo.widget.validate.ValidationTextbox.superclass.fillInTemplate.apply(this, arguments); + + // Attach isMissing and isValid methods to the textbox. + // We may use them later in connection with a submit button widget. + // TODO: this is unorthodox; it seems better to do it another way -- Bill + this.textbox.isValid = function() { this.isValid.call(this); }; + this.textbox.isMissing = function() { this.isMissing.call(this); }; + this.textbox.isInRange = function() { this.isInRange.call(this); }; + this.update(); + } + } +); + + +/* + ****** IntegerTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid/isInRange to test for integer input. + Has 4 new properties that can be specified as attributes in the markup. + + @attr signed The leading plus-or-minus sign. Can be true or false, default is either. + @attr separator The character used as the thousands separator. Default is no separator. + @attr min Minimum signed value. Default is -Infinity + @attr max Maximum signed value. Default is +Infinity +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.IntegerTextbox", + dojo.widget.validate.ValidationTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.IntegerTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if((localProperties.signed == "true")|| + (localProperties.signed == "always")){ + this.flags.signed = true; + }else if((localProperties.signed == "false")|| + (localProperties.signed == "never")){ + this.flags.signed = false; + this.flags.min = 0; + }else{ + this.flags.signed = [ true, false ]; // optional + } + if(localProperties.separator){ + this.flags.separator = localProperties.separator; + } + if(localProperties.min){ + this.flags.min = parseInt(localProperties.min); + } + if(localProperties.max){ + this.flags.max = parseInt(localProperties.max); + } + }, + + // Over-ride for integer validation + isValid: function() { + return dojo.validate.isInteger(this.textbox.value, this.flags); + }, + isInRange: function() { + return dojo.validate.isInRange(this.textbox.value, this.flags); + } + } +); + +/* + ****** RealNumberTextbox ****** + + A subclass that extends IntegerTextbox. + Over-rides isValid/isInRange to test for real number input. + Has 5 new properties that can be specified as attributes in the markup. + + @attr places The exact number of decimal places. If omitted, it's unlimited and optional. + @attr exponent Can be true or false. If omitted the exponential part is optional. + @attr eSigned Is the exponent signed? Can be true or false, if omitted the sign is optional. + @attr min Minimum signed value. Default is -Infinity + @attr max Maximum signed value. Default is +Infinity +*/ + +dojo.widget.defineWidget( + "dojo.widget.validate.RealNumberTextbox", + dojo.widget.validate.IntegerTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.RealNumberTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.places ) { + this.flags.places = Number( localProperties.places ); + } + if((localProperties.exponent == "true")|| + (localProperties.exponent == "always")){ + this.flags.exponent = true; + }else if((localProperties.exponent == "false")||(localProperties.exponent == "never")){ + this.flags.exponent = false; + }else{ + this.flags.exponent = [ true, false ]; // optional + } + if((localProperties.esigned == "true")||(localProperties.esigned == "always")){ + this.flags.eSigned = true; + }else if((localProperties.esigned == "false")||(localProperties.esigned == "never")){ + this.flags.eSigned = false; + }else{ + this.flags.eSigned = [ true, false ]; // optional + } + if(localProperties.min){ + this.flags.min = parseFloat(localProperties.min); + } + if(localProperties.max){ + this.flags.max = parseFloat(localProperties.max); + } + }, + + // Over-ride for real number validation + isValid: function() { + return dojo.validate.isRealNumber(this.textbox.value, this.flags); + }, + isInRange: function() { + return dojo.validate.isInRange(this.textbox.value, this.flags); + } + + } +); + +/* + ****** CurrencyTextbox ****** + + A subclass that extends IntegerTextbox. + Over-rides isValid/isInRange to test if input denotes a monetary value . + Has 5 new properties that can be specified as attributes in the markup. + + @attr cents The two decimal places for cents. Can be true or false, optional if omitted. + @attr symbol A currency symbol such as Yen "???", Pound "???", or the Euro "???". Default is "$". + @attr separator Default is "," instead of no separator as in IntegerTextbox. + @attr min Minimum signed value. Default is -Infinity + @attr max Maximum signed value. Default is +Infinity +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.CurrencyTextbox", + dojo.widget.validate.IntegerTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.CurrencyTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.cents ) { + this.flags.cents = ( localProperties.cents == "true" ); + } + if ( localProperties.symbol ) { + this.flags.symbol = localProperties.symbol; + } + if(localProperties.min){ + this.flags.min = parseFloat(localProperties.min); + } + if(localProperties.max){ + this.flags.max = parseFloat(localProperties.max); + } + }, + + // Over-ride for currency validation + isValid: function() { + return dojo.validate.isCurrency(this.textbox.value, this.flags); + }, + isInRange: function() { + return dojo.validate.isInRange(this.textbox.value, this.flags); + } + + } +); + +/* + ****** IpAddressTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test for IP addresses. + Can specify formats for ipv4 or ipv6 as attributes in the markup. + + @attr allowDottedDecimal true or false, default is true. + @attr allowDottedHex true or false, default is true. + @attr allowDottedOctal true or false, default is true. + @attr allowDecimal true or false, default is true. + @attr allowHex true or false, default is true. + @attr allowIPv6 true or false, default is true. + @attr allowHybrid true or false, default is true. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.IpAddressTextbox", + dojo.widget.validate.ValidationTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.IpAddressTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.allowdotteddecimal ) { + this.flags.allowDottedDecimal = ( localProperties.allowdotteddecimal == "true" ); + } + if ( localProperties.allowdottedhex ) { + this.flags.allowDottedHex = ( localProperties.allowdottedhex == "true" ); + } + if ( localProperties.allowdottedoctal ) { + this.flags.allowDottedOctal = ( localProperties.allowdottedoctal == "true" ); + } + if ( localProperties.allowdecimal ) { + this.flags.allowDecimal = ( localProperties.allowdecimal == "true" ); + } + if ( localProperties.allowhex ) { + this.flags.allowHex = ( localProperties.allowhex == "true" ); + } + if ( localProperties.allowipv6 ) { + this.flags.allowIPv6 = ( localProperties.allowipv6 == "true" ); + } + if ( localProperties.allowhybrid ) { + this.flags.allowHybrid = ( localProperties.allowhybrid == "true" ); + } + }, + + // Over-ride for IP address validation + isValid: function() { + return dojo.validate.isIpAddress(this.textbox.value, this.flags); + } + } +); + +/* + ****** UrlTextbox ****** + + A subclass of IpAddressTextbox. + Over-rides isValid to test for URL's. + Can specify 5 additional attributes in the markup. + + @attr scheme Can be true or false. If omitted the scheme is optional. + @attr allowIP Allow an IP address for hostname. Default is true. + @attr allowLocal Allow the host to be "localhost". Default is false. + @attr allowCC Allow 2 letter country code domains. Default is true. + @attr allowGeneric Allow generic domains. Can be true or false, default is true. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.UrlTextbox", + dojo.widget.validate.IpAddressTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.UrlTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.scheme ) { + this.flags.scheme = ( localProperties.scheme == "true" ); + } + if ( localProperties.allowip ) { + this.flags.allowIP = ( localProperties.allowip == "true" ); + } + if ( localProperties.allowlocal ) { + this.flags.allowLocal = ( localProperties.allowlocal == "true" ); + } + if ( localProperties.allowcc ) { + this.flags.allowCC = ( localProperties.allowcc == "true" ); + } + if ( localProperties.allowgeneric ) { + this.flags.allowGeneric = ( localProperties.allowgeneric == "true" ); + } + }, + + // Over-ride for URL validation + isValid: function() { + return dojo.validate.isUrl(this.textbox.value, this.flags); + } + } +); + +/* + ****** EmailTextbox ****** + + A subclass of UrlTextbox. + Over-rides isValid to test for email addresses. + Can use all markup attributes/properties of UrlTextbox except scheme. + One new attribute available in the markup. + + @attr allowCruft Allow address like . Default is false. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.EmailTextbox", + dojo.widget.validate.UrlTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.EmailTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.allowcruft ) { + this.flags.allowCruft = ( localProperties.allowcruft == "true" ); + } + }, + + // Over-ride for email address validation + isValid: function() { + return dojo.validate.isEmailAddress(this.textbox.value, this.flags); + } + } +); + +/* + ****** EmailListTextbox ****** + + A subclass of EmailTextbox. + Over-rides isValid to test for a list of email addresses. + Can use all markup attributes/properties of EmailTextbox and ... + + @attr listSeparator The character used to separate email addresses. + Default is ";", ",", "\n" or " ". +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.EmailListTextbox", + dojo.widget.validate.EmailTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.EmailListTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.listseparator ) { + this.flags.listSeparator = localProperties.listseparator; + } + }, + + // Over-ride for email address list validation + isValid: function() { + return dojo.validate.isEmailAddressList(this.textbox.value, this.flags); + } + } +); + +/* + ****** DateTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is in a valid date format. + + @attr format Described in dojo.validate.js. Default is "MM/DD/YYYY". +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.DateTextbox", + dojo.widget.validate.ValidationTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.DateTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.format ) { + this.flags.format = localProperties.format; + } + }, + + // Over-ride for date validation + isValid: function() { + return dojo.validate.isValidDate(this.textbox.value, this.flags.format); + } + } +); + +/* + ****** TimeTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is in a valid time format. + + @attr format Described in dojo.validate.js. Default is "h:mm:ss t". + @attr amSymbol The symbol used for AM. Default is "AM" or "am". + @attr pmSymbol The symbol used for PM. Default is "PM" or "pm". +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.TimeTextbox", + dojo.widget.validate.ValidationTextbox, + { + mixInProperties: function(localProperties, frag) { + // First initialize properties in super-class. + dojo.widget.validate.TimeTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.format ) { + this.flags.format = localProperties.format; + } + if ( localProperties.amsymbol ) { + this.flags.amSymbol = localProperties.amsymbol; + } + if ( localProperties.pmsymbol ) { + this.flags.pmSymbol = localProperties.pmsymbol; + } + }, + + // Over-ride for time validation + isValid: function() { + return dojo.validate.isValidTime(this.textbox.value, this.flags); + } + } +); + +/* + ****** UsStateTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is a US state abbr. + + @attr allowTerritories Allow Guam, Puerto Rico, etc. Default is true. + @attr allowMilitary Allow military 'states', e.g. Armed Forces Europe (AE). Default is true. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.UsStateTextbox", + dojo.widget.validate.ValidationTextbox, + { + mixInProperties: function(localProperties, frag) { + // Initialize properties in super-class. + dojo.widget.validate.UsStateTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if ( localProperties.allowterritories ) { + this.flags.allowTerritories = ( localProperties.allowterritories == "true" ); + } + if ( localProperties.allowmilitary ) { + this.flags.allowMilitary = ( localProperties.allowmilitary == "true" ); + } + }, + + isValid: function() { + return dojo.validate.us.isState(this.textbox.value, this.flags); + } + } +); + +/* + ****** UsZipTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is a US zip code. + Validates zip-5 and zip-5 plus 4. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.UsZipTextbox", + dojo.widget.validate.ValidationTextbox, + { + isValid: function() { + return dojo.validate.us.isZipCode(this.textbox.value); + } + } +); + +/* + ****** UsSocialSecurityNumberTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is a US Social Security Number. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.UsSocialSecurityNumberTextbox", + dojo.widget.validate.ValidationTextbox, + { + isValid: function() { + return dojo.validate.us.isSocialSecurityNumber(this.textbox.value); + } + } +); + +/* + ****** UsPhoneNumberTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is a 10-digit US phone number, an extension is optional. +*/ +dojo.widget.defineWidget( + "dojo.widget.validate.UsPhoneNumberTextbox", + dojo.widget.validate.ValidationTextbox, + { + isValid: function() { + return dojo.validate.us.isPhoneNumber(this.textbox.value); + } + } +); diff --git a/public/javascripts/dojo/src/widget/vml/Chart.js b/public/javascripts/dojo/src/widget/vml/Chart.js new file mode 100644 index 0000000..33b01f4 --- /dev/null +++ b/public/javascripts/dojo/src/widget/vml/Chart.js @@ -0,0 +1,426 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.vml.Chart"); + +dojo.require("dojo.widget.HtmlWidget"); +dojo.require("dojo.widget.Chart"); +dojo.require("dojo.math"); +dojo.require("dojo.html"); +//dojo.require("dojo.vml"); +dojo.require("dojo.graphics.color"); + +dojo.widget.vml.Chart=function(){ + dojo.widget.Chart.call(this); + dojo.widget.HtmlWidget.call(this); +}; +dojo.inherits(dojo.widget.vml.Chart, dojo.widget.HtmlWidget); +dojo.lang.extend(dojo.widget.vml.Chart, { + // widget props + templatePath:null, + templateCssPath:null, + + // state + _isInitialized:false, + hasData:false, + + // chart props + vectorNode:null, + plotArea:null, + dataGroup:null, + axisGroup:null, + + properties:{ + height:400, // defaults, will resize to the domNode. + width:600, + plotType:null, + padding:{ + top:10, + bottom:2, + left:60, + right:30 + }, + axes:{ + x:{ + plotAt:0, + label:"", + unitLabel:"", + unitType:Number, + nUnitsToShow:10, + range:{ + min:0, + max:200 + } + }, + y:{ + plotAt:0, + label:"", + unitLabel:"", + unitType:Number, + nUnitsToShow:10, + range:{ + min:0, + max:200 + } + } + } + }, + + fillInTemplate:function(args,frag){ + this.initialize(); + this.render(); + }, + parseData:function(){ + }, + initialize:function(){ + // parse the data first. + this.parseData(); + + // render the body of the chart, not the chart data. + if(this.vectorNode){ this.destroy(); } + this.vectorNode=document.createElement("div"); + this.vectorNode.style.width=this.properties.width+"px"; + this.vectorNode.style.height=this.properties.height+"px"; + this.vectorNode.style.position="relative"; + this.domNode.appendChild(this.vectorNode); + + var plotWidth=this.properties.width-this.properties.padding.left-this.properties.padding.right; + var plotHeight=this.properties.height-this.properties.padding.top-this.properties.padding.bottom; + + this.plotArea=document.createElement("div"); + this.plotArea.style.position="absolute"; + this.plotArea.style.backgroundColor="#fff"; + this.plotArea.style.top=(this.properties.padding.top)-2+"px"; + this.plotArea.style.left=(this.properties.padding.left-1)+"px"; + this.plotArea.style.width=plotWidth+"px"; + this.plotArea.style.height=plotHeight+"px"; + this.vectorNode.appendChild(this.plotArea); + + this.dataGroup=document.createElement("div"); + this.dataGroup.style.position="relative"; + this.plotArea.appendChild(this.dataGroup); + + // clipping rects, what a fucking pain. + var bg=this.domNode.style.backgroundColor; + var r=document.createElement("v:rect"); + r.setAttribute("fillcolor", bg); + r.setAttribute("stroked", "false"); + r.style.position="absolute"; + r.style.top=(-1*this.properties.padding.top)-1+"px"; + r.style.left=(-1*this.properties.padding.left)+"px"; + r.style.width=(this.properties.width-3)+"px"; + r.style.height=(this.properties.padding.top)-2+"px"; + this.vectorNode.appendChild(r); + + r=document.createElement("v:rect"); + r.setAttribute("fillcolor", bg); + r.setAttribute("stroked", "false"); + r.style.position="absolute"; + r.style.top=plotHeight-2+"px"; + r.style.left=(-1*this.properties.padding.left)+"px"; + r.style.width=(this.properties.width-3)+"px"; + r.style.height=(this.properties.padding.bottom)-2+"px"; // fixme: check this. + this.vectorNode.appendChild(r); + + r=document.createElement("v:rect"); + r.setAttribute("fillcolor", bg); + r.setAttribute("stroked", "false"); + r.style.position="absolute"; + r.style.top="-2px"; + r.style.left=(-1*this.properties.padding.left)+"px"; + r.style.width=(this.properties.padding.left-1)+"px"; + r.style.height=plotHeight+"px"; + this.vectorNode.appendChild(r); + + r=document.createElement("v:rect"); + r.setAttribute("fillcolor", bg); + r.setAttribute("stroked", "false"); + r.style.position="absolute"; + r.style.top="-2px"; + r.style.right=(-1*this.properties.padding.right)+1+"px"; + r.style.width=(this.properties.padding.right-1)+"px"; + r.style.height=plotHeight+"px"; + this.vectorNode.appendChild(r); + // end clipping rects. god that sucks, i wish VML had clipping outside of that crap vmlframe... + + this.axisGroup=document.createElement("div"); + this.axisGroup.style.position="relative"; + this.plotArea.appendChild(this.axisGroup); + + var stroke=1; + + // x axis + var line=document.createElement("v:line"); + var y=dojo.widget.vml.Chart.Plotter.getY(this.properties.axes.x.plotAt, this); + line.setAttribute("from", this.properties.padding.left-stroke + "," + y); + line.setAttribute("to", plotWidth + "," + y); + line.style.position="absolute"; + line.style.antialias="false"; + line.setAttribute("strokecolor", "#666"); + line.setAttribute("strokeweight", stroke*2+"px"); + this.axisGroup.appendChild(line); + + // y axis + var line=document.createElement("v:line"); + var y=dojo.widget.vml.Chart.Plotter.getX(this.properties.axes.y.plotAt, this); + line.setAttribute("from", y+","+this.properties.padding.top); + line.setAttribute("to", y+","+this.properties.height-this.properties.padding.bottom); + line.style.position="absolute"; + line.style.antialias="false"; + line.setAttribute("strokecolor", "#666"); + line.setAttribute("strokeweight", stroke*2+"px"); + this.axisGroup.appendChild(line); + + // labels + var size=10; + + // x axis labels. + var t=document.createElement("div"); + t.style.position="absolute"; + t.style.top=(this.properties.height-this.properties.padding.bottom+size+2)+"px"; + t.style.left=this.properties.padding.left+"px"; + t.style.fontFamily="sans-serif"; + t.style.fontSize=size+"px"; + t.innerHTML=dojo.math.round(parseFloat(this.properties.axes.x.range.min),2); + this.axisGroup.appendChild(t); + + t=document.createElement("div"); + t.style.position="absolute"; + t.style.top=(this.properties.height-this.properties.padding.bottom+size+2)+"px"; + t.style.left=(this.properties.width-this.properties.padding.right-(size/2))+"px"; + t.style.fontFamily="sans-serif"; + t.style.fontSize=size+"px"; + t.innerHTML=dojo.math.round(parseFloat(this.properties.axes.x.range.max),2); + this.axisGroup.appendChild(t); + + // y axis labels. + t=document.createElement("div"); + t.style.position="absolute"; + t.style.top=-1*(size/2)+"px"; + t.style.right=(plotWidth+4)+"px"; + t.style.fontFamily="sans-serif"; + t.style.fontSize=size+"px"; + t.innerHTML=dojo.math.round(parseFloat(this.properties.axes.y.range.max),2); + this.axisGroup.appendChild(t); + + t=document.createElement("div"); + t.style.position="absolute"; + t.style.top=(this.properties.height-this.properties.padding.bottom)+"px"; + t.style.right=(plotWidth+4)+"px"; + t.style.fontFamily="sans-serif"; + t.style.fontSize=size+"px"; + t.innerHTML=dojo.math.round(parseFloat(this.properties.axes.y.range.min),2); + this.axisGroup.appendChild(t); + + // this is last. + this.assignColors(); + this._isInitialized=true; + }, + destroy:function(){ + while(this.domNode.childNodes.length>0){ + this.domNode.removeChild(this.domNode.childNodes[0]); + } + this.vectorNode=this.plotArea=this.dataGroup=this.axisGroup=null; + }, + render:function(){ + if (this.dataGroup){ + while(this.dataGroup.childNodes.length>0){ + this.dataGroup.removeChild(this.dataGroup.childNodes[0]); + } + } else { + this.initialize(); + } + for(var i=0; i + + + +can be described as: + +dojo.???.foo = {} +dojo.???.foo.bar = {} +dojo.???.foo.bar.value = "bar"; +dojo.???.foo.baz = {} +dojo.???.foo.baz.xyzzy = {} +dojo.???.foo.baz.xyzzy.value = "xyzzy" + +*/ +// using documentFragment nomenclature to generalize in case we don't want to require passing a collection of nodes with a single parent +dojo.xml.Parse = function(){ + + function getDojoTagName(node){ + var tagName = node.tagName; + if(dojo.render.html.capable && dojo.render.html.ie && node.scopeName != 'HTML'){ + tagName = node.scopeName + ':' + tagName; + } + if(tagName.substr(0,5).toLowerCase() == "dojo:"){ + return tagName.toLowerCase(); + } + + if(tagName.substr(0,4).toLowerCase() == "dojo"){ + // FIXME: this assumes tag names are always lower case + return "dojo:" + tagName.substring(4).toLowerCase(); + } + + // allow lower-casing + var djt = node.getAttribute("dojoType") || node.getAttribute("dojotype"); + if(djt){ + if(djt.indexOf(":")<0){ + djt = "dojo:"+djt; + } + return djt.toLowerCase(); + } + + if(node.getAttributeNS && node.getAttributeNS(dojo.dom.dojoml,"type")){ + return "dojo:" + node.getAttributeNS(dojo.dom.dojoml,"type").toLowerCase(); + } + try{ + // FIXME: IE really really doesn't like this, so we squelch errors for it + djt = node.getAttribute("dojo:type"); + }catch(e){ /* FIXME: log? */ } + + if(djt){ return "dojo:"+djt.toLowerCase(); } + + if(!dj_global["djConfig"] || !djConfig["ignoreClassNames"]){ + // FIXME: should we make this optionally enabled via djConfig? + var classes = node.className||node.getAttribute("class"); + // FIXME: following line, without check for existence of classes.indexOf + // breaks firefox 1.5's svg widgets + if(classes && classes.indexOf && classes.indexOf("dojo-") != -1){ + var aclasses = classes.split (" "); + for(var x=0; x 5 && aclasses[x].indexOf("dojo-") >= 0){ + return "dojo:"+aclasses[x].substr(5).toLowerCase(); + } + } + } + } + + return tagName.toLowerCase(); + } + + this.parseElement = function(node, hasParentNodeSet, optimizeForDojoML, thisIdx){ + + var parsedNodeSet = {}; + + //There's a weird bug in IE where it counts end tags, e.g. as nodes that should be parsed. Ignore these + if(node.tagName && node.tagName.indexOf("/") == 0){ + return null; + } + + var tagName = getDojoTagName(node); + parsedNodeSet[tagName] = []; + if(tagName.substr(0,4).toLowerCase()=="dojo"){ + parsedNodeSet.namespace = "dojo"; + }else{ + var pos = tagName.indexOf(":"); + if(pos > 0){ + parsedNodeSet.namespace = tagName.substring(0,pos); + } + } + + var process = false; + if(!optimizeForDojoML){process=true;} + else if(parsedNodeSet.namespace&&dojo.getNamespace(parsedNodeSet.namespace)){process=true;} + else if(dojo.widget.tags[tagName]){ + dojo.deprecated('dojo.xml.Parse.parseElement', 'Widgets should be placed in a defined namespace', "0.5"); + process = true; + } + + if(process){ + var attributeSet = this.parseAttributes(node); + for(var attr in attributeSet){ + if((!parsedNodeSet[tagName][attr])||(typeof parsedNodeSet[tagName][attr] != "array")){ + parsedNodeSet[tagName][attr] = []; + } + parsedNodeSet[tagName][attr].push(attributeSet[attr]); + } + // FIXME: we might want to make this optional or provide cloning instead of + // referencing, but for now, we include a node reference to allow + // instantiated components to figure out their "roots" + parsedNodeSet[tagName].nodeRef = node; + parsedNodeSet.tagName = tagName; + parsedNodeSet.index = thisIdx||0; + // dojo.debug("parseElement: set the element tagName = "+parsedNodeSet.tagName+" and namespace to "+parsedNodeSet.namespace); + } + + var count = 0; + for(var i = 0; i < node.childNodes.length; i++){ + var tcn = node.childNodes.item(i); + switch(tcn.nodeType){ + case dojo.dom.ELEMENT_NODE: // element nodes, call this function recursively + count++; + var ctn = getDojoTagName(tcn); + if(!parsedNodeSet[ctn]){ + parsedNodeSet[ctn] = []; + } + parsedNodeSet[ctn].push(this.parseElement(tcn, true, optimizeForDojoML, count)); + if( (tcn.childNodes.length == 1)&& + (tcn.childNodes.item(0).nodeType == dojo.dom.TEXT_NODE)){ + parsedNodeSet[ctn][parsedNodeSet[ctn].length-1].value = tcn.childNodes.item(0).nodeValue; + } + break; + case dojo.dom.TEXT_NODE: // if a single text node is the child, treat it as an attribute + if(node.childNodes.length == 1){ + parsedNodeSet[tagName].push({ value: node.childNodes.item(0).nodeValue }); + } + break; + default: break; + /* + case dojo.dom.ATTRIBUTE_NODE: // attribute node... not meaningful here + break; + case dojo.dom.CDATA_SECTION_NODE: // cdata section... not sure if this would ever be meaningful... might be... + break; + case dojo.dom.ENTITY_REFERENCE_NODE: // entity reference node... not meaningful here + break; + case dojo.dom.ENTITY_NODE: // entity node... not sure if this would ever be meaningful + break; + case dojo.dom.PROCESSING_INSTRUCTION_NODE: // processing instruction node... not meaningful here + break; + case dojo.dom.COMMENT_NODE: // comment node... not not sure if this would ever be meaningful + break; + case dojo.dom.DOCUMENT_NODE: // document node... not sure if this would ever be meaningful + break; + case dojo.dom.DOCUMENT_TYPE_NODE: // document type node... not meaningful here + break; + case dojo.dom.DOCUMENT_FRAGMENT_NODE: // document fragment node... not meaningful here + break; + case dojo.dom.NOTATION_NODE:// notation node... not meaningful here + break; + */ + } + } + //return (hasParentNodeSet) ? parsedNodeSet[node.tagName] : parsedNodeSet; + //if(parsedNodeSet.tagName)dojo.debug("parseElement: RETURNING NODE WITH TAGNAME "+parsedNodeSet.tagName); + return parsedNodeSet; + }; + + /* parses a set of attributes on a node into an object tree */ + this.parseAttributes = function(node){ + var parsedAttributeSet = {}; + var atts = node.attributes; + // TODO: should we allow for duplicate attributes at this point... + // would any of the relevant dom implementations even allow this? + var attnode, i=0; + while((attnode=atts[i++])){ + if((dojo.render.html.capable)&&(dojo.render.html.ie)){ + if(!attnode){ continue; } + if( (typeof attnode == "object")&& + (typeof attnode.nodeValue == 'undefined')|| + (attnode.nodeValue == null)|| + (attnode.nodeValue == '')){ + continue; + } + } + + var nn = attnode.nodeName.split(":"); + nn = (nn.length == 2) ? nn[1] : attnode.nodeName; + + parsedAttributeSet[nn] = { + value: attnode.nodeValue + }; + } + return parsedAttributeSet; + }; +}; diff --git a/public/javascripts/dojo/src/xml/__package__.js b/public/javascripts/dojo/src/xml/__package__.js new file mode 100644 index 0000000..d1c38e6 --- /dev/null +++ b/public/javascripts/dojo/src/xml/__package__.js @@ -0,0 +1,18 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.require("dojo.xml.Parse"); +dojo.kwCompoundRequire({ + common: ["dojo.dom"], + browser: ["dojo.html.*"], + dashboard: ["dojo.html.*"], + svg: ["dojo.xml.svgUtil"] +}); +dojo.provide("dojo.xml.*"); diff --git a/public/javascripts/dojo/src/xml/svgUtil.js b/public/javascripts/dojo/src/xml/svgUtil.js new file mode 100644 index 0000000..e6c9f05 --- /dev/null +++ b/public/javascripts/dojo/src/xml/svgUtil.js @@ -0,0 +1,32 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.xml.svgUtil"); +// FIXME: add imports for deps! + +dojo.xml.svgUtil = new function(){ + + this.getInnerWidth = function(node){ + // FIXME: need to find out from dylan how to + } + + this.getOuterWidth = function(node){ + + } + + this.getInnerHeight = function(node){ + + } + + this.getOuterHeight = function(node){ + + } + +} diff --git a/public/javascripts/dojo/storage_dialog.swf b/public/javascripts/dojo/storage_dialog.swf new file mode 100644 index 0000000..cb15ec8 Binary files /dev/null and b/public/javascripts/dojo/storage_dialog.swf differ diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js new file mode 100644 index 0000000..92d1f73 --- /dev/null +++ b/public/javascripts/dragdrop.js @@ -0,0 +1,584 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// 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 + }, 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); + }, + + isContained: function(element, drop) { + var parentNode = element.parentNode; + return drop._containers.detect(function(c) { return parentNode == 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; + + if(this.last_active) this.deactivate(this.last_active); + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) { + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + if(drop.greedy) { + Droppables.activate(drop); + throw $break; + } + } + }); + }, + + 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(draggbale) { + 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); + }, + + 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.MoveBy(element, -top_offset, -left_offset, {duration:dur}); + }, + endeffect: function(element) { + new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); + }, + zindex: 1000, + revert: false, + 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')) + this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; + if(!this.handle) this.handle = $(options.handle); + if(!this.handle) this.handle = this.element; + + 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(this.element.style.left || '0'), + parseInt(this.element.style.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=='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); + } + + 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); + + // 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.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]; + + 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 + } +} + +/*--------------------------------------------------------------------------*/ + +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: new Array(), + + options: function(element){ + element = $(element); + return this.sortables.detect(function(s) { return s.element == element }); + }, + + destroy: function(element){ + element = $(element); + this.sortables.findAll(function(s) { return s.element == element }).each(function(s){ + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + }); + this.sortables = this.sortables.reject(function(s) { return s.element == element }); + }, + + create: function(element) { + element = $(element); + var options = Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag: 'tagname' + dropOnEmpty: false, + tree: false, // fixme: unimplemented + 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, + format: null, + 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, + 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, + hoverclass: options.hoverclass, + onHover: Sortable.onHover, + greedy: !options.dropOnEmpty + } + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables = []; + options.droppables = []; + + // make it so + + // drop on empty handling + if(options.dropOnEmpty) { + Droppables.add(element, + {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false}); + 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); + options.droppables.push(e); + }); + + // keep reference + this.sortables.push(options); + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdate)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + if(!element.hasChildNodes()) return null; + var elements = []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() && + (!options.only || (Element.hasClassName(e, options.only)))) + elements.push(e); + if(options.tree) { + var grandchildren = this.findElements(e, options); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : null); + }, + + onHover: function(element, dropon, overlap) { + 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) { + if(element.parentNode!=dropon) { + var oldParentNode = element.parentNode; + dropon.appendChild(element); + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon).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); + }, + + serialize: function(element) { + element = $(element); + var sortableOptions = this.options(element); + var options = Object.extend({ + tag: sortableOptions.tag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format || /^[^_]*_(.*)$/ + }, arguments[1] || {}); + return $(this.findElements(element, options) || []).map( function(item) { + return (encodeURIComponent(options.name) + "[]=" + + encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); + }).join("&"); + } +} \ No newline at end of file diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js new file mode 100644 index 0000000..414398c --- /dev/null +++ b/public/javascripts/effects.js @@ -0,0 +1,854 @@ +// 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. + +/* ------------- element ext -------------- */ + +// 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.collectTextNodesIgnoreClass = function(element, ignoreclass) { + var children = $(element).childNodes; + var text = ''; + var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); + + for (var i = 0; i < children.length; i++) { + if(children[i].nodeType==3) { + text+=children[i].nodeValue; + } else { + if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) + text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); + } + } + + return text; +} + +Element.setStyle = function(element, style) { + element = $(element); + for(k in style) element.style[k.camelize()] = style[k]; +} + +Element.setContentZoom = function(element, percent) { + 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) { + return $A($(element).getElementsByTagName('*')).select( + function(c) { return Element.hasClassName(c, className) }); +} + +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 })); + }); + } +}; + +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.Queue = { + effects: [], + _each: function(iterator) { + this.effects._each(iterator); + }, + interval: null, + add: function(effect) { + var timestamp = new Date().getTime(); + + switch(effect.options.queue) { + 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; + 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); + } +} +Object.extend(Effect.Queue, Enumerable); + +Effect.Base = function() {}; +Effect.Base.prototype = { + position: null, + setOptions: function(options) { + this.options = Object.extend({ + 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' + }, options || {}); + }, + start: function(options) { + this.setOptions(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.Queue.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.Queue.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)) + Element.setStyle(this.element, {zoom: 1}); + var options = Object.extend({ + from: Element.getOpacity(this.element) || 0.0, + to: 1.0 + }, arguments[1] || {}); + this.start(options); + }, + update: function(position) { + Element.setOpacity(this.element, position); + } +}); + +Effect.MoveBy = Class.create(); +Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), { + initialize: function(element, toTop, toLeft) { + this.element = $(element); + this.toTop = toTop; + this.toLeft = toLeft; + this.start(arguments[3]); + }, + 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) + Element.makePositioned(this.element); + this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); + this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0'); + }, + update: function(position) { + Element.setStyle(this.element, { + top: this.toTop * position + this.originalTop + 'px', + left: this.toLeft * position + this.originalLeft + 'px' + }); + } +}); + +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 = Element.getStyle(this.element,'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 = Element.getStyle(this.element,'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) + Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType }); + this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); + }, + finish: function(position) { + if (this.restoreAfterFinish) Element.setStyle(this.element, 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'; + } + } + Element.setStyle(this.element, 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(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; } + // Disable background image during the effect + this.oldStyle = { + backgroundImage: Element.getStyle(this.element, 'background-image') }; + Element.setStyle(this.element, {backgroundImage: 'none'}); + if(!this.options.endcolor) + this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); + if(!this.options.restorecolor) + this.options.restorecolor = Element.getStyle(this.element, '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) { + Element.setStyle(this.element,{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() { + Element.setStyle(this.element, 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) { + var oldOpacity = Element.getInlineOpacity(element); + var options = Object.extend({ + from: Element.getOpacity(element) || 1.0, + to: 0.0, + afterFinishInternal: function(effect) { with(Element) { + if(effect.options.to!=0) return; + hide(effect.element); + setStyle(effect.element, {opacity: oldOpacity}); }} + }, arguments[1] || {}); + return new Effect.Opacity(element,options); +} + +Effect.Appear = function(element) { + var options = Object.extend({ + from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0), + to: 1.0, + beforeSetup: function(effect) { with(Element) { + setOpacity(effect.element, effect.options.from); + show(effect.element); }} + }, arguments[1] || {}); + return new Effect.Opacity(element,options); +} + +Effect.Puff = function(element) { + element = $(element); + var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, '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) { with(Element) { + setStyle(effect.effects[0].element, {position: 'absolute'}); }}, + afterFinishInternal: function(effect) { with(Element) { + hide(effect.effects[0].element); + setStyle(effect.effects[0].element, oldStyle); }} + }, arguments[1] || {}) + ); +} + +Effect.BlindUp = function(element) { + element = $(element); + Element.makeClipping(element); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + restoreAfterFinish: true, + afterFinishInternal: function(effect) { with(Element) { + [hide, undoClipping].call(effect.element); }} + }, arguments[1] || {}) + ); +} + +Effect.BlindDown = function(element) { + element = $(element); + var oldHeight = Element.getStyle(element, 'height'); + var elementDimensions = Element.getDimensions(element); + 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) { with(Element) { + makeClipping(effect.element); + setStyle(effect.element, {height: '0px'}); + show(effect.element); + }}, + afterFinishInternal: function(effect) { with(Element) { + undoClipping(effect.element); + setStyle(effect.element, {height: oldHeight}); + }} + }, arguments[1] || {}) + ); +} + +Effect.SwitchOff = function(element) { + element = $(element); + var oldOpacity = Element.getInlineOpacity(element); + 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) { with(Element) { + [makePositioned,makeClipping].call(effect.element); + }}, + afterFinishInternal: function(effect) { with(Element) { + [hide,undoClipping,undoPositioned].call(effect.element); + setStyle(effect.element, {opacity: oldOpacity}); + }} + }) + } + }); +} + +Effect.DropOut = function(element) { + element = $(element); + var oldStyle = { + top: Element.getStyle(element, 'top'), + left: Element.getStyle(element, 'left'), + opacity: Element.getInlineOpacity(element) }; + return new Effect.Parallel( + [ new Effect.MoveBy(element, 100, 0, { sync: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 }) ], + Object.extend( + { duration: 0.5, + beforeSetup: function(effect) { with(Element) { + makePositioned(effect.effects[0].element); }}, + afterFinishInternal: function(effect) { with(Element) { + [hide, undoPositioned].call(effect.effects[0].element); + setStyle(effect.effects[0].element, oldStyle); }} + }, arguments[1] || {})); +} + +Effect.Shake = function(element) { + element = $(element); + var oldStyle = { + top: Element.getStyle(element, 'top'), + left: Element.getStyle(element, 'left') }; + return new Effect.MoveBy(element, 0, 20, + { duration: 0.05, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, -40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, 40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, -40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, 40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, -20, + { duration: 0.05, afterFinishInternal: function(effect) { with(Element) { + undoPositioned(effect.element); + setStyle(effect.element, oldStyle); + }}}) }}) }}) }}) }}) }}); +} + +Effect.SlideDown = function(element) { + element = $(element); + Element.cleanWhitespace(element); + // SlideDown need to have the content of the element wrapped in a container element with fixed height! + var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); + var elementDimensions = Element.getDimensions(element); + 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) { with(Element) { + makePositioned(effect.element); + makePositioned(effect.element.firstChild); + if(window.opera) setStyle(effect.element, {top: ''}); + makeClipping(effect.element); + setStyle(effect.element, {height: '0px'}); + show(element); }}, + afterUpdateInternal: function(effect) { with(Element) { + setStyle(effect.element.firstChild, {bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, + afterFinishInternal: function(effect) { with(Element) { + undoClipping(effect.element); + undoPositioned(effect.element.firstChild); + undoPositioned(effect.element); + setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} + }, arguments[1] || {}) + ); +} + +Effect.SlideUp = function(element) { + element = $(element); + Element.cleanWhitespace(element); + var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + scaleMode: 'box', + scaleFrom: 100, + restoreAfterFinish: true, + beforeStartInternal: function(effect) { with(Element) { + makePositioned(effect.element); + makePositioned(effect.element.firstChild); + if(window.opera) setStyle(effect.element, {top: ''}); + makeClipping(effect.element); + show(element); }}, + afterUpdateInternal: function(effect) { with(Element) { + setStyle(effect.element.firstChild, {bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, + afterFinishInternal: function(effect) { with(Element) { + [hide, undoClipping].call(effect.element); + undoPositioned(effect.element.firstChild); + undoPositioned(effect.element); + setStyle(effect.element.firstChild, {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) { with(Element) { + makeClipping(effect.element); }}, + afterFinishInternal: function(effect) { with(Element) { + hide(effect.element); + undoClipping(effect.element); }} + }); +} + +Effect.Grow = function(element) { + element = $(element); + var options = Object.extend({ + direction: 'center', + moveTransistion: 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(element) }; + + var dims = Element.getDimensions(element); + 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.MoveBy(element, initialMoveY, initialMoveX, { + duration: 0.01, + beforeSetup: function(effect) { with(Element) { + hide(effect.element); + makeClipping(effect.element); + makePositioned(effect.element); + }}, + afterFinishInternal: function(effect) { + new Effect.Parallel( + [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), + new Effect.MoveBy(effect.element, moveY, moveX, { 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) { with(Element) { + setStyle(effect.effects[0].element, {height: '0px'}); + show(effect.effects[0].element); }}, + afterFinishInternal: function(effect) { with(Element) { + [undoClipping, undoPositioned].call(effect.effects[0].element); + setStyle(effect.effects[0].element, oldStyle); }} + }, options) + ) + } + }); +} + +Effect.Shrink = function(element) { + element = $(element); + var options = Object.extend({ + direction: 'center', + moveTransistion: 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(element) }; + + var dims = Element.getDimensions(element); + 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.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition }) + ], Object.extend({ + beforeStartInternal: function(effect) { with(Element) { + [makePositioned, makeClipping].call(effect.effects[0].element) }}, + afterFinishInternal: function(effect) { with(Element) { + [hide, undoClipping, undoPositioned].call(effect.effects[0].element); + setStyle(effect.effects[0].element, oldStyle); }} + }, options) + ); +} + +Effect.Pulsate = function(element) { + element = $(element); + var options = arguments[1] || {}; + var oldOpacity = Element.getInlineOpacity(element); + 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) { Element.setStyle(effect.element, {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) { with(Element) { + [hide, undoClipping].call(effect.element); + setStyle(effect.element, oldStyle); + }} }); + }}, arguments[1] || {})); +} diff --git a/public/javascripts/prototype.js b/public/javascripts/prototype.js new file mode 100644 index 0000000..e9ccd3c --- /dev/null +++ b/public/javascripts/prototype.js @@ -0,0 +1,1785 @@ +/* Prototype JavaScript framework, version 1.4.0 + * (c) 2005 Sam Stephenson + * + * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff + * against the source tree, available from the Prototype darcs repository. + * + * 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.4.0', + 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 (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; + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} +Object.extend(String.prototype, { + 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(eval); + }, + + 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('\\', '\\\\').replace("'", '\\\'') + "'"; + } +}); + +String.prototype.parseQuery = String.prototype.toQueryParams; + +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 (value >= (result || value)) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value <= (result || value)) + 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) { + iterator(value = collections.pluck(index)); + return value; + }); + }, + + 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); + +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.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(); + }, + + shift: function() { + var result = this[0]; + for (var i = 0; i < this.length - 1; i++) + this[i] = this[i + 1]; + this.length--; + return result; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (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 ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || 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, + 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]; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', + 'application/x-www-form-urlencoded'); + + /* 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); + } +}); +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(child); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) { + var Element = new Object(); +} + +Object.extend(Element, { + 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); + }, + + 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*$/); + }, + + 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 (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; + } +}); + +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) { + if (this.element.tagName.toLowerCase() == 'tbody') { + 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 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 (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; + if (!value && !('value' in opt)) + value = opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = new Array(); + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) { + var optValue = opt.value; + if (!optValue && !('value' in opt)) + optValue = opt.text; + value.push(optValue); + } + } + 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 */ +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/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..4ab9e89 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1 @@ +# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file \ No newline at end of file diff --git a/public/stylesheets/grindable.css b/public/stylesheets/grindable.css new file mode 100644 index 0000000..fe339ae --- /dev/null +++ b/public/stylesheets/grindable.css @@ -0,0 +1,122 @@ +#Container { + float: none; + margin: 0 auto; + text-align: center; +} + +#Content { + margin: 0; + padding: 5px; + text-align: left; + border-top: none; + float: left; +} + +#Container, #Content { + width: 750px; +} + +body, p, ol, ul, td { + font-family: georgia, verdana, arial, helvetica, sans-serif; + line-height: 18px; +} + +h1, h2, h3 { color: #966956; } +h1 { font-size: 28px } +h2 { font-size: 19px } +h3 { font-size: 16px } + +.inputBox { + font-family: georgia, verdana, arial, helvetica, sans-serif; + border: 1px solid #966956; + padding: 2px; +} + +#info, #errorExplanation { + font-style: italic; + padding: 10px; + margin: 10px 0px 10px 0px; +} + +#errorExplanation { + border: 1px solid #d20000; + background-color: #d28f8f; + color: #8b0000; +} + +#info { + border: 1px solid #966956; + background-color: #fffecb; + color: #006400; +} + +.formRequest { + border: 1px solid #555555; + background-color: #eeeeee; + padding: 10px; + margin-top: 10px; + margin-bottom: 10px; +} + +#milkBox, #fundBox, #contributeBox { + border: 1px solid black; + padding: 0px 5px 0px 5px; + margin: 10px 0px 10px 0px; +} + +#milkBox { + background-color: #ffffff; + background-image: url(/images/milk-print.jpg); + background-repeat: repeat; +} + +#fundBox { + background-color: #99FF99; + background-image: url(/images/balance.jpg); + background-repeat: no-repeat; + background-position: center right; +} + +.even { + background-color: #bcffcd; +} + +.odd { + background-color: #46ff76; +} + +.collectionList { + padding: 2px; +} + +.collectionList th { + text-align: center; +} + +.collectionList a img { + text-decoration: none; + border: none; +} + +.dojoDialog { + background: #F3EBD8; + border: 1px solid #999; + -moz-border-radius: 5px; + padding: 4px; + max-width: 700px; + height: auto; + max-height: 400px; + overflow: auto; +} + +.dialog_header { + margin-bottom:10px; + background:#787d86; + padding:2px 5px 2px 5px; + text-align:right; + -moz-border-radius : 5px; +} + +.dialog_header a { + color:white; +} \ No newline at end of file diff --git a/script/about b/script/about new file mode 100755 index 0000000..7b07d46 --- /dev/null +++ b/script/about @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/about' \ No newline at end of file diff --git a/script/breakpointer b/script/breakpointer new file mode 100755 index 0000000..64af76e --- /dev/null +++ b/script/breakpointer @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/breakpointer' \ No newline at end of file diff --git a/script/console b/script/console new file mode 100755 index 0000000..42f28f7 --- /dev/null +++ b/script/console @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/console' \ No newline at end of file diff --git a/script/destroy b/script/destroy new file mode 100755 index 0000000..fa0e6fc --- /dev/null +++ b/script/destroy @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/destroy' \ No newline at end of file diff --git a/script/generate b/script/generate new file mode 100755 index 0000000..ef976e0 --- /dev/null +++ b/script/generate @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/generate' \ No newline at end of file diff --git a/script/performance/benchmarker b/script/performance/benchmarker new file mode 100755 index 0000000..c842d35 --- /dev/null +++ b/script/performance/benchmarker @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/performance/benchmarker' diff --git a/script/performance/profiler b/script/performance/profiler new file mode 100755 index 0000000..d855ac8 --- /dev/null +++ b/script/performance/profiler @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/performance/profiler' diff --git a/script/plugin b/script/plugin new file mode 100755 index 0000000..26ca64c --- /dev/null +++ b/script/plugin @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/plugin' \ No newline at end of file diff --git a/script/process/reaper b/script/process/reaper new file mode 100755 index 0000000..c77f045 --- /dev/null +++ b/script/process/reaper @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/process/reaper' diff --git a/script/process/spawner b/script/process/spawner new file mode 100755 index 0000000..7118f39 --- /dev/null +++ b/script/process/spawner @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/process/spawner' diff --git a/script/process/spinner b/script/process/spinner new file mode 100755 index 0000000..6816b32 --- /dev/null +++ b/script/process/spinner @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/process/spinner' diff --git a/script/runner b/script/runner new file mode 100755 index 0000000..ccc30f9 --- /dev/null +++ b/script/runner @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/runner' \ No newline at end of file diff --git a/script/server b/script/server new file mode 100755 index 0000000..1b9a002 --- /dev/null +++ b/script/server @@ -0,0 +1,22 @@ +#!/usr/bin/env ruby + +argv = ARGV.dup + +mroot = "#{File.dirname(__FILE__) + '/..'}" +if File.exists?("#{mroot}/log/mongrel.pid") + pid = "" + File.open("#{mroot}/log/mongrel.pid") {|f| pid = f.readline} +else + pid = false +end + +if (pid != false) && (ARGV[0] == 'stop') + command = "echo 'Mongrel stopping...';kill " + pid + ";echo 'Mongrel stopped.'" + argv = [] +elsif (pid != false) + command = "echo '\nMongrel is running with PID " + pid + "'\necho 'Use \"script/server stop\" to stop Mongrel\n'" +else + command = "mongrel_rails start -c #{mroot} " +end + +exec command + argv.join(' ') diff --git a/test/fixtures/baristas.yml b/test/fixtures/baristas.yml new file mode 100644 index 0000000..8794d28 --- /dev/null +++ b/test/fixtures/baristas.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first: + id: 1 +another: + id: 2 diff --git a/test/fixtures/funds.yml b/test/fixtures/funds.yml new file mode 100644 index 0000000..8794d28 --- /dev/null +++ b/test/fixtures/funds.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first: + id: 1 +another: + id: 2 diff --git a/test/fixtures/ledgers.yml b/test/fixtures/ledgers.yml new file mode 100644 index 0000000..8794d28 --- /dev/null +++ b/test/fixtures/ledgers.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first: + id: 1 +another: + id: 2 diff --git a/test/functional/activity_controller_test.rb b/test/functional/activity_controller_test.rb new file mode 100644 index 0000000..62a515d --- /dev/null +++ b/test/functional/activity_controller_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'activity_controller' + +# Re-raise errors caught by the controller. +class ActivityController; def rescue_action(e) raise e end; end + +class ActivityControllerTest < Test::Unit::TestCase + def setup + @controller = ActivityController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/functional/barista_controller_test.rb b/test/functional/barista_controller_test.rb new file mode 100644 index 0000000..b688a25 --- /dev/null +++ b/test/functional/barista_controller_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'barista_controller' + +# Re-raise errors caught by the controller. +class BaristaController; def rescue_action(e) raise e end; end + +class BaristaControllerTest < Test::Unit::TestCase + def setup + @controller = BaristaController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/functional/cafe_controller_test.rb b/test/functional/cafe_controller_test.rb new file mode 100644 index 0000000..36cb554 --- /dev/null +++ b/test/functional/cafe_controller_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'cafe_controller' + +# Re-raise errors caught by the controller. +class CafeController; def rescue_action(e) raise e end; end + +class CafeControllerTest < Test::Unit::TestCase + def setup + @controller = CafeController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/functional/fund_controller_test.rb b/test/functional/fund_controller_test.rb new file mode 100644 index 0000000..f6dae5e --- /dev/null +++ b/test/functional/fund_controller_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'fund_controller' + +# Re-raise errors caught by the controller. +class FundController; def rescue_action(e) raise e end; end + +class FundControllerTest < Test::Unit::TestCase + def setup + @controller = FundController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..a299c7f --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,28 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'test_help' + +class Test::Unit::TestCase + # Transactional fixtures accelerate your tests by wrapping each test method + # in a transaction that's rolled back on completion. This ensures that the + # test database remains unchanged so your fixtures don't have to be reloaded + # between every test method. Fewer database queries means faster tests. + # + # Read Mike Clark's excellent walkthrough at + # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting + # + # Every Active Record database supports transactions except MyISAM tables + # in MySQL. Turn off transactional fixtures in this case; however, if you + # don't care one way or the other, switching from MyISAM to InnoDB tables + # is recommended. + self.use_transactional_fixtures = true + + # Instantiated fixtures are slow, but give you @david where otherwise you + # would need people(:david). If you don't want to migrate your existing + # test cases which use the @david style and don't mind the speed hit (each + # instantiated fixtures translates to a database query per test method), + # then set this back to true. + self.use_instantiated_fixtures = false + + # Add more helper methods to be used by all tests here... +end diff --git a/test/unit/barista_test.rb b/test/unit/barista_test.rb new file mode 100644 index 0000000..344cda5 --- /dev/null +++ b/test/unit/barista_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class BaristaTest < Test::Unit::TestCase + fixtures :baristas + + # Replace this with your real tests. + def test_truth + assert_kind_of Barista, baristas(:first) + end +end diff --git a/test/unit/fund_test.rb b/test/unit/fund_test.rb new file mode 100644 index 0000000..789caf6 --- /dev/null +++ b/test/unit/fund_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class FundTest < Test::Unit::TestCase + fixtures :funds + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/unit/ledger_test.rb b/test/unit/ledger_test.rb new file mode 100644 index 0000000..37ab504 --- /dev/null +++ b/test/unit/ledger_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class LedgerTest < Test::Unit::TestCase + fixtures :ledgers + + # Replace this with your real tests. + def test_truth + assert_kind_of Ledger, ledgers(:first) + end +end