diff --git a/CHANGELOG b/CHANGELOG index 18b4288..2bc1ec4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -187,7 +187,7 @@ # runs the one statement 10 times script/benchmarker 10 'Person.expensive_method(10)' - + # pits the two statements against each other with 50 runs each script/benchmarker 50 'Person.expensive_method(10)' 'Person.cheap_method(10)' @@ -227,18 +227,18 @@ * Changed .htaccess to allow dispatch.* to be called from a sub-directory as part of the push with Action Pack to make Rails work on non-vhost setups #826 [Nicholas Seckar/Tobias Luetke] * Added script/runner which can be used to run code inside the environment by eval'ing the first parameter. Examples: - + ./script/runner 'ReminderService.deliver' ./script/runner 'Mailer.receive(STDIN.read)' - + This makes it easier to do CRON and postfix scripts without actually making a script just to trigger 1 line of code. * Fixed webrick_server cookie handling to allow multiple cookes to be set at once #800, #813 [dave@cherryville.org] * Fixed the Rakefile's interaction with postgresql to: - 1. Use PGPASSWORD and PGHOST in the environment to fix prompting for - passwords when connecting to a remote db and local socket connections. + 1. Use PGPASSWORD and PGHOST in the environment to fix prompting for + passwords when connecting to a remote db and local socket connections. 2. Add a '-x' flag to pg_dump which stops it dumping privileges #807 [rasputnik] 3. Quote the user name and use template0 when dumping so the functions doesn't get dumped too #855 [pburleson] 4. Use the port if available #875 [madrobby] @@ -301,10 +301,10 @@ Controller: components/list/items_controller.rb (holds a List::ItemsController class with uses_component_template_root called) - + Model : components/list/item.rb (namespace is still shared, so an Item model in app/models will take precedence) - + Views : components/list/items/show.rhtml @@ -397,11 +397,11 @@ * Fixed dependency management to happen in a unified fashion for Active Record and Action Pack using the new Dependencies module. This means that the environment options needs to change from: - + Before in development.rb: ActionController::Base.reload_dependencies = true   ActiveRecord::Base.reload_associations     = true - + Now in development.rb: Dependencies.mechanism = :load @@ -455,41 +455,41 @@ * Added breakpoint support 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. + + 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\"}>, + => "[#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 + >> 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 * Changed environments to be configurable through an environment variable. By default, the environment is "development", but you can change that and set your own by configuring the Apache vhost with a string like (mod_env must be available on the server): - + SetEnv RAILS_ENV production - + ...if you're using WEBrick, you can pick the environment to use with the command-line parameters -e/--environment, like this: - + ruby public/dispatcher.servlet -e production * Added a new default environment called "development", which leaves the production environment to be tuned exclusively for that. @@ -504,11 +504,11 @@ app/controllers/account_controller.rb # URL: /account/ app/controllers/admin/account_controller.rb # URL: /admin/account/ - + NOTE: You need to update your public/.htaccess with the new rules to pick it up -* Added reloading for associations and dependencies under cached environments like FastCGI and mod_ruby. This makes it possible to use - those environments for development. This is turned on by default, but can be turned off with +* Added reloading for associations and dependencies under cached environments like FastCGI and mod_ruby. This makes it possible to use + those environments for development. This is turned on by default, but can be turned off with ActiveRecord::Base.reload_associations = false and ActionController::Base.reload_dependencies = false in production environments. * Added support for sub-directories in app/models. So now you can have something like Basecamp with: @@ -517,7 +517,7 @@ app/models/project app/models/participants app/models/settings - + It's poor man's namespacing, but only for file-system organization. You still require files just like before. Nothing changes inside the files themselves. @@ -537,7 +537,7 @@ @david.projects << @new_project breakpoint "Let's have a closer look at @david" end - + You need to install dev-utils yourself for this to work ("gem install dev-util"). * Added shared generator behavior so future upgrades should be possible without manually copying over files [Jeremy Kemper] @@ -596,7 +596,7 @@ *0.7.0* -* Added an optional second argument to the new_model script that allows the programmer to specify the table name, +* Added an optional second argument to the new_model script that allows the programmer to specify the table name, which will used to generate a custom table_name method in the model and will also be used in the creation of fixtures. [Kevin Radloff] @@ -610,8 +610,8 @@ * create_fixtures in both the functional and unit test helper now turns off the log during fixture generation and can generate more than one fixture at a time. Which makes it possible for assignments like: - - @people, @projects, @project_access, @companies, @accounts = + + @people, @projects, @project_access, @companies, @accounts = create_fixtures "people", "projects", "project_access", "companies", "accounts" * Upgraded to Action Pack 0.8.5 (locally-scoped variables, partials, advanced send_file) @@ -623,7 +623,7 @@ * No longer specifies a template for rdoc, so it'll use whatever is default (you can change it in the rakefile) -* The new_model generator will now use the same rules for plural wordings as Active Record +* The new_model generator will now use the same rules for plural wordings as Active Record (so Category will give categories, not categorys) [Kevin Radloff] * dispatch.fcgi now sets FCGI_PURE_RUBY to true to ensure that it's the Ruby version that's loaded [danp] @@ -649,13 +649,13 @@ * Added environments that can be included from any script to get the full Active Record and Action Controller context running. This can be used by maintenance scripts or to interact with the model through IRB. Example: - + require 'config/environments/production' - + for account in Account.find_all account.recalculate_interests end - + A short migration script for an account model that had it's interest calculation strategy changed. * Accessing the index of a controller with "/weblog" will now redirect to "/weblog/" (only on Apache, not WEBrick) @@ -678,7 +678,7 @@ * Added lib in root as a place to store app specific libraries -* Added lib and vendor to load_path, so anything store within can be loaded directly. +* Added lib and vendor to load_path, so anything store within can be loaded directly. Hence lib/redcloth.rb can be loaded with require "redcloth" * Upgraded to Action Pack 0.7.8 (lots of fixes) @@ -692,7 +692,7 @@ * Updated the generated template stubs to valid XHTML files -* Ensure that controllers generated are capitalized, so "new_controller TodoLists" +* Ensure that controllers generated are capitalized, so "new_controller TodoLists" gives the same as "new_controller Todolists" and "new_controller todolists". diff --git a/README b/README index 934d835..2a02bf0 100644 --- a/README +++ b/README @@ -1,18 +1,18 @@ Cat Herder (source code to pdxruby.org) -This application was written way back in late 2005 at a group hackfest hosted +This application was written way back in late 2005 at a group hackfest hosted by the Portland Ruby Brigade. We wanted a way to propose and RSVP for events -without requiring any particular person or group to manage a calendar for -everyone else. +without requiring any particular person or group to manage a calendar for +everyone else. -Anyone can register for an account, propose an event, and sign up to attend +Anyone can register for an account, propose an event, and sign up to attend other people's events. There is also some basic support for aggregation of members' RSS feeds, and feedback from event participants, but the primary use of the system is still as a simple event calendar. -The file doc/TODO contains a few miscellaneous items we've thought about +The file doc/TODO contains a few miscellaneous items we've thought about changing over the years, but overall this whole codebase is probably of more interest as a historical oddity than as a useful application for other people to use. It uses a mish-mash of APIs, coding styles, and tests contributed by -about a dozen different maintainers over the last three years, and certainly +about a dozen different maintainers over the last three years, and certainly shows its age when compared to a shiny new legacy-free Rails 2 application. diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 04823c8..5a48f8f 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -19,7 +19,7 @@ def authenticate def authenticated? session[:member] && Member.find(session[:member].id) end - + # check to see if the currently authenticated member is # the member with the given id def member_is_this_member?(id) diff --git a/app/models/event.rb b/app/models/event.rb index 2f69432..9f384ac 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -20,60 +20,60 @@ class Event < ActiveRecord::Base validates_each :status do |rec,attr| rec.errors.add attr, 'that status is not one I know about' unless EVENT_STATUS.has_value? rec.send(attr) end - + # make sure the start time is in the future (unless it is already past) validates_each :starts_at do |rec, attr| unless rec.ends_at.nil? || rec.ends_at < Time.now rec.errors.add attr, 'must be later than now' if rec.starts_at && rec.starts_at < Time.now end end - + # make sure the end time is later than the start time (i.e. interval is positive) validates_each :ends_at do |rec, attr| rec.errors.add attr, 'must be later than start time' if rec.starts_at && rec.ends_at && rec.ends_at < rec.starts_at end - + def cancelled? self.status == EVENT_STATUS[:canceled] end - + def cancel! self.status = EVENT_STATUS[:canceled] end - + def active? self.status == EVENT_STATUS[:active] end - + def active! self.status = EVENT_STATUS[:active] end - + def has_participant(member) self.participants.map {|p| p.member }.member?(member) end - + def started? self.starts_at < Time.now end - + def ended? self.ends_at < Time.now end - + def feedbacks self.participants.map {|p| p.feedbacks }.flatten end - + def unclaimed? nil == self.member end - + def Event.find_upcoming(limit=10) - find(:all, :limit => limit, :order => 'starts_at desc', + find(:all, :limit => limit, :order => 'starts_at desc', :conditions => ['starts_at > ? and status = ?', Time.now, EVENT_STATUS[:active]]) end - + def Event.find_recent(limit=10) find(:all, :limit => limit, :order => 'ends_at desc') find(:all, :limit => limit, :order => 'ends_at desc', diff --git a/app/models/mail_bot.rb b/app/models/mail_bot.rb index 90c0fde..fe91ece 100644 --- a/app/models/mail_bot.rb +++ b/app/models/mail_bot.rb @@ -1,9 +1,9 @@ class MailBot < ActionMailer::Base SITE_FROM_ADDRESS = 'noreply@pdxruby.org' SUBJECT_PREFIX = '[pdxruby] ' - + helper ActionView::Helpers::UrlHelper - + # New user signup message def signup_message(ctrl, member) self.site_headers(member, "Account signup") @@ -21,43 +21,43 @@ def feedback_message(ctrl, event) self.site_headers(event.member, "Feedback added for event #{event.name}") @body = { :controller => ctrl, :event => event } end - + # Notify all event participants of changes to event details def change_message(ctrl, event) rcpt = event.participants.map {|p| p.member} self.site_headers(rcpt, "Event #{event.name} details changed") @body = { :controller => ctrl, :event => event } end - + # Notify all event participants of event cancellation def cancel_message(ctrl, event) rcpt = event.participants.map {|p| p.member} self.site_headers(rcpt, "Event #{event.name} has been cancelled") @body = { :controller => ctrl, :event => event } end - + # Notify event owner of RSVP for their event def rsvp_message(ctrl, participant) event = participant.event self.site_headers(event.member, "New participant signup for event #{event.name}") @body = { :controller => ctrl, :participant => participant } end - + # Notify event owner of new feedback def feedback_message(ctrl, feedback) event = feedback.participant.event self.site_headers(event.member, "New feedback for event #{event.name}") @body = { :controller => ctrl, :feedback => feedback } end - - # the deliver_new_event_message method should be called seperately for + + # the deliver_new_event_message method should be called seperately for # each site member (i.e., within a Member.find(:all) { ... } block) to # avoid exposing all member email addresses def new_event_message(ctrl, member, event) self.site_headers(member, "New event created") @body = { :controller => ctrl, :event => event, :member => member } end - + def site_headers(rcpt, subj) @recipients = rcpt.respond_to?(:map) ? rcpt.map {|m| m.email } : rcpt.email @from = SITE_FROM_ADDRESS diff --git a/app/models/member.rb b/app/models/member.rb index adf8018..3abca2e 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -1,11 +1,11 @@ class Member < ActiveRecord::Base attr_accessor :image_file - + has_many :events has_many :participants - + before_save :encrypt_password - + validates_presence_of :name validates_presence_of :email validates_presence_of :password, :on => :create @@ -18,26 +18,26 @@ class Member < ActiveRecord::Base validates_length_of :email, :maximum => 128 validates_length_of :feed_url, :maximum => 256, :allow_nil => true validates_length_of :irc_nick, :maximum => 128, :allow_nil => true - - validates_confirmation_of :password, + + validates_confirmation_of :password, :message => "should match confirmation", :on => :create - + validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i - validates_format_of :feed_url, - :with => Regexp.new(RE::URL), + validates_format_of :feed_url, + :with => Regexp.new(RE::URL), :allow_nil => true, :if => Proc.new {|member| !member.feed_url.empty?} - + # Encrypts some data with the salt. def encrypt(password) Digest::SHA1.hexdigest(password) end - + def compare_password(supplied_password) encrypted_password = encrypt(supplied_password) return (self.password == encrypt_password) end - + def reset_password srand chars = (0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a @@ -45,9 +45,9 @@ def reset_password self.password = tmp_pass return tmp_pass end - + private - + def encrypt_password self.password = encrypt(password) end diff --git a/app/views/events/_feedback.rhtml b/app/views/events/_feedback.rhtml index 2423b2b..79280ba 100644 --- a/app/views/events/_feedback.rhtml +++ b/app/views/events/_feedback.rhtml @@ -1,6 +1,6 @@
-<%= link_to feedback.participant.member.name, - :controller => 'members', +<%= link_to feedback.participant.member.name, + :controller => 'members', :action => 'show', :id => feedback.participant.member %> said, diff --git a/app/views/events/_form_ended.rhtml b/app/views/events/_form_ended.rhtml index f1fbe69..7c323d3 100644 --- a/app/views/events/_form_ended.rhtml +++ b/app/views/events/_form_ended.rhtml @@ -12,7 +12,7 @@ %>, <%= @event.location.address %>

- +

Time: <%= @event.starts_at %> - <%= @event.ends_at %>


diff --git a/app/views/events/_rsvp.rhtml b/app/views/events/_rsvp.rhtml index 4e9f1c9..64e2de8 100644 --- a/app/views/events/_rsvp.rhtml +++ b/app/views/events/_rsvp.rhtml @@ -1,7 +1,7 @@

-<%= link_to rsvp.member.name, - :controller => 'members', - :action => 'show', +<%= link_to rsvp.member.name, + :controller => 'members', + :action => 'show', :id => rsvp.member %> <% unless rsvp.comments == "" %> diff --git a/app/views/events/show.rhtml b/app/views/events/show.rhtml index 7389b72..a70e4b5 100644 --- a/app/views/events/show.rhtml +++ b/app/views/events/show.rhtml @@ -2,28 +2,28 @@ <% if @event.cancelled? %> <% end %> -

Organized by +

Organized by <% if @event.member.nil? %> - no one + no one (<%= link_to 'claim', {:id => @event.id, :action => 'claim'}, :confirm => 'Are you sure?' %>) <% else %> - <%= link_to @event.member.name, - :controller => 'members', - :action => 'show', - :id => @event.member.id + <%= link_to @event.member.name, + :controller => 'members', + :action => 'show', + :id => @event.member.id %> <% end %>

-

Time: <%= @event.starts_at.strftime('%a %b %d %Y at %I:%M%p') %> +

Time: <%= @event.starts_at.strftime('%a %b %d %Y at %I:%M%p') %> - <%= @event.ends_at.strftime('%a %b %d %Y at %I:%M%p') %>

-

Location: - <%= link_to @event.location.name, - :controller => 'locations', - :action => 'show', - :id => @event.location.id - %>, +

Location: + <%= link_to @event.location.name, + :controller => 'locations', + :action => 'show', + :id => @event.location.id + %>, <%= @event.location.address %>

@@ -38,9 +38,9 @@ <% unless (session[:member].nil?) || (@event.has_participant(session[:member])) %>

-<%= link_to 'Will you be attending?', - :controller => 'participants', - :action => 'new', +<%= link_to 'Will you be attending?', + :controller => 'participants', + :action => 'new', :event => @event unless @event.ended? %>

@@ -50,7 +50,7 @@ <%= if @participants_by_status[:yes].empty? "(none)" else - render :partial => 'rsvp', :collection => @participants_by_status[:yes] + render :partial => 'rsvp', :collection => @participants_by_status[:yes] end %>
@@ -59,7 +59,7 @@ <%= if @participants_by_status[:no].empty? "(none)" else - render :partial => 'rsvp', :collection => @participants_by_status[:no] + render :partial => 'rsvp', :collection => @participants_by_status[:no] end %> @@ -68,7 +68,7 @@ <%= if @participants_by_status[:maybe].empty? "(none)" else - render :partial => 'rsvp', :collection => @participants_by_status[:maybe] + render :partial => 'rsvp', :collection => @participants_by_status[:maybe] end %> @@ -89,7 +89,7 @@ :action => 'new', :event => @event if @event.has_participant(session[:member]) %> -<% if @event.feedbacks.size > 0 %> +<% if @event.feedbacks.size > 0 %> <%= render :partial => 'feedback', :collection => @event.feedbacks %> <% else %>

(none)

@@ -105,8 +105,8 @@ | <%= link_to 'Cancel this event', :action => 'cancel', :id => @event, :confirm => 'Are you sure?' %> <% end %> <% if @event.member == session[:member] %> -| <%= link_to 'Give up ownership', - :action => 'release', +| <%= link_to 'Give up ownership', + :action => 'release', :id => @event, :confirm => 'Are you sure?' %> <% end %> diff --git a/app/views/index/_article.rhtml b/app/views/index/_article.rhtml index 747dbfb..da040d9 100644 --- a/app/views/index/_article.rhtml +++ b/app/views/index/_article.rhtml @@ -1,6 +1,6 @@
  • <%= article.title %> -(<%= link_to 'Show', +(<%= link_to 'Show', :controller => 'articles', :action => 'show', :id => article.id %>) diff --git a/app/views/index/index.rhtml b/app/views/index/index.rhtml index de4908a..58e999d 100644 --- a/app/views/index/index.rhtml +++ b/app/views/index/index.rhtml @@ -1,20 +1,20 @@

    Who are we?

    - +

    pdx.rb is a gathering of Ruby programmers in the Portland, Oregon, area. - - + +

    Join us! We don't bite!

    - -

    We meet the first Tuesday (think Ruby Tuesday!) of every month from 7–10pm at + +

    We meet the first Tuesday (think Ruby Tuesday!) of every month from 7–10pm at CubeSpace (622 SE Grand Ave., Portland OR [map]). Our next monthly meeting is on <%= Date.today + (0..34).find{ |i| d = Date.today + i and d.cwday == 2 and d.day <= 7 } %>. - +

    This website is a small Ruby on Rails application that we have developed to keep track of events. You might start by creating an account. We have an online calendar you can subscribe to (here’s an alternative http: link if you need it). If you want to add an event, log in and add one. -

    You can join the +

    You can join the Google Group. You can also see the gmane archives of our old, now-inactive mailing list here. - +

    You can also find some of us on our IRC channel at #pdx.rb on irc.freenode.net.

    Upcoming events

    @@ -26,12 +26,12 @@ You can also see the gmane archives of our old, n
      <%= render :partial => 'event', :collection => @recent_events %>
    - +

    Recent articles

      <%= render :partial => 'article', :collection => @member_articles %>

    Thanks to...

    - +

    Robby Russell and Planet Argon for kindly serving up this site. diff --git a/app/views/mail_bot/cancel_message.rhtml b/app/views/mail_bot/cancel_message.rhtml index c29e86b..f391ef8 100644 --- a/app/views/mail_bot/cancel_message.rhtml +++ b/app/views/mail_bot/cancel_message.rhtml @@ -9,5 +9,5 @@ You can create a new event at the following location: :action => 'new', :only_path => false %> -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ \ No newline at end of file diff --git a/app/views/mail_bot/change_message.rhtml b/app/views/mail_bot/change_message.rhtml index 9975787..edfd561 100644 --- a/app/views/mail_bot/change_message.rhtml +++ b/app/views/mail_bot/change_message.rhtml @@ -4,10 +4,10 @@ You signed up to participate in <%= @event.name %>. That event's organizer, You should double-check the new details, and update your participation status if necessary: -<%= url_for :controller => 'events', - :action => 'show', - :id => @event.id, +<%= url_for :controller => 'events', + :action => 'show', + :id => @event.id, :only_path => false %> -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ \ No newline at end of file diff --git a/app/views/mail_bot/feedback_message.rhtml b/app/views/mail_bot/feedback_message.rhtml index 64845a8..e3e42df 100644 --- a/app/views/mail_bot/feedback_message.rhtml +++ b/app/views/mail_bot/feedback_message.rhtml @@ -1,17 +1,17 @@ -<% +<% member = @feedback.participant.member -event = @feedback.participant.event +event = @feedback.participant.event %><%= member.email %> has left the following feedback for your event <%= event.name %>: <%= @feedback.feedback %> -You can view other feedback for your event, as well as other details, at the +You can view other feedback for your event, as well as other details, at the following location: -<%= url_for :controller => 'events', - :action => 'show', - :id => event.id, +<%= url_for :controller => 'events', + :action => 'show', + :id => event.id, :only_path => false %> -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ \ No newline at end of file diff --git a/app/views/mail_bot/new_event_message.rhtml b/app/views/mail_bot/new_event_message.rhtml index 5043579..a863831 100644 --- a/app/views/mail_bot/new_event_message.rhtml +++ b/app/views/mail_bot/new_event_message.rhtml @@ -1,11 +1,11 @@ There's a new event being organized on pdxruby.org: -<%= url_for :controller => 'events', - :action => 'show', - :id => event.id, +<%= url_for :controller => 'events', + :action => 'show', + :id => event.id, :only_path => false %> Check it out, and sign up if you're interested. -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ \ No newline at end of file diff --git a/app/views/mail_bot/reset_password.rhtml b/app/views/mail_bot/reset_password.rhtml index cc0d54a..d835205 100644 --- a/app/views/mail_bot/reset_password.rhtml +++ b/app/views/mail_bot/reset_password.rhtml @@ -13,5 +13,5 @@ temporary security hole. Happy hacking, -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ diff --git a/app/views/mail_bot/rsvp_message.rhtml b/app/views/mail_bot/rsvp_message.rhtml index 98c1ebd..9fac193 100644 --- a/app/views/mail_bot/rsvp_message.rhtml +++ b/app/views/mail_bot/rsvp_message.rhtml @@ -1,17 +1,17 @@ -<% +<% member = @participant.member -event = @participant.event +event = @participant.event %><%= member.email %> has signed up to attend your event <%= event.name %>: <%= @participant.comments %> -You can view other participants for your event, as well as other details, at the +You can view other participants for your event, as well as other details, at the following location: -<%= url_for :controller => 'events', - :action => 'show', - :id => event.id, +<%= url_for :controller => 'events', + :action => 'show', + :id => event.id, :only_path => false %> -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ \ No newline at end of file diff --git a/app/views/mail_bot/signup_message.rhtml b/app/views/mail_bot/signup_message.rhtml index a834691..a02373a 100644 --- a/app/views/mail_bot/signup_message.rhtml +++ b/app/views/mail_bot/signup_message.rhtml @@ -11,5 +11,5 @@ You can edit your profile at the following location: Happy hacking, -The PDX.rb Crew +The PDX.rb Crew http://www.pdxruby.org/ diff --git a/app/views/members/list.rhtml b/app/views/members/list.rhtml index 76fa27c..5aa1669 100644 --- a/app/views/members/list.rhtml +++ b/app/views/members/list.rhtml @@ -6,7 +6,7 @@ Email - + <% for member in @members %> <%= member.name %> diff --git a/app/views/members/login.rhtml b/app/views/members/login.rhtml index 8aa856c..0cfaa9a 100644 --- a/app/views/members/login.rhtml +++ b/app/views/members/login.rhtml @@ -7,5 +7,5 @@

    <% end %> <% form_for :member, @member, :url => "/reset" do |f| %> - + <% end %> \ No newline at end of file diff --git a/app/views/members/show.rhtml b/app/views/members/show.rhtml index 9eb172c..368aef4 100644 --- a/app/views/members/show.rhtml +++ b/app/views/members/show.rhtml @@ -33,11 +33,11 @@ else @participations.each do |participation| %> - <%= link_to participation.event.name, :controller => "events", :action => "show", + <%= link_to participation.event.name, :controller => "events", :action => "show", :id => participation.event.id %> at <%= participation.event.starts_at %> (<%= participation.attending %>) <%= if @member.id == session[:member].id - link_to '[change]', :controller => "participants", :action => "edit", :id => participation.id + link_to '[change]', :controller => "participants", :action => "edit", :id => participation.id end %>
    diff --git a/app/views/members/update.rhtml b/app/views/members/update.rhtml index e920a9c..f74a0ea 100644 --- a/app/views/members/update.rhtml +++ b/app/views/members/update.rhtml @@ -1,4 +1,4 @@ -<% form_for :member, @member, +<% form_for :member, @member, :html => { :multipart => true } do |f| %> <% f.fieldset :legend => 'Profile' do |s| %> <%= error_messages_for 'member' %> diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 09158b8..5261cd1 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -1,6 +1,6 @@ # Be sure to restart your server when you modify this file. -# Add new inflection rules using the following format +# Add new inflection rules using the following format # (all these examples are active by default): # Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' diff --git a/config/routes.rb b/config/routes.rb index 3c8d91c..72f0360 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,13 +1,13 @@ ActionController::Routing::Routes.draw do |map| # Add your own custom routes here. # The priority is based upon order of creation: first created -> highest priority. - + map.home '/', :controller => "index", :action => "index" - + map.login '/login', :controller => "members", :action => "login" map.logout '/logout', :controller => "members", :action => "logout" map.reset '/reset', :controller => "members", :action => "reset" - + map.connect '', :controller => "index", :action => "index" # Allow downloading Web Service WSDL as a file with an extension diff --git a/db/schema.rb b/db/schema.rb index 92bdee8..0b21fff 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,4 +1,4 @@ -# This file is auto-generated from the current state of the database. Instead of editing this file, +# This file is auto-generated from the current state of the database. Instead of editing this file, # please use the migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. # diff --git a/doc/IDEAS b/doc/IDEAS index 08c098c..441814f 100644 --- a/doc/IDEAS +++ b/doc/IDEAS @@ -13,7 +13,7 @@ _Community Stuff_ - del.icio.us/simpy aggregator. Let members share their del username and fetch certain tags - + - provide an rss feed of our aggregated/combined feed data - provide an rss feed of events, and maybe an rss feed for @@ -29,7 +29,7 @@ _Community Stuff_ - It would be nice if the feeds could be moderated by people. If one person posts a bunch of off-topic entries, then the last 5 isn't very - Ruby-based. Currently, a user can delete his or her own articles, + Ruby-based. Currently, a user can delete his or her own articles, which is probably good-enough for a little while. - Perhaps a field should be added to the articles relation that contains the number of 'nay' votes. When some threshold diff --git a/doc/POSTGRESQL b/doc/POSTGRESQL index cac81e5..57e3808 100644 --- a/doc/POSTGRESQL +++ b/doc/POSTGRESQL @@ -58,15 +58,15 @@ Then your database.yml would be roughly: host: /tmp/pdxruby_socket user: yourusername password: itdoesntmatter - + development: database: pdxruby_dev <<: *login - + test: database: pdxruby_test <<: *login - + production: database: pdxruby_production <<: *login diff --git a/doc/TODO b/doc/TODO index 6bebead..ef74274 100644 --- a/doc/TODO +++ b/doc/TODO @@ -2,13 +2,13 @@ Notes: -1) If you complete one of these, please remove it from the list. +1) If you complete one of these, please remove it from the list. -2) If you want to "claim" a task (i.e. you plan on doing it shortly), +2) If you want to "claim" a task (i.e. you plan on doing it shortly), put your name in [square brackets] at the end of the event. _Spamming_ - + - All members are notified of new events - Event organizer isn't notified when they sign up for the event @@ -33,11 +33,11 @@ _Cosmetic_ - Upcoming events should be ordered ASC (i.e. more soon things on top) - - Make timestamps prettier (this and following 2 items + - Make timestamps prettier (this and following 2 items suggested by bleything on dev-list) - Article list enhancements (sort by author, etc.) _Testing_ - + - write functional tests for application.rb diff --git a/lib/authenticated_test_helper.rb b/lib/authenticated_test_helper.rb index 446af91..ad3e4db 100644 --- a/lib/authenticated_test_helper.rb +++ b/lib/authenticated_test_helper.rb @@ -17,7 +17,7 @@ def assert_requires_login(member = nil, &block) end # Assert the block accepts the login - # + # # assert_accepts_login(:bob) { get :edit, :id => 1 } # # Accepts anonymous logins: diff --git a/lib/tasks/agiledox.rake b/lib/tasks/agiledox.rake index 2298d80..07e61d0 100644 --- a/lib/tasks/agiledox.rake +++ b/lib/tasks/agiledox.rake @@ -3,12 +3,12 @@ task :agiledox do tests = FileList['test/**/*_test.rb'] tests.each do |file| m = %r".*/([^/].*)_test.rb".match(file) - puts m[1]+" should:\n" + puts m[1]+" should:\n" test_definitions = File::readlines(file).select {|line| line =~ /.*def test.*/} test_definitions.each do |definition| m = %r"test_(should_)?(.*)".match(definition) puts " - "+m[2].gsub(/_/," ") end - puts "\n" + puts "\n" end end \ No newline at end of file diff --git a/public/.htaccess b/public/.htaccess index d9d211c..1d37bd9 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -5,14 +5,14 @@ Options +FollowSymLinks +ExecCGI # If you don't want Rails to look in certain directories, # use the following rewrite rules so that Apache won't rewrite certain requests -# +# # Example: # RewriteCond %{REQUEST_URI} ^/notrails.* # RewriteRule .* - [L] # Redirect all requests not available on the filesystem to Rails # By default the cgi dispatcher is used which is very slow -# +# # For better performance replace the dispatcher with the fastcgi one # # Example: @@ -33,7 +33,7 @@ RewriteRule ^(.*)$ dispatch.cgi [QSA,L] # In case Rails experiences terminal errors # Instead of displaying this message you can supply a file here which will be rendered instead -# +# # Example: # ErrorDocument 500 /500.html diff --git a/public/javascripts/controls.js b/public/javascripts/controls.js index fbc4418..88f74a9 100644 --- a/public/javascripts/controls.js +++ b/public/javascripts/controls.js @@ -5,18 +5,18 @@ // Richard Livsey // Rahul Bhargava // Rob Wills -// +// // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ -// Autocompleter.Base handles all the autocompletion functionality +// Autocompleter.Base handles all the autocompletion functionality // that's independent of the data source for autocompletion. This // includes drawing the autocompletion menu, observing keyboard // and mouse events, and similar. // -// Specific autocompleters need to provide, at the very least, +// Specific autocompleters need to provide, at the very least, // a getUpdatedChoices function that will be invoked every time -// the text inside the monitored textbox changes. This method +// the text inside the monitored textbox changes. This method // should get the text for which to provide autocompletion by // invoking this.getToken(), NOT by directly accessing // this.element.value. This is to allow incremental tokenized @@ -30,8 +30,8 @@ // will incrementally autocomplete with a comma as the token. // Additionally, ',' in the above example can be replaced with // a token array, e.g. { tokens: [',', '\n'] } which -// enables autocompletion on multiple tokens. This is most -// useful when one of the tokens is \n (a newline), as it +// enables autocompletion on multiple tokens. This is most +// useful when one of the tokens is \n (a newline), as it // allows smart autocompletion after linebreaks. if(typeof Effect == 'undefined') @@ -41,12 +41,12 @@ var Autocompleter = { } Autocompleter.Base = Class.create({ baseInitialize: function(element, update, options) { element = $(element) - this.element = element; - this.update = $(update); - this.hasFocus = false; - this.changed = false; - this.active = false; - this.index = 0; + this.element = element; + this.update = $(update); + this.hasFocus = false; + this.changed = false; + this.active = false; + this.index = 0; this.entryCount = 0; this.oldElementValue = this.element.value; @@ -59,28 +59,28 @@ Autocompleter.Base = Class.create({ this.options.tokens = this.options.tokens || []; this.options.frequency = this.options.frequency || 0.4; this.options.minChars = this.options.minChars || 1; - this.options.onShow = this.options.onShow || - function(element, update){ + this.options.onShow = this.options.onShow || + function(element, update){ if(!update.style.position || update.style.position=='absolute') { update.style.position = 'absolute'; Position.clone(element, update, { - setHeight: false, + setHeight: false, offsetTop: element.offsetHeight }); } Effect.Appear(update,{duration:0.15}); }; - this.options.onHide = this.options.onHide || + this.options.onHide = this.options.onHide || function(element, update){ new Effect.Fade(update,{duration:0.15}) }; - if(typeof(this.options.tokens) == 'string') + if(typeof(this.options.tokens) == 'string') this.options.tokens = new Array(this.options.tokens); // Force carriage returns as token delimiters anyway if (!this.options.tokens.include('\n')) this.options.tokens.push('\n'); this.observer = null; - + this.element.setAttribute('autocomplete','off'); Element.hide(this.update); @@ -91,10 +91,10 @@ Autocompleter.Base = Class.create({ show: function() { if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); - if(!this.iefix && + if(!this.iefix && (Prototype.Browser.IE) && (Element.getStyle(this.update, 'position')=='absolute')) { - new Insertion.After(this.update, + new Insertion.After(this.update, ''); @@ -102,7 +102,7 @@ Autocompleter.Base = Class.create({ } if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); }, - + fixIEOverlapping: function() { Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); this.iefix.style.zIndex = 1; @@ -150,15 +150,15 @@ Autocompleter.Base = Class.create({ Event.stop(event); return; } - else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; this.changed = true; this.hasFocus = true; if(this.observer) clearTimeout(this.observer); - this.observer = + this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); }, @@ -170,35 +170,35 @@ Autocompleter.Base = Class.create({ onHover: function(event) { var element = Event.findElement(event, 'LI'); - if(this.index != element.autocompleteIndex) + if(this.index != element.autocompleteIndex) { this.index = element.autocompleteIndex; this.render(); } Event.stop(event); }, - + onClick: function(event) { var element = Event.findElement(event, 'LI'); this.index = element.autocompleteIndex; this.selectEntry(); this.hide(); }, - + onBlur: function(event) { // needed to make click events working setTimeout(this.hide.bind(this), 250); this.hasFocus = false; - this.active = false; - }, - + this.active = false; + }, + render: function() { if(this.entryCount > 0) { for (var i = 0; i < this.entryCount; i++) - this.index==i ? - Element.addClassName(this.getEntry(i),"selected") : + this.index==i ? + Element.addClassName(this.getEntry(i),"selected") : Element.removeClassName(this.getEntry(i),"selected"); - if(this.hasFocus) { + if(this.hasFocus) { this.show(); this.active = true; } @@ -207,27 +207,27 @@ Autocompleter.Base = Class.create({ this.hide(); } }, - + markPrevious: function() { if(this.index > 0) this.index-- else this.index = this.entryCount-1; this.getEntry(this.index).scrollIntoView(true); }, - + markNext: function() { if(this.index < this.entryCount-1) this.index++ else this.index = 0; this.getEntry(this.index).scrollIntoView(false); }, - + getEntry: function(index) { return this.update.firstChild.childNodes[index]; }, - + getCurrentEntry: function() { return this.getEntry(this.index); }, - + selectEntry: function() { this.active = false; this.updateElement(this.getCurrentEntry()); @@ -244,7 +244,7 @@ Autocompleter.Base = Class.create({ if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); } else value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); - + var bounds = this.getTokenBounds(); if (bounds[0] != -1) { var newValue = this.element.value.substr(0, bounds[0]); @@ -257,7 +257,7 @@ Autocompleter.Base = Class.create({ } this.oldElementValue = this.element.value; this.element.focus(); - + if (this.options.afterUpdateElement) this.options.afterUpdateElement(this.element, selectedElement); }, @@ -269,20 +269,20 @@ Autocompleter.Base = Class.create({ Element.cleanWhitespace(this.update.down()); if(this.update.firstChild && this.update.down().childNodes) { - this.entryCount = + this.entryCount = this.update.down().childNodes.length; for (var i = 0; i < this.entryCount; i++) { var entry = this.getEntry(i); entry.autocompleteIndex = i; this.addObservers(entry); } - } else { + } else { this.entryCount = 0; } this.stopIndicator(); this.index = 0; - + if(this.entryCount==1 && this.options.autoSelect) { this.selectEntry(); this.hide(); @@ -298,7 +298,7 @@ Autocompleter.Base = Class.create({ }, onObserverEvent: function() { - this.changed = false; + this.changed = false; this.tokenBounds = null; if(this.getToken().length>=this.options.minChars) { this.getUpdatedChoices(); @@ -351,16 +351,16 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, { getUpdatedChoices: function() { this.startIndicator(); - - var entry = encodeURIComponent(this.options.paramName) + '=' + + + var entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken()); this.options.parameters = this.options.callback ? this.options.callback(this.element, entry) : entry; - if(this.options.defaultParams) + if(this.options.defaultParams) this.options.parameters += '&' + this.options.defaultParams; - + new Ajax.Request(this.url, this.options); }, @@ -382,7 +382,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, { // - choices - How many autocompletion choices to offer // // - partialSearch - If false, the autocompleter will match entered -// text only at the beginning of strings in the +// text only at the beginning of strings in the // autocomplete array. Defaults to true, which will // match text at the beginning of any *word* in the // strings in the autocomplete array. If you want to @@ -399,7 +399,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, { // - ignoreCase - Whether to ignore case when autocompleting. // Defaults to true. // -// It's possible to pass in a custom function as the 'selector' +// It's possible to pass in a custom function as the 'selector' // option, if you prefer to write your own autocompletion logic. // In that case, the other options above will not apply unless // you support them. @@ -427,20 +427,20 @@ Autocompleter.Local = Class.create(Autocompleter.Base, { var entry = instance.getToken(); var count = 0; - for (var i = 0; i < instance.options.array.length && - ret.length < instance.options.choices ; i++) { + for (var i = 0; i < instance.options.array.length && + ret.length < instance.options.choices ; i++) { var elem = instance.options.array[i]; - var foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase()) : + var foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase()) : elem.indexOf(entry); while (foundPos != -1) { - if (foundPos == 0 && elem.length != entry.length) { - ret.push("
  • " + elem.substr(0, entry.length) + "" + + if (foundPos == 0 && elem.length != entry.length) { + ret.push("
  • " + elem.substr(0, entry.length) + "" + elem.substr(entry.length) + "
  • "); break; - } else if (entry.length >= instance.options.partialChars && + } else if (entry.length >= instance.options.partialChars && instance.options.partialSearch && foundPos != -1) { if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { partial.push("
  • " + elem.substr(0, foundPos) + "" + @@ -450,8 +450,8 @@ Autocompleter.Local = Class.create(Autocompleter.Base, { } } - foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : + foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : elem.indexOf(entry, foundPos + 1); } @@ -937,7 +937,7 @@ Ajax.InPlaceCollectionEditor.DefaultOptions = { loadingCollectionText: 'Loading options...' }; -// Delayed observer, like Form.Element.Observer, +// Delayed observer, like Form.Element.Observer, // but waits for delay after last key input // Ideal for live-search fields @@ -947,7 +947,7 @@ Form.Element.DelayedObserver = Class.create({ this.element = $(element); this.callback = callback; this.timer = null; - this.lastValue = $F(this.element); + this.lastValue = $F(this.element); Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); }, delayedListener: function(event) { diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js index ccf4a1e..c356ddf 100644 --- a/public/javascripts/dragdrop.js +++ b/public/javascripts/dragdrop.js @@ -1,6 +1,6 @@ // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) -// +// // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ @@ -32,7 +32,7 @@ var Droppables = { options._containers.push($(containment)); } } - + if(options.accept) options.accept = [options.accept].flatten(); Element.makePositioned(element); // fix IE @@ -40,34 +40,34 @@ var Droppables = { this.drops.push(options); }, - + findDeepestChild: function(drops) { deepest = drops[0]; - + for (i = 1; i < drops.length; ++i) if (Element.isParent(drops[i].element, deepest.element)) deepest = drops[i]; - + return deepest; }, isContained: function(element, drop) { var containmentNode; if(drop.tree) { - containmentNode = element.treeNode; + containmentNode = element.treeNode; } else { containmentNode = element.parentNode; } return drop._containers.detect(function(c) { return containmentNode == c }); }, - + isAffected: function(point, element, drop) { return ( (drop.element!=element) && ((!drop._containers) || this.isContained(element, drop)) && ((!drop.accept) || - (Element.classNames(element).detect( + (Element.classNames(element).detect( function(v) { return drop.accept.include(v) } ) )) && Position.within(drop.element, point[0], point[1]) ); }, @@ -87,12 +87,12 @@ var Droppables = { show: function(point, element) { if(!this.drops.length) return; var drop, affected = []; - + this.drops.each( function(drop) { if(Droppables.isAffected(point, element, drop)) affected.push(drop); }); - + if(affected.length>0) drop = Droppables.findDeepestChild(affected); @@ -101,7 +101,7 @@ var Droppables = { Position.within(drop.element, point[0], point[1]); if(drop.onHover) drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); - + if (drop != this.last_active) Droppables.activate(drop); } }, @@ -112,8 +112,8 @@ var Droppables = { if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) if (this.last_active.onDrop) { - this.last_active.onDrop(element, this.last_active.element, event); - return true; + this.last_active.onDrop(element, this.last_active.element, event); + return true; } }, @@ -126,20 +126,20 @@ var Droppables = { 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) { @@ -148,24 +148,24 @@ var Draggables = { Event.stopObserving(document, "keypress", this.eventKeypress); } }, - + activate: function(draggable) { - if(draggable.options.delay) { - this._timeout = setTimeout(function() { - Draggables._timeout = null; - window.focus(); - Draggables.activeDraggable = draggable; - }.bind(this), draggable.options.delay); + if(draggable.options.delay) { + this._timeout = setTimeout(function() { + Draggables._timeout = null; + window.focus(); + Draggables.activeDraggable = draggable; + }.bind(this), draggable.options.delay); } else { window.focus(); // allows keypress events if window isn't currently focused, fails for Safari this.activeDraggable = draggable; } }, - + deactivate: function() { this.activeDraggable = null; }, - + updateDrag: function(event) { if(!this.activeDraggable) return; var pointer = [Event.pointerX(event), Event.pointerY(event)]; @@ -173,36 +173,36 @@ var Draggables = { // the same coordinates, prevent needless redrawing (moz bug?) if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; this._lastPointer = pointer; - + this.activeDraggable.updateDrag(event, pointer); }, - + endDrag: function(event) { - if(this._timeout) { - clearTimeout(this._timeout); - this._timeout = null; + if(this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; } if(!this.activeDraggable) return; this._lastPointer = null; this.activeDraggable.endDrag(event); this.activeDraggable = null; }, - + keyPress: function(event) { if(this.activeDraggable) this.activeDraggable.keyPress(event); }, - + addObserver: function(observer) { this.observers.push(observer); this._cacheObserverCallbacks(); }, - + removeObserver: function(element) { // element instead of observer fixes mem leaks this.observers = this.observers.reject( function(o) { return o.element==element }); this._cacheObserverCallbacks(); }, - + notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' if(this[eventName+'Count'] > 0) this.observers.each( function(o) { @@ -210,7 +210,7 @@ var Draggables = { }); if(draggable.options[eventName]) draggable.options[eventName](draggable, event); }, - + _cacheObserverCallbacks: function() { ['onStart','onEnd','onDrag'].each( function(eventName) { Draggables[eventName+'Count'] = Draggables.observers.select( @@ -234,12 +234,12 @@ var Draggable = Class.create({ }, endeffect: function(element) { var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; - new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, + new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, queue: {scope:'_draggable', position:'end'}, - afterFinish: function(){ - Draggable._dragging[element] = false + afterFinish: function(){ + Draggable._dragging[element] = false } - }); + }); }, zindex: 1000, revert: false, @@ -250,57 +250,57 @@ var Draggable = Class.create({ snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } delay: 0 }; - + if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) Object.extend(defaults, { starteffect: function(element) { element._opacity = Element.getOpacity(element); Draggable._dragging[element] = true; - new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); + new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); } }); - + var options = Object.extend(defaults, arguments[1] || { }); this.element = $(element); - + if(options.handle && Object.isString(options.handle)) this.handle = this.element.down('.'+options.handle, 0); - + if(!this.handle) this.handle = $(options.handle); if(!this.handle) this.handle = this.element; - + if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { options.scroll = $(options.scroll); this._isScrollChild = Element.childOf(this.element, options.scroll); } - Element.makePositioned(this.element); // fix IE + Element.makePositioned(this.element); // fix IE this.options = options; - this.dragging = false; + this.dragging = false; this.eventMouseDown = this.initDrag.bindAsEventListener(this); Event.observe(this.handle, "mousedown", this.eventMouseDown); - + Draggables.register(this); }, - + destroy: function() { Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); Draggables.unregister(this); }, - + currentDelta: function() { return([ parseInt(Element.getStyle(this.element,'left') || '0'), parseInt(Element.getStyle(this.element,'top') || '0')]); }, - + initDrag: function(event) { if(!Object.isUndefined(Draggable._dragging[this.element]) && Draggable._dragging[this.element]) return; - if(Event.isLeftClick(event)) { + if(Event.isLeftClick(event)) { // abort on form elements, fixes a Firefox issue var src = Event.element(event); if((tag_name = src.tagName.toUpperCase()) && ( @@ -309,26 +309,26 @@ var Draggable = Class.create({ tag_name=='OPTION' || tag_name=='BUTTON' || tag_name=='TEXTAREA')) return; - + var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pos = Position.cumulativeOffset(this.element); this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); - + Draggables.activate(this); Event.stop(event); } }, - + startDrag: function(event) { this.dragging = true; if(!this.delta) this.delta = this.currentDelta(); - + if(this.options.zindex) { this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); this.element.style.zIndex = this.options.zindex; } - + if(this.options.ghosting) { this._clone = this.element.cloneNode(true); this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); @@ -336,7 +336,7 @@ var Draggable = Class.create({ Position.absolutize(this.element); this.element.parentNode.insertBefore(this._clone, this.element); } - + if(this.options.scroll) { if (this.options.scroll == window) { var where = this._getWindowScroll(this.options.scroll); @@ -347,28 +347,28 @@ var Draggable = Class.create({ this.originalScrollTop = this.options.scroll.scrollTop; } } - + Draggables.notify('onStart', this, event); - + if(this.options.starteffect) this.options.starteffect(this.element); }, - + updateDrag: function(event, pointer) { if(!this.dragging) this.startDrag(event); - + if(!this.options.quiet){ Position.prepare(); Droppables.show(pointer, this.element); } - + Draggables.notify('onDrag', this, event); - + this.draw(pointer); if(this.options.change) this.options.change(this); - + if(this.options.scroll) { this.stopScrolling(); - + var p; if (this.options.scroll == window) { with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } @@ -386,16 +386,16 @@ var Draggable = Class.create({ if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); this.startScrolling(speed); } - + // fix AppleWebKit rendering if(Prototype.Browser.WebKit) window.scrollBy(0,0); - + Event.stop(event); }, - + finishDrag: function(event, success) { this.dragging = false; - + if(this.options.quiet){ Position.prepare(); var pointer = [Event.pointerX(event), Event.pointerY(event)]; @@ -410,17 +410,17 @@ var Draggable = Class.create({ this._clone = null; } - var dropped = false; - if(success) { - dropped = Droppables.fire(event, this.element); - if (!dropped) dropped = false; + var dropped = false; + if(success) { + dropped = Droppables.fire(event, this.element); + if (!dropped) dropped = false; } if(dropped && this.options.onDropped) this.options.onDropped(this.element); Draggables.notify('onEnd', this, event); var revert = this.options.revert; if(revert && Object.isFunction(revert)) revert = revert(this.element); - + var d = this.currentDelta(); if(revert && this.options.reverteffect) { if (dropped == 0 || revert != 'failure') @@ -433,45 +433,45 @@ var Draggable = Class.create({ if(this.options.zindex) this.element.style.zIndex = this.originalZ; - if(this.options.endeffect) + if(this.options.endeffect) this.options.endeffect(this.element); - + Draggables.deactivate(this); Droppables.reset(); }, - + keyPress: function(event) { if(event.keyCode!=Event.KEY_ESC) return; this.finishDrag(event, false); Event.stop(event); }, - + endDrag: function(event) { if(!this.dragging) return; this.stopScrolling(); this.finishDrag(event, true); Event.stop(event); }, - + draw: function(point) { var pos = Position.cumulativeOffset(this.element); if(this.options.ghosting) { var r = Position.realOffset(this.element); pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; } - + var d = this.currentDelta(); pos[0] -= d[0]; pos[1] -= d[1]; - + if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; } - - var p = [0,1].map(function(i){ - return (point[i]-pos[i]-this.offset[i]) + + var p = [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) }.bind(this)); - + if(this.options.snap) { if(Object.isFunction(this.options.snap)) { p = this.options.snap(p[0],p[1],this); @@ -484,16 +484,16 @@ var Draggable = Class.create({ return (v/this.options.snap).round()*this.options.snap }.bind(this)) } }} - + var style = this.element.style; if((!this.options.constraint) || (this.options.constraint=='horizontal')) style.left = p[0] + "px"; if((!this.options.constraint) || (this.options.constraint=='vertical')) style.top = p[1] + "px"; - + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering }, - + stopScrolling: function() { if(this.scrollInterval) { clearInterval(this.scrollInterval); @@ -501,14 +501,14 @@ var Draggable = Class.create({ Draggables._lastScrollPointer = null; } }, - + startScrolling: function(speed) { if(!(speed[0] || speed[1])) return; this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; this.lastScrolled = new Date(); this.scrollInterval = setInterval(this.scroll.bind(this), 10); }, - + scroll: function() { var current = new Date(); var delta = current - this.lastScrolled; @@ -524,7 +524,7 @@ var Draggable = Class.create({ this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; } - + Position.prepare(); Droppables.show(Draggables._lastPointer, this.element); Draggables.notify('onDrag', this); @@ -538,10 +538,10 @@ var Draggable = Class.create({ Draggables._lastScrollPointer[1] = 0; this.draw(Draggables._lastScrollPointer); } - + if(this.options.change) this.options.change(this); }, - + _getWindowScroll: function(w) { var T, L, W, H; with (w.document) { @@ -577,11 +577,11 @@ var SortableObserver = Class.create({ 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)) @@ -591,11 +591,11 @@ var SortableObserver = Class.create({ var Sortable = { SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, - + sortables: { }, - + _findRootElement: function(element) { - while (element.tagName.toUpperCase() != "BODY") { + while (element.tagName.toUpperCase() != "BODY") { if(element.id && Sortable.sortables[element.id]) return element; element = element.parentNode; } @@ -606,22 +606,22 @@ var Sortable = { if(!element) return; return Sortable.sortables[element.id]; }, - + destroy: function(element){ var s = Sortable.options(element); - + if(s) { Draggables.removeObserver(s.element); s.droppables.each(function(d){ Droppables.remove(d) }); s.draggables.invoke('destroy'); - + delete Sortable.sortables[s.element.id]; } }, create: function(element) { element = $(element); - var options = Object.extend({ + var options = Object.extend({ element: element, tag: 'li', // assumes li children, override with tag: 'tagname' dropOnEmpty: false, @@ -635,17 +635,17 @@ var Sortable = { delay: 0, hoverclass: null, ghosting: false, - quiet: false, + quiet: false, scroll: false, scrollSensitivity: 20, scrollSpeed: 15, format: this.SERIALIZE_RULE, - - // these take arrays of elements or ids and can be + + // these take arrays of elements or ids and can be // used for better initialization performance elements: false, handles: false, - + onChange: Prototype.emptyFunction, onUpdate: Prototype.emptyFunction }, arguments[1] || { }); @@ -682,7 +682,7 @@ var Sortable = { if(options.zindex) options_for_draggable.zindex = options.zindex; - // build options for the droppables + // build options for the droppables var options_for_droppable = { overlap: options.overlap, containment: options.containment, @@ -690,7 +690,7 @@ var Sortable = { hoverclass: options.hoverclass, onHover: Sortable.onHover } - + var options_for_tree = { onHover: Sortable.onEmptyHover, overlap: options.overlap, @@ -699,7 +699,7 @@ var Sortable = { } // fix for gecko engine - Element.cleanWhitespace(element); + Element.cleanWhitespace(element); options.draggables = []; options.droppables = []; @@ -712,14 +712,14 @@ var Sortable = { (options.elements || this.findElements(element, options) || []).each( function(e,i) { var handle = options.handles ? $(options.handles[i]) : - (options.handle ? $(e).select('.' + options.handle)[0] : e); + (options.handle ? $(e).select('.' + options.handle)[0] : e); options.draggables.push( new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); Droppables.add(e, options_for_droppable); if(options.tree) e.treeNode = element; - options.droppables.push(e); + options.droppables.push(e); }); - + if(options.tree) { (Sortable.findTreeElements(element, options) || []).each( function(e) { Droppables.add(e, options_for_tree); @@ -741,7 +741,7 @@ var Sortable = { return Element.findChildren( element, options.only, options.tree ? true : false, options.tag); }, - + findTreeElements: function(element, options) { return Element.findChildren( element, options.only, options.tree ? true : false, options.treeTag); @@ -758,7 +758,7 @@ var Sortable = { var oldParentNode = element.parentNode; element.style.visibility = "hidden"; // fix gecko rendering dropon.parentNode.insertBefore(element, dropon); - if(dropon.parentNode!=oldParentNode) + if(dropon.parentNode!=oldParentNode) Sortable.options(oldParentNode).onChange(element); Sortable.options(dropon.parentNode).onChange(element); } @@ -769,26 +769,26 @@ var Sortable = { var oldParentNode = element.parentNode; element.style.visibility = "hidden"; // fix gecko rendering dropon.parentNode.insertBefore(element, nextElement); - if(dropon.parentNode!=oldParentNode) + if(dropon.parentNode!=oldParentNode) Sortable.options(oldParentNode).onChange(element); Sortable.options(dropon.parentNode).onChange(element); } } }, - + onEmptyHover: function(element, dropon, overlap) { var oldParentNode = element.parentNode; var droponOptions = Sortable.options(dropon); - + if(!Element.isParent(dropon, element)) { var index; - + var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); var child = null; - + if(children) { var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); - + for (index = 0; index < children.length; index += 1) { if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { offset -= Element.offsetSize (children[index], droponOptions.overlap); @@ -801,9 +801,9 @@ var Sortable = { } } } - + dropon.insertBefore(element, child); - + Sortable.options(oldParentNode).onChange(element); droponOptions.onChange(element); } @@ -816,34 +816,34 @@ var Sortable = { mark: function(dropon, position) { // mark on ghosting only var sortable = Sortable.options(dropon.parentNode); - if(sortable && !sortable.ghosting) return; + if(sortable && !sortable.ghosting) return; if(!Sortable._marker) { - Sortable._marker = + Sortable._marker = ($('dropmarker') || Element.extend(document.createElement('DIV'))). hide().addClassName('dropmarker').setStyle({position:'absolute'}); document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); - } + } var offsets = Position.cumulativeOffset(dropon); Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); - + if(position=='after') - if(sortable.overlap == 'horizontal') + if(sortable.overlap == 'horizontal') Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); else Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); - + Sortable._marker.show(); }, - + _tree: function(element, options, parent) { var children = Sortable.findElements(element, options) || []; - + for (var i = 0; i < children.length; ++i) { var match = children[i].id.match(options.format); if (!match) continue; - + var child = { id: encodeURIComponent(match ? match[1] : null), element: element, @@ -852,15 +852,15 @@ var Sortable = { position: parent.children.length, container: $(children[i]).down(options.treeTag) } - + /* Get the element containing the children and recurse over it */ if (child.container) this._tree(child.container, options, child) - + parent.children.push (child); } - return parent; + return parent; }, tree: function(element) { @@ -873,7 +873,7 @@ var Sortable = { name: element.id, format: sortableOptions.format }, arguments[1] || { }); - + var root = { id: null, parent: null, @@ -881,7 +881,7 @@ var Sortable = { container: element, position: 0 } - + return Sortable._tree(element, options, root); }, @@ -897,7 +897,7 @@ var Sortable = { sequence: function(element) { element = $(element); var options = Object.extend(this.options(element), arguments[1] || { }); - + return $(this.findElements(element, options) || []).map( function(item) { return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; }); @@ -906,14 +906,14 @@ var Sortable = { setSequence: function(element, new_sequence) { element = $(element); var options = Object.extend(this.options(element), arguments[2] || { }); - + var nodeMap = { }; this.findElements(element, options).each( function(n) { if (n.id.match(options.format)) nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; n.parentNode.removeChild(n); }); - + new_sequence.each(function(ident) { var n = nodeMap[ident]; if (n) { @@ -922,16 +922,16 @@ var Sortable = { } }); }, - + serialize: function(element) { element = $(element); var options = Object.extend(Sortable.options(element), arguments[1] || { }); var name = encodeURIComponent( (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); - + if (options.tree) { return Sortable.tree(element, arguments[1]).children.map( function (item) { - return [name + Sortable._constructIndex(item) + "[id]=" + + return [name + Sortable._constructIndex(item) + "[id]=" + encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); }).flatten().join('&'); } else { @@ -949,7 +949,7 @@ Element.isParent = function(child, element) { return Element.isParent(child.parentNode, element); } -Element.findChildren = function(element, only, recursive, tagName) { +Element.findChildren = function(element, only, recursive, tagName) { if(!element.hasChildNodes()) return null; tagName = tagName.toUpperCase(); if(only) only = [only].flatten(); diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js index 65aed23..4650a34 100644 --- a/public/javascripts/effects.js +++ b/public/javascripts/effects.js @@ -3,46 +3,46 @@ // Justin Palmer (http://encytemedia.com/) // Mark Pilgrim (http://diveintomark.org/) // Martin Bialasinki -// +// // script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ +// For details, see the script.aculo.us web site: http://script.aculo.us/ -// converts rgb() and #xxx to #xxxxxx format, -// returns self (or first argument) if not convertable -String.prototype.parseColor = function() { +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor = function() { var color = '#'; - if (this.slice(0,4) == 'rgb(') { - var cols = this.slice(4,this.length-1).split(','); - var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); - } else { - if (this.slice(0,1) == '#') { - if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); - if (this.length==7) color = this.toLowerCase(); - } - } - return (color.length==7 ? color : (arguments[0] || this)); + if (this.slice(0,4) == 'rgb(') { + var cols = this.slice(4,this.length-1).split(','); + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); + } else { + if (this.slice(0,1) == '#') { + if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); + if (this.length==7) color = this.toLowerCase(); + } + } + return (color.length==7 ? color : (arguments[0] || this)); }; /*--------------------------------------------------------------------------*/ -Element.collectTextNodes = function(element) { +Element.collectTextNodes = function(element) { return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : + return (node.nodeType==3 ? node.nodeValue : (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); }).flatten().join(''); }; -Element.collectTextNodesIgnoreClass = function(element, className) { +Element.collectTextNodesIgnoreClass = function(element, className) { return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + return (node.nodeType==3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? Element.collectTextNodesIgnoreClass(node, className) : '')); }).flatten().join(''); }; Element.setContentZoom = function(element, percent) { - element = $(element); - element.setStyle({fontSize: (percent/100) + 'em'}); + element = $(element); + element.setStyle({fontSize: (percent/100) + 'em'}); if (Prototype.Browser.WebKit) window.scrollBy(0,0); return element; }; @@ -82,16 +82,16 @@ var Effect = { wobble: function(pos) { return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; }, - pulse: function(pos, pulses) { - pulses = pulses || 5; + pulse: function(pos, pulses) { + pulses = pulses || 5; return ( - ((pos % (1/pulses)) * pulses).round() == 0 ? - ((pos * pulses * 2) - (pos * pulses * 2).floor()) : + ((pos % (1/pulses)) * pulses).round() == 0 ? + ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor()) ); }, - spring: function(pos) { - return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); + spring: function(pos) { + return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); }, none: function(pos) { return 0; @@ -112,14 +112,14 @@ var Effect = { tagifyText: function(element) { var tagifyStyle = 'position:relative'; if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; - + element = $(element); $A(element.childNodes).each( function(child) { if (child.nodeType==3) { child.nodeValue.toArray().each( function(character) { element.insertBefore( new Element('span', {style: tagifyStyle}).update( - character == ' ' ? String.fromCharCode(160) : character), + character == ' ' ? String.fromCharCode(160) : character), child); }); Element.remove(child); @@ -128,13 +128,13 @@ var Effect = { }, multiple: function(element, effect) { var elements; - if (((typeof element == 'object') || - Object.isFunction(element)) && + if (((typeof element == 'object') || + Object.isFunction(element)) && (element.length)) elements = element; else elements = $(element).childNodes; - + var options = Object.extend({ speed: 0.1, delay: 0.0 @@ -156,7 +156,7 @@ var Effect = { var options = Object.extend({ queue: { position:'end', scope:(element.id || 'global'), limit: 1 } }, arguments[2] || { }); - Effect[element.visible() ? + Effect[element.visible() ? Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); } }; @@ -168,20 +168,20 @@ Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; Effect.ScopedQueue = Class.create(Enumerable, { initialize: function() { this.effects = []; - this.interval = null; + this.interval = null; }, _each: function(iterator) { this.effects._each(iterator); }, add: function(effect) { var timestamp = new Date().getTime(); - - var position = Object.isString(effect.options.queue) ? + + var position = Object.isString(effect.options.queue) ? effect.options.queue : effect.options.queue.position; - + switch(position) { case 'front': - // move unstarted effects after this effect + // move unstarted effects after this effect this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { e.startOn += effect.finishOn; e.finishOn += effect.finishOn; @@ -195,13 +195,13 @@ Effect.ScopedQueue = Class.create(Enumerable, { timestamp = this.effects.pluck('finishOn').max() || timestamp; break; } - + effect.startOn += timestamp; effect.finishOn += timestamp; if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) this.effects.push(effect); - + if (!this.interval) this.interval = setInterval(this.loop.bind(this), 15); }, @@ -214,7 +214,7 @@ Effect.ScopedQueue = Class.create(Enumerable, { }, loop: function() { var timePos = new Date().getTime(); - for(var i=0, len=this.effects.length;i0) { @@ -430,9 +430,9 @@ Effect.Scale = Class.create(Effect.Base, { 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]; @@ -509,7 +509,7 @@ Effect.ScrollTo = function(element) { var options = arguments[1] || { }, scrollOffsets = document.viewport.getScrollOffsets(), elementOffsets = $(element).cumulativeOffset(), - max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); + max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); if (options.offset) elementOffsets[1] += options.offset; @@ -529,9 +529,9 @@ Effect.Fade = function(element) { var options = Object.extend({ from: element.getOpacity() || 1.0, to: 0.0, - afterFinishInternal: function(effect) { + afterFinishInternal: function(effect) { if (effect.options.to!=0) return; - effect.element.hide().setStyle({opacity: oldOpacity}); + effect.element.hide().setStyle({opacity: oldOpacity}); } }, arguments[1] || { }); return new Effect.Opacity(element,options); @@ -547,15 +547,15 @@ Effect.Appear = function(element) { effect.element.forceRerendering(); }, beforeSetup: function(effect) { - effect.element.setOpacity(effect.options.from).show(); + effect.element.setOpacity(effect.options.from).show(); }}, arguments[1] || { }); return new Effect.Opacity(element,options); }; Effect.Puff = function(element) { element = $(element); - var oldStyle = { - opacity: element.getInlineOpacity(), + var oldStyle = { + opacity: element.getInlineOpacity(), position: element.getStyle('position'), top: element.style.top, left: element.style.left, @@ -563,10 +563,10 @@ Effect.Puff = function(element) { height: element.style.height }; return new Effect.Parallel( - [ new Effect.Scale(element, 200, - { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], - Object.extend({ duration: 1.0, + [ new Effect.Scale(element, 200, + { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], + Object.extend({ duration: 1.0, beforeSetupInternal: function(effect) { Position.absolutize(effect.effects[0].element) }, @@ -580,12 +580,12 @@ Effect.BlindUp = function(element) { element = $(element); element.makeClipping(); return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, + Object.extend({ scaleContent: false, + scaleX: false, restoreAfterFinish: true, afterFinishInternal: function(effect) { effect.element.hide().undoClipping(); - } + } }, arguments[1] || { }) ); }; @@ -593,15 +593,15 @@ Effect.BlindUp = function(element) { Effect.BlindDown = function(element) { element = $(element); var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, scaleX: false, scaleFrom: 0, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, restoreAfterFinish: true, afterSetup: function(effect) { - effect.element.makeClipping().setStyle({height: '0px'}).show(); - }, + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, afterFinishInternal: function(effect) { effect.element.undoClipping(); } @@ -616,10 +616,10 @@ Effect.SwitchOff = function(element) { from: 0, transition: Effect.Transitions.flicker, afterFinishInternal: function(effect) { - new Effect.Scale(effect.element, 1, { + new Effect.Scale(effect.element, 1, { duration: 0.3, scaleFromCenter: true, scaleX: false, scaleContent: false, restoreAfterFinish: true, - beforeSetup: function(effect) { + beforeSetup: function(effect) { effect.element.makePositioned().makeClipping(); }, afterFinishInternal: function(effect) { @@ -637,16 +637,16 @@ Effect.DropOut = function(element) { left: element.getStyle('left'), opacity: element.getInlineOpacity() }; return new Effect.Parallel( - [ new Effect.Move(element, {x: 0, y: 100, sync: true }), + [ new Effect.Move(element, {x: 0, y: 100, sync: true }), new Effect.Opacity(element, { sync: true, to: 0.0 }) ], Object.extend( { duration: 0.5, beforeSetup: function(effect) { - effect.effects[0].element.makePositioned(); + effect.effects[0].element.makePositioned(); }, afterFinishInternal: function(effect) { effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); - } + } }, arguments[1] || { })); }; @@ -682,9 +682,9 @@ Effect.SlideDown = function(element) { // SlideDown need to have the content of the element wrapped in a container element with fixed height! var oldInnerBottom = element.down().getStyle('bottom'); var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, - scaleX: false, + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, scaleFrom: window.opera ? 0 : 1, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, restoreAfterFinish: true, @@ -692,11 +692,11 @@ Effect.SlideDown = function(element) { effect.element.makePositioned(); effect.element.down().makePositioned(); if (window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping().setStyle({height: '0px'}).show(); + effect.element.makeClipping().setStyle({height: '0px'}).show(); }, afterUpdateInternal: function(effect) { effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); + (effect.dims[0] - effect.element.clientHeight) + 'px' }); }, afterFinishInternal: function(effect) { effect.element.undoClipping().undoPositioned(); @@ -710,8 +710,8 @@ Effect.SlideUp = function(element) { var oldInnerBottom = element.down().getStyle('bottom'); var elementDimensions = element.getDimensions(); return new Effect.Scale(element, window.opera ? 0 : 1, - Object.extend({ scaleContent: false, - scaleX: false, + Object.extend({ scaleContent: false, + scaleX: false, scaleMode: 'box', scaleFrom: 100, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, @@ -721,7 +721,7 @@ Effect.SlideUp = function(element) { effect.element.down().makePositioned(); if (window.opera) effect.element.setStyle({top: ''}); effect.element.makeClipping().show(); - }, + }, afterUpdateInternal: function(effect) { effect.element.down().setStyle({bottom: (effect.dims[0] - effect.element.clientHeight) + 'px' }); @@ -734,15 +734,15 @@ Effect.SlideUp = function(element) { ); }; -// Bug in opera makes the TD containing this element expand for a instance after finish +// Bug in opera makes the TD containing this element expand for a instance after finish Effect.Squish = function(element) { - return new Effect.Scale(element, window.opera ? 1 : 0, { + return new Effect.Scale(element, window.opera ? 1 : 0, { restoreAfterFinish: true, beforeSetup: function(effect) { - effect.element.makeClipping(); - }, + effect.element.makeClipping(); + }, afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); + effect.element.hide().undoClipping(); } }); }; @@ -762,13 +762,13 @@ Effect.Grow = function(element) { width: element.style.width, opacity: element.getInlineOpacity() }; - var dims = element.getDimensions(); + var dims = element.getDimensions(); var initialMoveX, initialMoveY; var moveX, moveY; - + switch (options.direction) { case 'top-left': - initialMoveX = initialMoveY = moveX = moveY = 0; + initialMoveX = initialMoveY = moveX = moveY = 0; break; case 'top-right': initialMoveX = dims.width; @@ -793,11 +793,11 @@ Effect.Grow = function(element) { moveY = -dims.height / 2; break; } - + return new Effect.Move(element, { x: initialMoveX, y: initialMoveY, - duration: 0.01, + duration: 0.01, beforeSetup: function(effect) { effect.element.hide().makeClipping().makePositioned(); }, @@ -806,14 +806,14 @@ Effect.Grow = function(element) { [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), new Effect.Scale(effect.element, 100, { - scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, + scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) ], Object.extend({ beforeSetup: function(effect) { - effect.effects[0].element.setStyle({height: '0px'}).show(); + effect.effects[0].element.setStyle({height: '0px'}).show(); }, afterFinishInternal: function(effect) { - effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); + effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); } }, options) ) @@ -838,7 +838,7 @@ Effect.Shrink = function(element) { var dims = element.getDimensions(); var moveX, moveY; - + switch (options.direction) { case 'top-left': moveX = moveY = 0; @@ -855,19 +855,19 @@ Effect.Shrink = function(element) { moveX = dims.width; moveY = dims.height; break; - case 'center': + case 'center': moveX = dims.width / 2; moveY = dims.height / 2; break; } - + return new Effect.Parallel( [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) - ], Object.extend({ + ], Object.extend({ beforeStartInternal: function(effect) { - effect.effects[0].element.makePositioned().makeClipping(); + effect.effects[0].element.makePositioned().makeClipping(); }, afterFinishInternal: function(effect) { effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } @@ -882,7 +882,7 @@ Effect.Pulsate = function(element) { var transition = options.transition || Effect.Transitions.sinoidal; var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; reverser.bind(transition); - return new Effect.Opacity(element, + return new Effect.Opacity(element, Object.extend(Object.extend({ duration: 2.0, from: 0, afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } }, options), {transition: reverser})); @@ -896,12 +896,12 @@ Effect.Fold = function(element) { width: element.style.width, height: element.style.height }; element.makeClipping(); - return new Effect.Scale(element, 5, Object.extend({ + return new Effect.Scale(element, 5, Object.extend({ scaleContent: false, scaleX: false, afterFinishInternal: function(effect) { - new Effect.Scale(element, 1, { - scaleContent: false, + new Effect.Scale(element, 1, { + scaleContent: false, scaleY: false, afterFinishInternal: function(effect) { effect.element.hide().undoClipping().setStyle(oldStyle); @@ -916,7 +916,7 @@ Effect.Morph = Class.create(Effect.Base, { var options = Object.extend({ style: { } }, arguments[1] || { }); - + if (!Object.isString(options.style)) this.style = $H(options.style); else { if (options.style.include(':')) @@ -939,13 +939,13 @@ Effect.Morph = Class.create(Effect.Base, { } this.start(options); }, - + setup: function(){ function parseColor(color){ if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; color = color.parseColor(); return $R(0,2).map(function(i){ - return parseInt( color.slice(i*2+1,i*2+3), 16 ) + return parseInt( color.slice(i*2+1,i*2+3), 16 ) }); } this.transforms = this.style.map(function(pair){ @@ -965,9 +965,9 @@ Effect.Morph = Class.create(Effect.Base, { } var originalValue = this.element.getStyle(property); - return { - style: property.camelize(), - originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), + return { + style: property.camelize(), + originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), targetValue: unit=='color' ? parseColor(value) : value, unit: unit }; @@ -984,7 +984,7 @@ Effect.Morph = Class.create(Effect.Base, { update: function(position) { var style = { }, transform, i = this.transforms.length; while(i--) - style[(transform = this.transforms[i]).style] = + style[(transform = this.transforms[i]).style] = transform.unit=='color' ? '#'+ (Math.round(transform.originalValue[0]+ (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + @@ -993,7 +993,7 @@ Effect.Morph = Class.create(Effect.Base, { (Math.round(transform.originalValue[2]+ (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : (transform.originalValue + - (transform.targetValue - transform.originalValue) * position).toFixed(3) + + (transform.targetValue - transform.originalValue) * position).toFixed(3) + (transform.unit === null ? '' : transform.unit); this.element.setStyle(style, true); } @@ -1030,7 +1030,7 @@ Effect.Transform = Class.create({ }); Element.CSS_PROPERTIES = $w( - 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + + 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + @@ -1039,7 +1039,7 @@ Element.CSS_PROPERTIES = $w( 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + 'right textIndent top width wordSpacing zIndex'); - + Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; String.__parseStyleElement = document.createElement('div'); @@ -1051,11 +1051,11 @@ String.prototype.parseStyle = function(){ String.__parseStyleElement.innerHTML = '
    '; style = String.__parseStyleElement.childNodes[0].style; } - + Element.CSS_PROPERTIES.each(function(property){ - if (style[property]) styleRules.set(property, style[property]); + if (style[property]) styleRules.set(property, style[property]); }); - + if (Prototype.Browser.IE && this.include('opacity')) styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); @@ -1104,7 +1104,7 @@ Effect.Methods = { $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ 'pulsate shake puff squish switchOff dropOut').each( - function(effect) { + function(effect) { Effect.Methods[effect] = function(element, options){ element = $(element); Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); @@ -1113,7 +1113,7 @@ $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ } ); -$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( +$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( function(f) { Effect.Methods[f] = Element[f]; } ); diff --git a/public/javascripts/scriptaculous.js b/public/javascripts/scriptaculous.js index cd0e341..4da2a00 100644 --- a/public/javascripts/scriptaculous.js +++ b/public/javascripts/scriptaculous.js @@ -1,5 +1,5 @@ // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// +// // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including @@ -7,7 +7,7 @@ // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // diff --git a/public/javascripts/slider.js b/public/javascripts/slider.js index 1712b98..15c4894 100644 --- a/public/javascripts/slider.js +++ b/public/javascripts/slider.js @@ -1,5 +1,5 @@ // Copyright (c) 2005 Marty Haught -// +// // See scriptaculous.js for full license. if(!Control) var Control = {}; @@ -26,8 +26,8 @@ Control.Slider.prototype = { this.value = 0; var defaultMaximum = Math.round(this.track.offsetWidth / this.increment); - if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment); - + if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment); + this.maximum = this.options.maximum || defaultMaximum; this.minimum = this.options.minimum || 0; @@ -35,7 +35,7 @@ Control.Slider.prototype = { this.alignX = parseInt (this.options.alignX) || 0; this.alignY = parseInt (this.options.alignY) || 0; - // Zero out the slider position + // Zero out the slider position this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX); this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY); @@ -54,7 +54,7 @@ Control.Slider.prototype = { this.disabled = false; // FIXME: use css - this.handleImage = $(this.options.handleImage) || false; + this.handleImage = $(this.options.handleImage) || false; this.handleDisabled = this.options.handleDisabled || false; this.handleEnabled = false; if(this.handleImage) @@ -93,7 +93,7 @@ Control.Slider.prototype = { this.disabled = false; if(this.handleEnabled) this.handleImage.src = this.handleEnabled; - }, + }, currentLeft: function() { return parseInt(this.handle.style.left || '0'); }, @@ -111,7 +111,7 @@ Control.Slider.prototype = { }, trackTop: function(){ return Position.cumulativeOffset(this.track)[1]; - }, + }, getNearestValue: function(value){ if(this.values){ var i = 0; @@ -131,11 +131,11 @@ Control.Slider.prototype = { }, setSliderValue: function(sliderValue){ // First check our max and minimum and nearest values - sliderValue = this.getNearestValue(sliderValue); + sliderValue = this.getNearestValue(sliderValue); if(sliderValue > this.maximum) sliderValue = this.maximum; if(sliderValue < this.minimum) sliderValue = this.minimum; var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment; - + if(this.isVertical()){ this.setCurrentTop(offsetDiff + this.currentTop()); } else { @@ -143,9 +143,9 @@ Control.Slider.prototype = { } this.value = sliderValue; this.updateFinished(); - }, + }, minimumOffset: function(){ - return(this.isVertical() ? + return(this.isVertical() ? this.trackTop() + this.alignY : this.trackLeft() + this.alignX); }, @@ -153,7 +153,7 @@ Control.Slider.prototype = { return(this.isVertical() ? this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment : this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment); - }, + }, isVertical: function(){ return (this.axis == 'vertical'); }, @@ -191,7 +191,7 @@ Control.Slider.prototype = { offsets[0] -= this.currentLeft(); offsets[1] -= this.currentTop(); - + // Adjust for the pointer's position on the handle pointer[0] -= this.offsetX; pointer[1] -= this.offsetY; @@ -232,7 +232,7 @@ Control.Slider.prototype = { } this.active = false; this.dragging = false; - }, + }, finishDrag: function(event, success) { this.active = false; this.dragging = false; @@ -249,7 +249,7 @@ Control.Slider.prototype = { switch(event.keyCode) { case Event.KEY_ESC: this.finishDrag(event, false); - Event.stop(event); + Event.stop(event); break; } if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); diff --git a/test/fixtures/articles.yml b/test/fixtures/articles.yml index f5a62a3..9413d69 100644 --- a/test/fixtures/articles.yml +++ b/test/fixtures/articles.yml @@ -11,7 +11,7 @@ peatsbooks: modified_at: now member_id: 1 title: PDX.rb versus Peats Books - content: meep. meep. moop. + content: meep. meep. moop. link: http//www.peatbooks.com/ hackfest: @@ -19,5 +19,5 @@ hackfest: modified_at: now member_id: 2 title: PDX.rb gets drunk. Ben takes off his clothes - content: Seriously... he took his clothes off and sat on PeatsBooks.com. + content: Seriously... he took his clothes off and sat on PeatsBooks.com. link: http//blog.bleything.net/ diff --git a/test/test_helper.rb b/test/test_helper.rb index af195f0..9063a69 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -6,7 +6,7 @@ class Test::Unit::TestCase # Turn off transactional fixtures if you're working with MyISAM tables in MySQL self.use_transactional_fixtures = true - + # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david) self.use_instantiated_fixtures = false diff --git a/test/unit/mail_bot_test.rb b/test/unit/mail_bot_test.rb index b467937..3768523 100644 --- a/test/unit/mail_bot_test.rb +++ b/test/unit/mail_bot_test.rb @@ -15,7 +15,7 @@ def setup @expected = TMail::Mail.new @expected.set_content_type "text", "plain", { "charset" => CHARSET } end - + def test_nothing assert true end diff --git a/vendor/plugins/yet_another_form_builder/lib/rubaidh/form_helper.rb b/vendor/plugins/yet_another_form_builder/lib/rubaidh/form_helper.rb index 21601f1..045c695 100644 --- a/vendor/plugins/yet_another_form_builder/lib/rubaidh/form_helper.rb +++ b/vendor/plugins/yet_another_form_builder/lib/rubaidh/form_helper.rb @@ -1,10 +1,10 @@ module Rubaidh #:nodoc: module FormHelper - + # def self.included(base) # base.alias_method_chain :fields_for, :fieldset # end - # + # # # Behaves just like the regular +fields_for+ with a little extra magic # # juju in that it creates a fieldset around the fields inside. # def fields_for_with_fieldset(object_name, *args, &block) @@ -32,7 +32,7 @@ def fieldset(options, builder, &block) block.call(builder) concat "", block.binding end - + def grouped_collection_select(object_name, method, collection, group_method, group_label_method, value_method, text_method, options = {}, html_options = {}) ActionView::Helpers::InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_grouped_collection_select_tag(collection, group_method, group_label_method, value_method, text_method, options, html_options) end @@ -57,7 +57,7 @@ def to_label_tag(options = {}) label end - + def to_grouped_collection_select_tag(collection, group_method, group_label_method, value_method, text_method, options, html_options) html_options = html_options.stringify_keys add_default_name_and_id(html_options) @@ -140,17 +140,17 @@ def fields_for(object_name, object, builder = self.class, &proc) def fieldset(options = {}, builder = self, &block) @template.fieldset(options, builder, &block) end - + private def label_options_from_options(options) label_options = options.dup - - # Remove the options from the main field which apply solely to the + + # Remove the options from the main field which apply solely to the # label. [:label, :description, :required].each do |v| options.delete(v) end - + # Tidy up the label options so they only have what's required. label_options.reject do |k, v| ![:id, :label, :description, :required].include?(k)