[23729] users/jberry/mpwa
source_changes at macosforge.org
source_changes at macosforge.org
Sat Apr 7 16:43:11 PDT 2007
Revision: 23729
http://trac.macosforge.org/projects/macports/changeset/23729
Author: jberry at macports.org
Date: 2007-04-07 16:43:09 -0700 (Sat, 07 Apr 2007)
Log Message:
-----------
More of mpwa:
* Model and simple views for ports, portpkgs, people, tags
* Update to rails 1.2.3
* Leaving out variants and dependencies for now
* Leaving out stuff for build logging and comments for now
Modified Paths:
--------------
users/jberry/mpwa/config/boot.rb
users/jberry/mpwa/config/database.yml
users/jberry/mpwa/config/environment.rb
users/jberry/mpwa/doc/schema-thoughts.sql
users/jberry/mpwa/public/javascripts/controls.js
users/jberry/mpwa/public/javascripts/dragdrop.js
users/jberry/mpwa/public/javascripts/effects.js
users/jberry/mpwa/public/javascripts/prototype.js
Added Paths:
-----------
users/jberry/mpwa/app/controllers/person_controller.rb
users/jberry/mpwa/app/controllers/port_controller.rb
users/jberry/mpwa/app/controllers/port_pkg_controller.rb
users/jberry/mpwa/app/controllers/tag_controller.rb
users/jberry/mpwa/app/helpers/person_helper.rb
users/jberry/mpwa/app/helpers/port_helper.rb
users/jberry/mpwa/app/helpers/port_pkg_helper.rb
users/jberry/mpwa/app/helpers/tag_helper.rb
users/jberry/mpwa/app/models/person.rb
users/jberry/mpwa/app/models/port.rb
users/jberry/mpwa/app/models/port_pkg.rb
users/jberry/mpwa/app/models/tag.rb
users/jberry/mpwa/app/views/layouts/person.rhtml
users/jberry/mpwa/app/views/layouts/port.rhtml
users/jberry/mpwa/app/views/layouts/port_pkg.rhtml
users/jberry/mpwa/app/views/layouts/tag.rhtml
users/jberry/mpwa/app/views/person/
users/jberry/mpwa/app/views/person/_form.rhtml
users/jberry/mpwa/app/views/person/edit.rhtml
users/jberry/mpwa/app/views/person/list.rhtml
users/jberry/mpwa/app/views/person/new.rhtml
users/jberry/mpwa/app/views/person/show.rhtml
users/jberry/mpwa/app/views/port/
users/jberry/mpwa/app/views/port/_form.rhtml
users/jberry/mpwa/app/views/port/edit.rhtml
users/jberry/mpwa/app/views/port/list.rhtml
users/jberry/mpwa/app/views/port/new.rhtml
users/jberry/mpwa/app/views/port/show.rhtml
users/jberry/mpwa/app/views/port_pkg/
users/jberry/mpwa/app/views/port_pkg/_form.rhtml
users/jberry/mpwa/app/views/port_pkg/edit.rhtml
users/jberry/mpwa/app/views/port_pkg/list.rhtml
users/jberry/mpwa/app/views/port_pkg/new.rhtml
users/jberry/mpwa/app/views/port_pkg/show.rhtml
users/jberry/mpwa/app/views/tag/
users/jberry/mpwa/app/views/tag/_form.rhtml
users/jberry/mpwa/app/views/tag/edit.rhtml
users/jberry/mpwa/app/views/tag/list.rhtml
users/jberry/mpwa/app/views/tag/new.rhtml
users/jberry/mpwa/app/views/tag/show.rhtml
users/jberry/mpwa/public/stylesheets/scaffold.css
users/jberry/mpwa/script/process/inspector
users/jberry/mpwa/test/fixtures/people.yml
users/jberry/mpwa/test/fixtures/port_pkgs.yml
users/jberry/mpwa/test/fixtures/ports.yml
users/jberry/mpwa/test/fixtures/tags.yml
users/jberry/mpwa/test/fixtures/users.yml
users/jberry/mpwa/test/functional/person_controller_test.rb
users/jberry/mpwa/test/functional/port_controller_test.rb
users/jberry/mpwa/test/functional/port_pkg_controller_test.rb
users/jberry/mpwa/test/functional/tag_controller_test.rb
users/jberry/mpwa/test/unit/person_test.rb
users/jberry/mpwa/test/unit/port_pkg_test.rb
users/jberry/mpwa/test/unit/port_test.rb
users/jberry/mpwa/test/unit/tag_test.rb
users/jberry/mpwa/test/unit/user_test.rb
Added: users/jberry/mpwa/app/controllers/person_controller.rb
===================================================================
--- users/jberry/mpwa/app/controllers/person_controller.rb (rev 0)
+++ users/jberry/mpwa/app/controllers/person_controller.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,51 @@
+class PersonController < ApplicationController
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @person_pages, @people = paginate :people, :per_page => 10
+ end
+
+ def show
+ @person = Person.find(params[:id])
+ end
+
+ def new
+ @person = Person.new
+ end
+
+ def create
+ @person = Person.new(params[:person])
+ if @person.save
+ flash[:notice] = 'Person was successfully created.'
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @person = Person.find(params[:id])
+ end
+
+ def update
+ @person = Person.find(params[:id])
+ if @person.update_attributes(params[:person])
+ flash[:notice] = 'Person was successfully updated.'
+ redirect_to :action => 'show', :id => @person
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ Person.find(params[:id]).destroy
+ redirect_to :action => 'list'
+ end
+end
Added: users/jberry/mpwa/app/controllers/port_controller.rb
===================================================================
--- users/jberry/mpwa/app/controllers/port_controller.rb (rev 0)
+++ users/jberry/mpwa/app/controllers/port_controller.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,51 @@
+class PortController < ApplicationController
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @port_pages, @ports = paginate :ports, :per_page => 10
+ end
+
+ def show
+ @port = Port.find(params[:id])
+ end
+
+ def new
+ @port = Port.new
+ end
+
+ def create
+ @port = Port.new(params[:port])
+ if @port.save
+ flash[:notice] = 'Port was successfully created.'
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @port = Port.find(params[:id])
+ end
+
+ def update
+ @port = Port.find(params[:id])
+ if @port.update_attributes(params[:port])
+ flash[:notice] = 'Port was successfully updated.'
+ redirect_to :action => 'show', :id => @port
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ Port.find(params[:id]).destroy
+ redirect_to :action => 'list'
+ end
+end
Added: users/jberry/mpwa/app/controllers/port_pkg_controller.rb
===================================================================
--- users/jberry/mpwa/app/controllers/port_pkg_controller.rb (rev 0)
+++ users/jberry/mpwa/app/controllers/port_pkg_controller.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,51 @@
+class PortPkgController < ApplicationController
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @port_pkg_pages, @port_pkgs = paginate :port_pkgs, :per_page => 10
+ end
+
+ def show
+ @port_pkg = PortPkg.find(params[:id])
+ end
+
+ def new
+ @port_pkg = PortPkg.new
+ end
+
+ def create
+ @port_pkg = PortPkg.new(params[:port_pkg])
+ if @port_pkg.save
+ flash[:notice] = 'PortPkg was successfully created.'
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @port_pkg = PortPkg.find(params[:id])
+ end
+
+ def update
+ @port_pkg = PortPkg.find(params[:id])
+ if @port_pkg.update_attributes(params[:port_pkg])
+ flash[:notice] = 'PortPkg was successfully updated.'
+ redirect_to :action => 'show', :id => @port_pkg
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ PortPkg.find(params[:id]).destroy
+ redirect_to :action => 'list'
+ end
+end
Added: users/jberry/mpwa/app/controllers/tag_controller.rb
===================================================================
--- users/jberry/mpwa/app/controllers/tag_controller.rb (rev 0)
+++ users/jberry/mpwa/app/controllers/tag_controller.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,51 @@
+class TagController < ApplicationController
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @tag_pages, @tags = paginate :tags, :per_page => 10
+ end
+
+ def show
+ @tag = Tag.find(params[:id])
+ end
+
+ def new
+ @tag = Tag.new
+ end
+
+ def create
+ @tag = Tag.new(params[:tag])
+ if @tag.save
+ flash[:notice] = 'Tag was successfully created.'
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @tag = Tag.find(params[:id])
+ end
+
+ def update
+ @tag = Tag.find(params[:id])
+ if @tag.update_attributes(params[:tag])
+ flash[:notice] = 'Tag was successfully updated.'
+ redirect_to :action => 'show', :id => @tag
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def destroy
+ Tag.find(params[:id]).destroy
+ redirect_to :action => 'list'
+ end
+end
Added: users/jberry/mpwa/app/helpers/person_helper.rb
===================================================================
--- users/jberry/mpwa/app/helpers/person_helper.rb (rev 0)
+++ users/jberry/mpwa/app/helpers/person_helper.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,2 @@
+module PersonHelper
+end
Added: users/jberry/mpwa/app/helpers/port_helper.rb
===================================================================
--- users/jberry/mpwa/app/helpers/port_helper.rb (rev 0)
+++ users/jberry/mpwa/app/helpers/port_helper.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,2 @@
+module PortHelper
+end
Added: users/jberry/mpwa/app/helpers/port_pkg_helper.rb
===================================================================
--- users/jberry/mpwa/app/helpers/port_pkg_helper.rb (rev 0)
+++ users/jberry/mpwa/app/helpers/port_pkg_helper.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,2 @@
+module PortPkgHelper
+end
Added: users/jberry/mpwa/app/helpers/tag_helper.rb
===================================================================
--- users/jberry/mpwa/app/helpers/tag_helper.rb (rev 0)
+++ users/jberry/mpwa/app/helpers/tag_helper.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,2 @@
+module TagHelper
+end
Added: users/jberry/mpwa/app/models/person.rb
===================================================================
--- users/jberry/mpwa/app/models/person.rb (rev 0)
+++ users/jberry/mpwa/app/models/person.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,4 @@
+class Person < ActiveRecord::Base
+ has_and_belongs_to_many :ports, :class_name => 'Port', :join_table => 'maintainers_ports'
+ has_many :port_pkgs, :foreign_key => 'submitter_id'
+end
Added: users/jberry/mpwa/app/models/port.rb
===================================================================
--- users/jberry/mpwa/app/models/port.rb (rev 0)
+++ users/jberry/mpwa/app/models/port.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+class Port < ActiveRecord::Base
+ has_many :port_pkgs
+ has_and_belongs_to_many :tags
+ has_and_belongs_to_many :maintainers, :class_name => 'Person', :join_table => 'maintainers_ports'
+end
Added: users/jberry/mpwa/app/models/port_pkg.rb
===================================================================
--- users/jberry/mpwa/app/models/port_pkg.rb (rev 0)
+++ users/jberry/mpwa/app/models/port_pkg.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+class PortPkg < ActiveRecord::Base
+ belongs_to :port
+ belongs_to :submitter, :class_name => 'Person', :foreign_key => 'submitter_id'
+ has_and_belongs_to_many :tags
+end
Added: users/jberry/mpwa/app/models/tag.rb
===================================================================
--- users/jberry/mpwa/app/models/tag.rb (rev 0)
+++ users/jberry/mpwa/app/models/tag.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,4 @@
+class Tag < ActiveRecord::Base
+ has_and_belongs_to_many :ports
+ has_and_belongs_to_many :port_pkgs
+end
Added: users/jberry/mpwa/app/views/layouts/person.rhtml
===================================================================
--- users/jberry/mpwa/app/views/layouts/person.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/layouts/person.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+ <title>Person: <%= controller.action_name %></title>
+ <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+
+<%= yield %>
+
+</body>
+</html>
Added: users/jberry/mpwa/app/views/layouts/port.rhtml
===================================================================
--- users/jberry/mpwa/app/views/layouts/port.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/layouts/port.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+ <title>Port: <%= controller.action_name %></title>
+ <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+
+<%= yield %>
+
+</body>
+</html>
Added: users/jberry/mpwa/app/views/layouts/port_pkg.rhtml
===================================================================
--- users/jberry/mpwa/app/views/layouts/port_pkg.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/layouts/port_pkg.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+ <title>PortPkg: <%= controller.action_name %></title>
+ <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+
+<%= yield %>
+
+</body>
+</html>
Added: users/jberry/mpwa/app/views/layouts/tag.rhtml
===================================================================
--- users/jberry/mpwa/app/views/layouts/tag.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/layouts/tag.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+ <title>Tag: <%= controller.action_name %></title>
+ <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+
+<%= yield %>
+
+</body>
+</html>
Added: users/jberry/mpwa/app/views/person/_form.rhtml
===================================================================
--- users/jberry/mpwa/app/views/person/_form.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/person/_form.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,16 @@
+<%= error_messages_for 'person' %>
+
+<!--[form:person]-->
+<p><label for="person_user_name">User name</label><br/>
+<%= text_field 'person', 'user_name' %></p>
+
+<p><label for="person_firt_name">First name</label><br/>
+<%= text_field 'person', 'first_name' %></p>
+
+<p><label for="person_last_name">Last name</label><br/>
+<%= text_field 'person', 'last_name' %></p>
+
+<p><label for="person_email">Email</label><br/>
+<%= text_field 'person', 'email' %></p>
+<!--[eoform:person]-->
+
Added: users/jberry/mpwa/app/views/person/edit.rhtml
===================================================================
--- users/jberry/mpwa/app/views/person/edit.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/person/edit.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,9 @@
+<h1>Editing person</h1>
+
+<% form_tag :action => 'update', :id => @person do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag 'Edit' %>
+<% end %>
+
+<%= link_to 'Show', :action => 'show', :id => @person %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/person/list.rhtml
===================================================================
--- users/jberry/mpwa/app/views/person/list.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/person/list.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,27 @@
+<h1>Listing people</h1>
+
+<table>
+ <tr>
+ <% for column in Person.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for person in @people %>
+ <tr>
+ <% for column in Person.content_columns %>
+ <td><%=h person.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => person %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => person %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => person }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @person_pages.current.previous } if @person_pages.current.previous %>
+<%= link_to 'Next page', { :page => @person_pages.current.next } if @person_pages.current.next %>
+
+<br />
+
+<%= link_to 'New person', :action => 'new' %>
Added: users/jberry/mpwa/app/views/person/new.rhtml
===================================================================
--- users/jberry/mpwa/app/views/person/new.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/person/new.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,8 @@
+<h1>New person</h1>
+
+<% form_tag :action => 'create' do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag "Create" %>
+<% end %>
+
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/person/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/person/show.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/person/show.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,22 @@
+<% for column in Person.content_columns %>
+<p>
+ <b><%= column.human_name %>:</b> <%=h @person.send(column.name) %>
+</p>
+<% end %>
+
+<h4>Ports</h4>
+<p>
+ <% for port in @person.ports %>
+ <%= link_to port.name, :controller => 'port', :action => 'show', :id => port %><br />
+ <% end %>
+</p>
+
+<h4>Packages</h4>
+<p>
+ <% for pkg in @person.port_pkgs %>
+ <%= link_to pkg.id, :controller => 'port_pkg', :action => 'show', :id => pkg %><br />
+ <% end %>
+</p>
+
+<%= link_to 'Edit', :action => 'edit', :id => @person %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/port/_form.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port/_form.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port/_form.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,16 @@
+<%= error_messages_for 'port' %>
+
+<!--[form:port]-->
+<p><label for="name">Name</label><br/>
+<%= text_field 'port', 'name' %></p>
+
+<p><label for="port_home_page">HomePage</label><br/>
+<%= text_field 'port', 'home_page' %></p>
+
+<p><label for="port_short_desc">ShortDesc</label><br/>
+<%= text_field 'port', 'short_desc' %></p>
+
+<p><label for="port_long_desc">LongDesc</label><br/>
+<%= text_area 'port', 'long_desc' %></p>
+<!--[eoform:port]-->
+
Added: users/jberry/mpwa/app/views/port/edit.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port/edit.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port/edit.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,9 @@
+<h1>Editing port</h1>
+
+<% form_tag :action => 'update', :id => @port do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag 'Edit' %>
+<% end %>
+
+<%= link_to 'Show', :action => 'show', :id => @port %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/port/list.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port/list.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port/list.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,27 @@
+<h1>Listing ports</h1>
+
+<table>
+ <tr>
+ <% for column in Port.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for port in @ports %>
+ <tr>
+ <% for column in Port.content_columns %>
+ <td><%=h port.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => port %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => port %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => port }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @port_pages.current.previous } if @port_pages.current.previous %>
+<%= link_to 'Next page', { :page => @port_pages.current.next } if @port_pages.current.next %>
+
+<br />
+
+<%= link_to 'New port', :action => 'new' %>
Added: users/jberry/mpwa/app/views/port/new.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port/new.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port/new.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,8 @@
+<h1>New port</h1>
+
+<% form_tag :action => 'create' do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag "Create" %>
+<% end %>
+
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/port/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port/show.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port/show.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,29 @@
+<% for column in Port.content_columns %>
+<p>
+ <b><%= column.human_name %>:</b> <%=h @port.send(column.name) %>
+</p>
+<% end %>
+
+<h4>Maintainers</h4>
+<p>
+ <% for maintainer in @port.maintainers %>
+ <%= link_to maintainer.user_name, :controller => 'person', :action => 'show', :id => maintainer %><br />
+ <% end %>
+</p>
+
+<h4>Tags</h4>
+<p>
+ <% for tag in @port.tags %>
+ <%= link_to tag.name, :controller => 'tag', :action => 'show', :id => tag %>
+ <% end %>
+</p>
+
+<h4>Port Packages</h4>
+<p>
+ <% for pkg in @port.port_pkgs %>
+ <%= link_to pkg.id, :controller => 'port_pkg', :action => 'show', :id => pkg %><br />
+ <% end %>
+</p>
+
+<%= link_to 'Edit', :action => 'edit', :id => @port %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/port_pkg/_form.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port_pkg/_form.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port_pkg/_form.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,19 @@
+<%= error_messages_for 'port_pkg' %>
+
+<!--[form:port_pkg]-->
+<p><label for="port_pkg_submitted_at">Submitted at</label><br/>
+<%= datetime_select 'port_pkg', 'submitted_at' %></p>
+
+<p><label for="port_pkg_epoch">Epoch</label><br/>
+<%= text_field 'port_pkg', 'epoch' %></p>
+
+<p><label for="port_pkg_version">Version</label><br/>
+<%= text_field 'port_pkg', 'version' %></p>
+
+<p><label for="port_pkg_revision">Revision</label><br/>
+<%= text_field 'port_pkg', 'revision' %></p>
+
+<p><label for="port_pkg_url">Url</label><br/>
+<%= text_field 'port_pkg', 'url' %></p>
+<!--[eoform:port_pkg]-->
+
Added: users/jberry/mpwa/app/views/port_pkg/edit.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port_pkg/edit.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port_pkg/edit.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,9 @@
+<h1>Editing port_pkg</h1>
+
+<% form_tag :action => 'update', :id => @port_pkg do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag 'Edit' %>
+<% end %>
+
+<%= link_to 'Show', :action => 'show', :id => @port_pkg %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/port_pkg/list.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port_pkg/list.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port_pkg/list.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,27 @@
+<h1>Listing port_pkgs</h1>
+
+<table>
+ <tr>
+ <% for column in PortPkg.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for port_pkg in @port_pkgs %>
+ <tr>
+ <% for column in PortPkg.content_columns %>
+ <td><%=h port_pkg.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => port_pkg %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => port_pkg %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => port_pkg }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @port_pkg_pages.current.previous } if @port_pkg_pages.current.previous %>
+<%= link_to 'Next page', { :page => @port_pkg_pages.current.next } if @port_pkg_pages.current.next %>
+
+<br />
+
+<%= link_to 'New port_pkg', :action => 'new' %>
Added: users/jberry/mpwa/app/views/port_pkg/new.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port_pkg/new.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port_pkg/new.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,8 @@
+<h1>New port_pkg</h1>
+
+<% form_tag :action => 'create' do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag "Create" %>
+<% end %>
+
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/port_pkg/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/port_pkg/show.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/port_pkg/show.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,21 @@
+<% for column in PortPkg.content_columns %>
+<p>
+ <b><%= column.human_name %>:</b> <%=h @port_pkg.send(column.name) %>
+</p>
+<% end %>
+
+<h4>Port</h4>
+<p><%= link_to @port_pkg.port.name, :controller => 'port', :action => 'show', :id => @port_pkg.port %></p>
+
+<h4>Submitter</h4>
+<p><%= link_to @port_pkg.submitter.user_name, :controller => 'person', :action => 'show', :id => @port_pkg.submitter %></p>
+
+<h4>Tags</h4>
+<p>
+ <% for tag in @port_pkg.tags %>
+ <%= link_to tag.name, :controller => 'tag', :action => 'show', :id => tag %>
+ <% end %>
+</p>
+
+<%= link_to 'Edit', :action => 'edit', :id => @port_pkg %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/tag/_form.rhtml
===================================================================
--- users/jberry/mpwa/app/views/tag/_form.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/tag/_form.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,7 @@
+<%= error_messages_for 'tag' %>
+
+<!--[form:tag]-->
+<p><label for="tag_name">Name</label><br/>
+<%= text_field 'tag', 'name' %></p>
+<!--[eoform:tag]-->
+
Added: users/jberry/mpwa/app/views/tag/edit.rhtml
===================================================================
--- users/jberry/mpwa/app/views/tag/edit.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/tag/edit.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,9 @@
+<h1>Editing tag</h1>
+
+<% form_tag :action => 'update', :id => @tag do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag 'Edit' %>
+<% end %>
+
+<%= link_to 'Show', :action => 'show', :id => @tag %> |
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/tag/list.rhtml
===================================================================
--- users/jberry/mpwa/app/views/tag/list.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/tag/list.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,27 @@
+<h1>Listing tags</h1>
+
+<table>
+ <tr>
+ <% for column in Tag.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for tag in @tags %>
+ <tr>
+ <% for column in Tag.content_columns %>
+ <td><%=h tag.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => tag %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => tag %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => tag }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @tag_pages.current.previous } if @tag_pages.current.previous %>
+<%= link_to 'Next page', { :page => @tag_pages.current.next } if @tag_pages.current.next %>
+
+<br />
+
+<%= link_to 'New tag', :action => 'new' %>
Added: users/jberry/mpwa/app/views/tag/new.rhtml
===================================================================
--- users/jberry/mpwa/app/views/tag/new.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/tag/new.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,8 @@
+<h1>New tag</h1>
+
+<% form_tag :action => 'create' do %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag "Create" %>
+<% end %>
+
+<%= link_to 'Back', :action => 'list' %>
Added: users/jberry/mpwa/app/views/tag/show.rhtml
===================================================================
--- users/jberry/mpwa/app/views/tag/show.rhtml (rev 0)
+++ users/jberry/mpwa/app/views/tag/show.rhtml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,22 @@
+<% for column in Tag.content_columns %>
+<p>
+ <b><%= column.human_name %>:</b> <%=h @tag.send(column.name) %>
+</p>
+<% end %>
+
+<h4>Ports with this tag</h4>
+<p>
+ <% for port in @tag.ports %>
+ <%= link_to port.name, :controller => 'port', :action => 'show', :id => port %><br />
+ <% end %>
+</p>
+
+<h4>Port Packages with this tag</h4>
+<p>
+ <% for pkg in @tag.port_pkgs %>
+ <%= link_to pkg.id, :controller => 'port_pkg', :action => 'show', :id => pkg %><br />
+ <% end %>
+</p>
+
+<%= link_to 'Edit', :action => 'edit', :id => @tag %> |
+<%= link_to 'Back', :action => 'list' %>
Modified: users/jberry/mpwa/config/boot.rb
===================================================================
--- users/jberry/mpwa/config/boot.rb 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/config/boot.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -3,7 +3,7 @@
unless defined?(RAILS_ROOT)
root_path = File.join(File.dirname(__FILE__), '..')
- unless RUBY_PLATFORM =~ /mswin32/
+ unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
require 'pathname'
root_path = Pathname.new(root_path).cleanpath(true).to_s
end
@@ -22,13 +22,14 @@
rails_gem_version = $1
if version = defined?(RAILS_GEM_VERSION) ? RAILS_GEM_VERSION : rails_gem_version
- rails_gem = Gem.cache.search('rails', "=#{version}").first
+ # Asking for 1.1.6 will give you 1.1.6.5206, if available -- makes it easier to use beta gems
+ rails_gem = Gem.cache.search('rails', "~>#{version}.0").sort_by { |g| g.version.version }.last
if rails_gem
- gem "rails", "=#{version}"
+ gem "rails", "=#{rails_gem.version.version}"
require rails_gem.full_gem_path + '/lib/initializer'
else
- STDERR.puts %(Cannot find gem for Rails =#{version}:
+ STDERR.puts %(Cannot find gem for Rails ~>#{version}.0:
Install the missing gem with 'gem install -v=#{version} rails', or
change environment.rb to define RAILS_GEM_VERSION with your desired version.
)
@@ -41,4 +42,4 @@
end
Rails::Initializer.run(:set_load_path)
-end
\ No newline at end of file
+end
Modified: users/jberry/mpwa/config/database.yml
===================================================================
--- users/jberry/mpwa/config/database.yml 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/config/database.yml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -12,10 +12,11 @@
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
adapter: mysql
- database: mpwebapp_development
- username: mpwebapp
+ database: mpwa_development
+ username: mpwa
password: macports
host: localhost
+ socket: /opt/local/var/run/mysql5/mysqld.sock
# Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'.
@@ -23,13 +24,13 @@
test:
adapter: mysql
database: mpwa_test
- username: root
+ username: mpwa
password:
host: localhost
production:
adapter: mysql
database: mpwa_production
- username: root
+ username: mpwa
password:
host: localhost
Modified: users/jberry/mpwa/config/environment.rb
===================================================================
--- users/jberry/mpwa/config/environment.rb 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/config/environment.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -5,7 +5,7 @@
# ENV['RAILS_ENV'] ||= 'production'
# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '1.1.6'
+RAILS_GEM_VERSION = '1.2.3'
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
Modified: users/jberry/mpwa/doc/schema-thoughts.sql
===================================================================
--- users/jberry/mpwa/doc/schema-thoughts.sql 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/doc/schema-thoughts.sql 2007-04-07 23:43:09 UTC (rev 23729)
@@ -1,123 +1,123 @@
--- Person represents a person, potentially with a login/password
+-- People represents a person, potentially with a login/password
-- persons are used for maintainer, submitter, commenter?
-drop table if exists Person;
-create table Person (
- id bigint not null primary key auto_increment,
-
- userName text,
- firtName text,
- lastName text,
- email text
-
- -- authMethod
- -- authToken
- );
-
--- Port represents a port: a piece of software
-drop table if exists Port;
-create table Port (
- id bigint not null primary key auto_increment,
-
- portName text,
- shortDesc text,
- longDesc text,
- homePage text
-
- -- many-many association for tags through PortTagAssoc
- -- many-many association for maintainers through PortMaintainerAssoc
- );
-
--- PortMaintainerAssoc: many-many association between Port and Maintainer
-drop table if exists PortMaintainerAssoc;
-create table PortMaintainerAssoc (
- port bigint not null,
- person bigint not null
- );
-
--- PortPkg is an instance of build/install rules for a port.
--- There may be many PortPkgs for each port
-drop table if exists PortPkg;
-create table PortPkg (
- id bigint not null primary key auto_increment,
+drop table if exists People;
+create table People (
+ id bigint not null primary key auto_increment,
+
+ user_name varchar(63),
+ first_name varchar(63),
+ last_name varchar(63),
+ email varchar(63)
+
+ -- auth_method
+ -- auth_token
+);
+
+-- Ports represents a port: a piece of software
+drop table if exists Ports;
+create table Ports (
+ id bigint not null primary key auto_increment,
+
+ name varchar(63),
+ short_desc text,
+ long_desc text,
+ home_page varchar(255)
+
+ -- many-many association for tags through ports_tags
+ -- many-many association for maintainers through ports_maintainers
+);
+
+-- ports_maintainers: many-many association between Maintainers and Ports
+drop table if exists Maintainers_Ports;
+create table Maintainers_Ports (
+ person_id bigint not null,
+ port_id bigint not null
+);
+
+-- A PortPkg is an instance of build/install rules for a port.
+-- There may be many PortPkg for each Port
+drop table if exists Port_Pkgs;
+create table Port_Pkgs (
+ id bigint not null primary key auto_increment,
- port bigint not null,
-
- submitter bigint not null, -- one-one: Person
- submitDate datetime not null,
-
- epoch text,
- version text,
- revision text,
-
- pkgurl text -- uniquely identify a portpkg to outside world
- -- this might also also indexing of externally served portpkgs
-
- -- many-many association for tags through PkgTagAssoc
- -- many-many association for variants through VariantAssoc
- -- many-many association for dependencies through PkgDependencyAssoc
-
- -- (note that both pkgs and variants, have dependency relations)
- );
+ port_id bigint not null,
+
+ submitter_id bigint not null, -- one-one: Person
+ submitted_at datetime not null,
+
+ epoch varchar(32),
+ version varchar(32),
+ revision varchar(32),
+
+ url varchar(127) -- uniquely identify a portpkg to outside world
+ -- this might also also indexing of externally served portpkgs
+
+ -- one-many association for variants
+ -- many-many association for tags through PkgTagAssoc
+ -- many-many association for dependencies through PkgDependencyAssoc
+
+ -- (note that both pkgs and variants, have dependency relations)
+);
-- A tag which may be attached to various items through PkgTagAssoc, PortTagAssoc
-drop table if exists Tag;
-create table Tag (
- id bigint not null primary key auto_increment,
- name text
- );
-
+drop table if exists Tags;
+create table Tags (
+ id bigint not null primary key auto_increment,
+ name varchar(31)
+);
+
-- many-many relationship between PortPkg and Tag
-drop table if exists PkgTagAssoc;
-create table PkgTagAssoc (
- portPkg bigint not null,
- tag bigint not null
- );
+drop table if exists Port_Pkgs_Tags;
+create table Port_Pkgs_Tags (
+ port_pkg_id bigint not null,
+ tag_id bigint not null
+);
-- many-many relationship between Port and Tag
-drop table if exists PortTagAssoc;
-create table PortTagAssoc (
- port bigint not null,
- tag bigint not null
- );
+drop table if exists Ports_Tags;
+create table Ports_Tags (
+ port_id bigint not null,
+ tag_id bigint not null
+);
-- A dependency onto onther port
-drop table if exists Dependency;
-create table Dependency (
- id bigint not null primary key auto_increment,
- depExpr text -- textual? dependency expression
-
- -- can we point directly to the target port (or portpkg, or porturl???)
- -- that would make it much easier to determine reverse dependencies.
- -- maybe we have nullable fields for port, portpkg, porturl, version, revision, etc...
- );
+drop table if exists Dependencies;
+create table Dependencies (
+ id bigint not null primary key auto_increment,
+ expression text -- textual? dependency expression
+
+ -- can we point directly to the target port (or portpkg, or porturl???)
+ -- that would make it much easier to determine reverse dependencies.
+ -- maybe we have nullable fields for port, portpkg, porturl, version, revision, etc...
+);
-- many-many relationship between PortPkg and Dependency
-drop table if exists PkgDependencyAssoc;
-create table PkgDependencyAssoc (
- portPkg bigint not null,
- dependency bigint not null
- );
+drop table if exists Dependencies_Port_Pkgs;
+create table Dependencies_Port_Pkgs (
+ package_id bigint not null,
+ dependency_id bigint not null
+);
-- Variant available to a PortPkg
-drop table if exists Variant;
-create table Variant (
- id bigint not null primary key auto_increment,
- portPkg bigint not null,
-
- name text,
- description text
-
- -- many-many association for dependencies through VariantDependencyAssoc
-
- -- conflicts expr?
- );
+drop table if exists Variants;
+create table Variants (
+ id bigint not null primary key auto_increment,
+ port_pkg_id bigint not null,
+
+ name varchar(63),
+ description text
+
+ -- many-many association for dependencies through Dependencies_Variants
+
+ -- conflicts expr?
+);
-- many-many relationship between a Variant and Dependency
-drop table if exists VariantDependencyAssoc;
-create table VariantDependencyAssoc (
- variant bigint not null,
- dependency bigint not null
- );
+drop table if exists Dependencies_Variants;
+create table Dependencies_Variants (
+ variant_id bigint not null,
+ dependency_id bigint not null
+);
-- Missing components:
Modified: users/jberry/mpwa/public/javascripts/controls.js
===================================================================
--- users/jberry/mpwa/public/javascripts/controls.js 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/public/javascripts/controls.js 2007-04-07 23:43:09 UTC (rev 23729)
@@ -1,12 +1,13 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-// (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
// Contributors:
// Richard Livsey
// Rahul Bhargava
// Rob Wills
//
-// See scriptaculous.js for full license.
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
// Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This
@@ -33,6 +34,9 @@
// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.
+if(typeof Effect == 'undefined')
+ throw("controls.js requires including script.aculo.us' effects.js library");
+
var Autocompleter = {}
Autocompleter.Base = function() {};
Autocompleter.Base.prototype = {
@@ -45,7 +49,7 @@
this.index = 0;
this.entryCount = 0;
- if (this.setOptions)
+ if(this.setOptions)
this.setOptions(options);
else
this.options = options || {};
@@ -55,17 +59,20 @@
this.options.frequency = this.options.frequency || 0.4;
this.options.minChars = this.options.minChars || 1;
this.options.onShow = this.options.onShow ||
- function(element, update){
- if(!update.style.position || update.style.position=='absolute') {
- update.style.position = 'absolute';
- Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
- }
- Effect.Appear(update,{duration:0.15});
- };
+ function(element, update){
+ if(!update.style.position || update.style.position=='absolute') {
+ update.style.position = 'absolute';
+ Position.clone(element, update, {
+ setHeight: false,
+ offsetTop: element.offsetHeight
+ });
+ }
+ Effect.Appear(update,{duration:0.15});
+ };
this.options.onHide = this.options.onHide ||
- function(element, update){ new Effect.Fade(update,{duration:0.15}) };
+ 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);
this.observer = null;
@@ -94,7 +101,7 @@
},
fixIEOverlapping: function() {
- Position.clone(this.update, this.iefix);
+ Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
this.update.style.zIndex = 2;
Element.show(this.iefix);
@@ -202,11 +209,13 @@
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) {
@@ -254,11 +263,11 @@
if(!this.changed && this.hasFocus) {
this.update.innerHTML = choices;
Element.cleanWhitespace(this.update);
- Element.cleanWhitespace(this.update.firstChild);
+ Element.cleanWhitespace(this.update.down());
- if(this.update.firstChild && this.update.firstChild.childNodes) {
+ if(this.update.firstChild && this.update.down().childNodes) {
this.entryCount =
- this.update.firstChild.childNodes.length;
+ this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
@@ -269,9 +278,14 @@
}
this.stopIndicator();
-
this.index = 0;
- this.render();
+
+ if(this.entryCount==1 && this.options.autoSelect) {
+ this.selectEntry();
+ this.hide();
+ } else {
+ this.render();
+ }
}
},
@@ -459,6 +473,7 @@
this.element = $(element);
this.options = Object.extend({
+ paramName: "value",
okButton: true,
okText: "ok",
cancelLink: true,
@@ -531,7 +546,7 @@
Element.hide(this.element);
this.createForm();
this.element.parentNode.insertBefore(this.form, this.element);
- Field.scrollFreeActivate(this.editField);
+ if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);
// stop the event to avoid a page refresh in Safari
if (evt) {
Event.stop(evt);
@@ -590,7 +605,7 @@
var textField = document.createElement("input");
textField.obj = this;
textField.type = "text";
- textField.name = "value";
+ textField.name = this.options.paramName;
textField.value = text;
textField.style.backgroundColor = this.options.highlightcolor;
textField.className = 'editor_field';
@@ -603,7 +618,7 @@
this.options.textarea = true;
var textArea = document.createElement("textarea");
textArea.obj = this;
- textArea.name = "value";
+ textArea.name = this.options.paramName;
textArea.value = this.convertHTMLLineBreaks(text);
textArea.rows = this.options.rows;
textArea.cols = this.options.cols || 40;
@@ -636,6 +651,7 @@
Element.removeClassName(this.form, this.options.loadingClassName);
this.editField.disabled = false;
this.editField.value = transport.responseText.stripTags();
+ Field.scrollFreeActivate(this.editField);
},
onclickCancel: function() {
this.onComplete();
@@ -772,6 +788,8 @@
collection.each(function(e,i) {
optionTag = document.createElement("option");
optionTag.value = (e instanceof Array) ? e[0] : e;
+ if((typeof this.options.value == 'undefined') &&
+ ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
if(this.options.value==optionTag.value) optionTag.selected = true;
optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
selectTag.appendChild(optionTag);
Modified: users/jberry/mpwa/public/javascripts/dragdrop.js
===================================================================
--- users/jberry/mpwa/public/javascripts/dragdrop.js 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/public/javascripts/dragdrop.js 2007-04-07 23:43:09 UTC (rev 23729)
@@ -1,9 +1,11 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi at oriontransfer.co.nz)
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi at oriontransfer.co.nz)
//
-// See scriptaculous.js for full license.
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
-/*--------------------------------------------------------------------------*/
+if(typeof Effect == 'undefined')
+ throw("dragdrop.js requires including script.aculo.us' effects.js library");
var Droppables = {
drops: [],
@@ -145,8 +147,16 @@
},
activate: function(draggable) {
- window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
- this.activeDraggable = draggable;
+ if(draggable.options.delay) {
+ this._timeout = setTimeout(function() {
+ Draggables._timeout = null;
+ window.focus();
+ Draggables.activeDraggable = draggable;
+ }.bind(this), draggable.options.delay);
+ } else {
+ window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+ this.activeDraggable = draggable;
+ }
},
deactivate: function() {
@@ -160,10 +170,15 @@
// the same coordinates, prevent needless redrawing (moz bug?)
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer;
+
this.activeDraggable.updateDrag(event, pointer);
},
endDrag: function(event) {
+ if(this._timeout) {
+ clearTimeout(this._timeout);
+ this._timeout = null;
+ }
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
@@ -190,6 +205,7 @@
this.observers.each( function(o) {
if(o[eventName]) o[eventName](eventName, draggable, event);
});
+ if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
},
_cacheObserverCallbacks: function() {
@@ -204,39 +220,59 @@
/*--------------------------------------------------------------------------*/
var Draggable = Class.create();
+Draggable._dragging = {};
+
Draggable.prototype = {
initialize: function(element) {
- var options = Object.extend({
+ var defaults = {
handle: false,
- starteffect: function(element) {
- new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7});
- },
reverteffect: function(element, top_offset, left_offset) {
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
- element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur});
+ new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+ queue: {scope:'_draggable', position:'end'}
+ });
},
- endeffect: function(element) {
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
+ endeffect: function(element) {
+ var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+ queue: {scope:'_draggable', position:'end'},
+ afterFinish: function(){
+ Draggable._dragging[element] = false
+ }
+ });
},
zindex: 1000,
revert: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
- snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
- }, arguments[1] || {});
+ snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
+ delay: 0
+ };
+
+ if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')
+ Object.extend(defaults, {
+ starteffect: function(element) {
+ element._opacity = Element.getOpacity(element);
+ Draggable._dragging[element] = true;
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+ }
+ });
+
+ var options = Object.extend(defaults, arguments[1] || {});
this.element = $(element);
- if(options.handle && (typeof options.handle == 'string')) {
- var h = Element.childrenWithClassName(this.element, options.handle, true);
- if(h.length>0) this.handle = h[0];
- }
+ if(options.handle && (typeof options.handle == 'string'))
+ 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)
+ 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
@@ -262,6 +298,8 @@
},
initDrag: function(event) {
+ if(typeof Draggable._dragging[this.element] != 'undefined' &&
+ Draggable._dragging[this.element]) return;
if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = Event.element(event);
@@ -272,11 +310,6 @@
src.tagName=='BUTTON' ||
src.tagName=='TEXTAREA')) return;
- if(this.element._revert) {
- this.element._revert.cancel();
- this.element._revert = null;
- }
-
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var pos = Position.cumulativeOffset(this.element);
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
@@ -312,6 +345,7 @@
}
Draggables.notify('onStart', this, event);
+
if(this.options.starteffect) this.options.starteffect(this.element);
},
@@ -320,6 +354,7 @@
Position.prepare();
Droppables.show(pointer, this.element);
Draggables.notify('onDrag', this, event);
+
this.draw(pointer);
if(this.options.change) this.options.change(this);
@@ -331,8 +366,8 @@
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
} else {
p = Position.page(this.options.scroll);
- p[0] += this.options.scroll.scrollLeft;
- p[1] += this.options.scroll.scrollTop;
+ p[0] += this.options.scroll.scrollLeft + Position.deltaX;
+ p[1] += this.options.scroll.scrollTop + Position.deltaY;
p.push(p[0]+this.options.scroll.offsetWidth);
p.push(p[1]+this.options.scroll.offsetHeight);
}
@@ -378,7 +413,7 @@
if(this.options.endeffect)
this.options.endeffect(this.element);
-
+
Draggables.deactivate(this);
Droppables.reset();
},
@@ -398,10 +433,15 @@
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)) {
+ 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;
}
@@ -412,7 +452,7 @@
if(this.options.snap) {
if(typeof this.options.snap == 'function') {
- p = this.options.snap(p[0],p[1]);
+ p = this.options.snap(p[0],p[1],this);
} else {
if(this.options.snap instanceof Array) {
p = p.map( function(v, i) {
@@ -428,6 +468,7 @@
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
},
@@ -440,6 +481,7 @@
},
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);
@@ -464,14 +506,16 @@
Position.prepare();
Droppables.show(Draggables._lastPointer, this.element);
Draggables.notify('onDrag', this);
- Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
- Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
- Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
- if (Draggables._lastScrollPointer[0] < 0)
- Draggables._lastScrollPointer[0] = 0;
- if (Draggables._lastScrollPointer[1] < 0)
- Draggables._lastScrollPointer[1] = 0;
- this.draw(Draggables._lastScrollPointer);
+ if (this._isScrollChild) {
+ Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+ Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+ Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+ if (Draggables._lastScrollPointer[0] < 0)
+ Draggables._lastScrollPointer[0] = 0;
+ if (Draggables._lastScrollPointer[1] < 0)
+ Draggables._lastScrollPointer[1] = 0;
+ this.draw(Draggables._lastScrollPointer);
+ }
if(this.options.change) this.options.change(this);
},
@@ -523,6 +567,8 @@
}
var Sortable = {
+ SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+
sortables: {},
_findRootElement: function(element) {
@@ -563,12 +609,13 @@
containment: element, // also takes array of elements (or id's); or false
handle: false, // or a CSS class
only: false,
+ delay: 0,
hoverclass: null,
ghosting: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
- format: /^[^_]*_(.*)$/,
+ format: this.SERIALIZE_RULE,
onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction
}, arguments[1] || {});
@@ -582,6 +629,7 @@
scroll: options.scroll,
scrollSpeed: options.scrollSpeed,
scrollSensitivity: options.scrollSensitivity,
+ delay: options.delay,
ghosting: options.ghosting,
constraint: options.constraint,
handle: options.handle };
@@ -610,7 +658,6 @@
tree: options.tree,
hoverclass: options.hoverclass,
onHover: Sortable.onHover
- //greedy: !options.dropOnEmpty
}
var options_for_tree = {
@@ -635,7 +682,7 @@
(this.findElements(element, options) || []).each( function(e) {
// handles are per-draggable
var handle = options.handle ?
- Element.childrenWithClassName(e, options.handle)[0] : e;
+ $(e).down('.'+options.handle,0) : e;
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
@@ -706,7 +753,7 @@
if(!Element.isParent(dropon, element)) {
var index;
- var children = Sortable.findElements(dropon, {tag: droponOptions.tag});
+ var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null;
if(children) {
@@ -733,7 +780,7 @@
},
unmark: function() {
- if(Sortable._marker) Element.hide(Sortable._marker);
+ if(Sortable._marker) Sortable._marker.hide();
},
mark: function(dropon, position) {
@@ -742,23 +789,21 @@
if(sortable && !sortable.ghosting) return;
if(!Sortable._marker) {
- Sortable._marker = $('dropmarker') || document.createElement('DIV');
- Element.hide(Sortable._marker);
- Element.addClassName(Sortable._marker, 'dropmarker');
- Sortable._marker.style.position = 'absolute';
+ 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.style.left = offsets[0] + 'px';
- Sortable._marker.style.top = offsets[1] + 'px';
+ Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
if(position=='after')
if(sortable.overlap == 'horizontal')
- Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
+ Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
else
- Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
+ Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
- Element.show(Sortable._marker);
+ Sortable._marker.show();
},
_tree: function(element, options, parent) {
@@ -773,9 +818,9 @@
id: encodeURIComponent(match ? match[1] : null),
element: element,
parent: parent,
- children: new Array,
+ children: [],
position: parent.children.length,
- container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase())
+ container: $(children[i]).down(options.treeTag)
}
/* Get the element containing the children and recurse over it */
@@ -788,17 +833,6 @@
return parent;
},
- /* Finds the first element of the given tag type within a parent element.
- Used for finding the first LI[ST] within a L[IST]I[TEM].*/
- _findChildrenElement: function (element, containerTag) {
- if (element && element.hasChildNodes)
- for (var i = 0; i < element.childNodes.length; ++i)
- if (element.childNodes[i].tagName == containerTag)
- return element.childNodes[i];
-
- return null;
- },
-
tree: function(element) {
element = $(element);
var sortableOptions = this.options(element);
@@ -813,12 +847,12 @@
var root = {
id: null,
parent: null,
- children: new Array,
+ children: [],
container: element,
position: 0
}
- return Sortable._tree (element, options, root);
+ return Sortable._tree(element, options, root);
},
/* Construct a [i] index for a particular node */
@@ -867,7 +901,7 @@
if (options.tree) {
return Sortable.tree(element, arguments[1]).children.map( function (item) {
- return [name + Sortable._constructIndex(item) + "=" +
+ return [name + Sortable._constructIndex(item) + "[id]=" +
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&');
} else {
@@ -878,12 +912,10 @@
}
}
-/* Returns true if child is contained within element */
+// Returns true if child is contained within element
Element.isParent = function(child, element) {
if (!child.parentNode || child == element) return false;
-
if (child.parentNode == element) return true;
-
return Element.isParent(child.parentNode, element);
}
@@ -906,8 +938,5 @@
}
Element.offsetSize = function (element, type) {
- if (type == 'vertical' || type == 'height')
- return element.offsetHeight;
- else
- return element.offsetWidth;
-}
\ No newline at end of file
+ return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
+}
Modified: users/jberry/mpwa/public/javascripts/effects.js
===================================================================
--- users/jberry/mpwa/public/javascripts/effects.js 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/public/javascripts/effects.js 2007-04-07 23:43:09 UTC (rev 23729)
@@ -1,15 +1,16 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
//
-// See scriptaculous.js for full license.
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor = function() {
- var color = '#';
+ 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);
@@ -41,15 +42,17 @@
Element.setContentZoom = function(element, percent) {
element = $(element);
- Element.setStyle(element, {fontSize: (percent/100) + 'em'});
+ element.setStyle({fontSize: (percent/100) + 'em'});
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ return element;
}
-Element.getOpacity = function(element){
+Element.getOpacity = function(element){
+ element = $(element);
var opacity;
- if (opacity = Element.getStyle(element, 'opacity'))
+ if (opacity = element.getStyle('opacity'))
return parseFloat(opacity);
- if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
if(opacity[1]) return parseFloat(opacity[1]) / 100;
return 1.0;
}
@@ -57,34 +60,26 @@
Element.setOpacity = function(element, value){
element= $(element);
if (value == 1){
- Element.setStyle(element, { opacity:
+ element.setStyle({ opacity:
(/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
- 0.999999 : null });
- if(/MSIE/.test(navigator.userAgent))
- Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
+ 0.999999 : 1.0 });
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
} else {
if(value < 0.00001) value = 0;
- Element.setStyle(element, {opacity: value});
- if(/MSIE/.test(navigator.userAgent))
- Element.setStyle(element,
- { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')' });
+ element.setStyle({opacity: value});
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.setStyle(
+ { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+ 'alpha(opacity='+value*100+')' });
}
+ return element;
}
Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
}
-Element.childrenWithClassName = function(element, className, findFirst) {
- var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
- var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
- return (c.className && c.className.match(classNameRegExp));
- });
- if(!results) results = [];
- return results;
-}
-
Element.forceRerendering = function(element) {
try {
element = $(element);
@@ -104,9 +99,17 @@
/*--------------------------------------------------------------------------*/
var Effect = {
+ _elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+ },
tagifyText: function(element) {
+ if(typeof Builder == 'undefined')
+ throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+
var tagifyStyle = 'position:relative';
- if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
+ if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
+
element = $(element);
$A(element.childNodes).each( function(child) {
if(child.nodeType==3) {
@@ -159,34 +162,36 @@
/* ------------- transitions ------------- */
-Effect.Transitions = {}
+Effect.Transitions = {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ },
+ reverse: function(pos) {
+ return 1-pos;
+ },
+ flicker: function(pos) {
+ return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ },
+ wobble: function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ },
+ pulse: function(pos, pulses) {
+ pulses = pulses || 5;
+ return (
+ Math.round((pos % (1/pulses)) * pulses) == 0 ?
+ ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
+ 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
+ );
+ },
+ none: function(pos) {
+ return 0;
+ },
+ full: function(pos) {
+ return 1;
+ }
+};
-Effect.Transitions.linear = function(pos) {
- return pos;
-}
-Effect.Transitions.sinoidal = function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
-}
-Effect.Transitions.reverse = function(pos) {
- return 1-pos;
-}
-Effect.Transitions.flicker = function(pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
-}
-Effect.Transitions.wobble = function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
-}
-Effect.Transitions.pulse = function(pos) {
- return (Math.floor(pos*10) % 2 == 0 ?
- (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
-}
-Effect.Transitions.none = function(pos) {
- return 0;
-}
-Effect.Transitions.full = function(pos) {
- return 1;
-}
-
/* ------------- core effects ------------- */
Effect.ScopedQueue = Class.create();
@@ -212,6 +217,9 @@
e.finishOn += effect.finishOn;
});
break;
+ case 'with-last':
+ timestamp = this.effects.pluck('startOn').max() || timestamp;
+ break;
case 'end':
// start effect after last queued effect has finished
timestamp = this.effects.pluck('finishOn').max() || timestamp;
@@ -348,12 +356,24 @@
}
});
+Effect.Event = Class.create();
+Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+ initialize: function() {
+ var options = Object.extend({
+ duration: 0
+ }, arguments[0] || {});
+ this.start(options);
+ },
+ update: Prototype.emptyFunction
+});
+
Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
// make this work on IE on elements without 'layout'
- if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
+ if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
var options = Object.extend({
from: this.element.getOpacity() || 0.0,
@@ -370,6 +390,7 @@
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
x: 0,
y: 0,
@@ -393,8 +414,8 @@
},
update: function(position) {
this.element.setStyle({
- left: this.options.x * position + this.originalLeft + 'px',
- top: this.options.y * position + this.originalTop + 'px'
+ left: Math.round(this.options.x * position + this.originalLeft) + 'px',
+ top: Math.round(this.options.y * position + this.originalTop) + 'px'
});
}
});
@@ -408,7 +429,8 @@
Effect.Scale = Class.create();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
initialize: function(element, percent) {
- this.element = $(element)
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
scaleX: true,
scaleY: true,
@@ -433,7 +455,7 @@
this.originalLeft = this.element.offsetLeft;
var fontSize = this.element.getStyle('font-size') || '100%';
- ['em','px','%'].each( function(fontSizeType) {
+ ['em','px','%','pt'].each( function(fontSizeType) {
if(fontSize.indexOf(fontSizeType)>0) {
this.fontSize = parseFloat(fontSize);
this.fontSizeType = fontSizeType;
@@ -458,12 +480,12 @@
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
},
finish: function(position) {
- if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
},
setDimensions: function(height, width) {
var d = {};
- if(this.options.scaleX) d.width = width + 'px';
- if(this.options.scaleY) d.height = height + 'px';
+ if(this.options.scaleX) d.width = Math.round(width) + 'px';
+ if(this.options.scaleY) d.height = Math.round(height) + 'px';
if(this.options.scaleFromCenter) {
var topd = (height - this.dims[0])/2;
var leftd = (width - this.dims[1])/2;
@@ -483,6 +505,7 @@
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
this.start(options);
},
@@ -547,8 +570,7 @@
to: 0.0,
afterFinishInternal: function(effect) {
if(effect.options.to!=0) return;
- effect.element.hide();
- effect.element.setStyle({opacity: oldOpacity});
+ effect.element.hide().setStyle({opacity: oldOpacity});
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
@@ -563,25 +585,31 @@
effect.element.forceRerendering();
},
beforeSetup: function(effect) {
- effect.element.setOpacity(effect.options.from);
- effect.element.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(), position: element.getStyle('position') };
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
return new Effect.Parallel(
[ new Effect.Scale(element, 200,
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) {
- effect.effects[0].element.setStyle({position: 'absolute'}); },
+ Position.absolutize(effect.effects[0].element)
+ },
afterFinishInternal: function(effect) {
- effect.effects[0].element.hide();
- effect.effects[0].element.setStyle(oldStyle); }
+ effect.effects[0].element.hide().setStyle(oldStyle); }
}, arguments[1] || {})
);
}
@@ -589,13 +617,12 @@
Effect.BlindUp = function(element) {
element = $(element);
element.makeClipping();
- return new Effect.Scale(element, 0,
+ return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
+ effect.element.hide().undoClipping();
}
}, arguments[1] || {})
);
@@ -604,28 +631,25 @@
Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100,
- Object.extend({ scaleContent: false,
- scaleX: false,
- scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function(effect) {
- effect.element.makeClipping();
- effect.element.setStyle({height: '0px'});
- effect.element.show();
- },
- afterFinishInternal: function(effect) {
- effect.element.undoClipping();
- }
- }, arguments[1] || {})
- );
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {}));
}
Effect.SwitchOff = function(element) {
element = $(element);
var oldOpacity = element.getInlineOpacity();
- return new Effect.Appear(element, {
+ return new Effect.Appear(element, Object.extend({
duration: 0.4,
from: 0,
transition: Effect.Transitions.flicker,
@@ -634,18 +658,14 @@
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
beforeSetup: function(effect) {
- effect.element.makePositioned();
- effect.element.makeClipping();
+ effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.undoPositioned();
- effect.element.setStyle({opacity: oldOpacity});
+ effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
})
}
- });
+ }, arguments[1] || {}));
}
Effect.DropOut = function(element) {
@@ -663,9 +683,7 @@
effect.effects[0].element.makePositioned();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.hide();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
+ effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
}
}, arguments[1] || {}));
}
@@ -687,54 +705,42 @@
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
- effect.element.undoPositioned();
- effect.element.setStyle(oldStyle);
+ effect.element.undoPositioned().setStyle(oldStyle);
}}) }}) }}) }}) }}) }});
}
Effect.SlideDown = function(element) {
- element = $(element);
- element.cleanWhitespace();
+ element = $(element).cleanWhitespace();
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
- scaleFrom: 0,
+ scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makePositioned();
- effect.element.firstChild.makePositioned();
+ effect.element.down().makePositioned();
if(window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping();
- effect.element.setStyle({height: '0px'});
- effect.element.show(); },
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
afterUpdateInternal: function(effect) {
- effect.element.firstChild.setStyle({bottom:
+ effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
- effect.element.undoClipping();
- // IE will crash if child is undoPositioned first
- if(/MSIE/.test(navigator.userAgent)){
- effect.element.undoPositioned();
- effect.element.firstChild.undoPositioned();
- }else{
- effect.element.firstChild.undoPositioned();
- effect.element.undoPositioned();
- }
- effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
+ effect.element.undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
}, arguments[1] || {})
);
}
-
+
Effect.SlideUp = function(element) {
- element = $(element);
- element.cleanWhitespace();
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
- return new Effect.Scale(element, 0,
+ element = $(element).cleanWhitespace();
+ var oldInnerBottom = element.down().getStyle('bottom');
+ return new Effect.Scale(element, window.opera ? 0 : 1,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
@@ -742,32 +748,32 @@
restoreAfterFinish: true,
beforeStartInternal: function(effect) {
effect.element.makePositioned();
- effect.element.firstChild.makePositioned();
+ effect.element.down().makePositioned();
if(window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping();
- effect.element.show(); },
+ effect.element.makeClipping().show();
+ },
afterUpdateInternal: function(effect) {
- effect.element.firstChild.setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.firstChild.undoPositioned();
- effect.element.undoPositioned();
- effect.element.setStyle({bottom: oldInnerBottom}); }
+ effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
+ effect.element.down().undoPositioned();
+ }
}, arguments[1] || {})
);
}
// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
- return new Effect.Scale(element, window.opera ? 1 : 0,
- { restoreAfterFinish: true,
- beforeSetup: function(effect) {
- effect.element.makeClipping(effect.element); },
- afterFinishInternal: function(effect) {
- effect.element.hide(effect.element);
- effect.element.undoClipping(effect.element); }
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
+ restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
});
}
@@ -823,9 +829,7 @@
y: initialMoveY,
duration: 0.01,
beforeSetup: function(effect) {
- effect.element.hide();
- effect.element.makeClipping();
- effect.element.makePositioned();
+ effect.element.hide().makeClipping().makePositioned();
},
afterFinishInternal: function(effect) {
new Effect.Parallel(
@@ -836,13 +840,10 @@
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) {
- effect.effects[0].element.setStyle({height: '0px'});
- effect.effects[0].element.show();
+ effect.effects[0].element.setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.undoClipping();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
)
@@ -896,13 +897,10 @@
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
], Object.extend({
beforeStartInternal: function(effect) {
- effect.effects[0].element.makePositioned();
- effect.effects[0].element.makeClipping(); },
+ effect.effects[0].element.makePositioned().makeClipping();
+ },
afterFinishInternal: function(effect) {
- effect.effects[0].element.hide();
- effect.effects[0].element.undoClipping();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle); }
+ effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
}, options)
);
}
@@ -912,10 +910,10 @@
var options = arguments[1] || {};
var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
reverser.bind(transition);
return new Effect.Opacity(element,
- Object.extend(Object.extend({ duration: 3.0, from: 0,
+ Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
}
@@ -927,7 +925,7 @@
left: element.style.left,
width: element.style.width,
height: element.style.height };
- Element.makeClipping(element);
+ element.makeClipping();
return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
scaleX: false,
@@ -936,15 +934,147 @@
scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.setStyle(oldStyle);
+ effect.element.hide().undoClipping().setStyle(oldStyle);
} });
}}, arguments[1] || {}));
};
+Effect.Morph = Class.create();
+Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ style: ''
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function(){
+ function parseColor(color){
+ if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+ color = color.parseColor();
+ return $R(0,2).map(function(i){
+ return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ });
+ }
+ this.transforms = this.options.style.parseStyle().map(function(property){
+ var originalValue = this.element.getStyle(property[0]);
+ return $H({
+ style: property[0],
+ originalValue: property[1].unit=='color' ?
+ parseColor(originalValue) : parseFloat(originalValue || 0),
+ targetValue: property[1].unit=='color' ?
+ parseColor(property[1].value) : property[1].value,
+ unit: property[1].unit
+ });
+ }.bind(this)).reject(function(transform){
+ return (
+ (transform.originalValue == transform.targetValue) ||
+ (
+ transform.unit != 'color' &&
+ (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+ )
+ )
+ });
+ },
+ update: function(position) {
+ var style = $H(), value = null;
+ this.transforms.each(function(transform){
+ value = transform.unit=='color' ?
+ $R(0,2).inject('#',function(m,v,i){
+ return m+(Math.round(transform.originalValue[i]+
+ (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) :
+ transform.originalValue + Math.round(
+ ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
+ style[transform.style] = value;
+ });
+ this.element.setStyle(style);
+ }
+});
+
+Effect.Transform = Class.create();
+Object.extend(Effect.Transform.prototype, {
+ initialize: function(tracks){
+ this.tracks = [];
+ this.options = arguments[1] || {};
+ this.addTracks(tracks);
+ },
+ addTracks: function(tracks){
+ tracks.each(function(track){
+ var data = $H(track).values().first();
+ this.tracks.push($H({
+ ids: $H(track).keys().first(),
+ effect: Effect.Morph,
+ options: { style: data }
+ }));
+ }.bind(this));
+ return this;
+ },
+ play: function(){
+ return new Effect.Parallel(
+ this.tracks.map(function(track){
+ var elements = [$(track.ids) || $$(track.ids)].flatten();
+ return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
+ }).flatten(),
+ this.options
+ );
+ }
+});
+
+Element.CSS_PROPERTIES = ['azimuth', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
+ 'backgroundPosition', 'backgroundRepeat', 'borderBottomColor', 'borderBottomStyle',
+ 'borderBottomWidth', 'borderCollapse', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth',
+ 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderSpacing', 'borderTopColor',
+ 'borderTopStyle', 'borderTopWidth', 'bottom', 'captionSide', 'clear', 'clip', 'color', 'content',
+ 'counterIncrement', 'counterReset', 'cssFloat', 'cueAfter', 'cueBefore', 'cursor', 'direction',
+ 'display', 'elevation', 'emptyCells', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
+ 'fontStyle', 'fontVariant', 'fontWeight', 'height', 'left', 'letterSpacing', 'lineHeight',
+ 'listStyleImage', 'listStylePosition', 'listStyleType', 'marginBottom', 'marginLeft', 'marginRight',
+ 'marginTop', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'opacity',
+ 'orphans', 'outlineColor', 'outlineOffset', 'outlineStyle', 'outlineWidth', 'overflowX', 'overflowY',
+ 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'page', 'pageBreakAfter', 'pageBreakBefore',
+ 'pageBreakInside', 'pauseAfter', 'pauseBefore', 'pitch', 'pitchRange', 'position', 'quotes',
+ 'richness', 'right', 'size', 'speakHeader', 'speakNumeral', 'speakPunctuation', 'speechRate', 'stress',
+ 'tableLayout', 'textAlign', 'textDecoration', 'textIndent', 'textShadow', 'textTransform', 'top',
+ 'unicodeBidi', 'verticalAlign', 'visibility', 'voiceFamily', 'volume', 'whiteSpace', 'widows',
+ 'width', 'wordSpacing', 'zIndex'];
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.prototype.parseStyle = function(){
+ var element = Element.extend(document.createElement('div'));
+ element.innerHTML = '<div style="' + this + '"></div>';
+ var style = element.down().style, styleRules = $H();
+
+ Element.CSS_PROPERTIES.each(function(property){
+ if(style[property]) styleRules[property] = style[property];
+ });
+
+ var result = $H();
+
+ styleRules.each(function(pair){
+ var property = pair[0], value = pair[1], unit = null;
+
+ if(value.parseColor('#zzzzzz') != '#zzzzzz') {
+ value = value.parseColor();
+ unit = 'color';
+ } else if(Element.CSS_LENGTH.test(value))
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
+ value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;
+
+ result[property.underscore().dasherize()] = $H({ value:value, unit:unit });
+ }.bind(this));
+
+ return result;
+};
+
+Element.morph = function(element, style) {
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
+ return element;
+};
+
['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
- 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
+ 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
function(f) { Element.Methods[f] = Element[f]; }
);
Modified: users/jberry/mpwa/public/javascripts/prototype.js
===================================================================
--- users/jberry/mpwa/public/javascripts/prototype.js 2007-04-07 21:27:37 UTC (rev 23728)
+++ users/jberry/mpwa/public/javascripts/prototype.js 2007-04-07 23:43:09 UTC (rev 23729)
@@ -1,5 +1,5 @@
-/* Prototype JavaScript framework, version 1.5.0_rc0
- * (c) 2005 Sam Stephenson <sam at conio.net>
+/* Prototype JavaScript framework, version 1.5.0
+ * (c) 2005-2007 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://prototype.conio.net/
@@ -7,11 +7,14 @@
/*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.5.0_rc0',
+ Version: '1.5.0',
+ BrowserFeatures: {
+ XPath: !!document.evaluate
+ },
+
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
-
emptyFunction: function() {},
- K: function(x) {return x}
+ K: function(x) { return x }
}
var Class = {
@@ -31,16 +34,36 @@
return destination;
}
-Object.inspect = function(object) {
- try {
- if (object == undefined) return 'undefined';
- if (object == null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- } catch (e) {
- if (e instanceof RangeError) return '...';
- throw e;
+Object.extend(Object, {
+ inspect: function(object) {
+ try {
+ if (object === undefined) return 'undefined';
+ if (object === null) return 'null';
+ return object.inspect ? object.inspect() : object.toString();
+ } catch (e) {
+ if (e instanceof RangeError) return '...';
+ throw e;
+ }
+ },
+
+ keys: function(object) {
+ var keys = [];
+ for (var property in object)
+ keys.push(property);
+ return keys;
+ },
+
+ values: function(object) {
+ var values = [];
+ for (var property in object)
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function(object) {
+ return Object.extend({}, object);
}
-}
+});
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
@@ -50,9 +73,9 @@
}
Function.prototype.bindAsEventListener = function(object) {
- var __method = this;
+ var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
- return __method.call(object, event || window.event);
+ return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
}
}
@@ -77,7 +100,7 @@
these: function() {
var returnValue;
- for (var i = 0; i < arguments.length; i++) {
+ for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
@@ -102,20 +125,30 @@
},
registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
+ stop: function() {
+ if (!this.timer) return;
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
- this.callback();
+ this.callback(this);
} finally {
this.currentlyExecuting = false;
}
}
}
}
+String.interpret = function(value){
+ return value == null ? '' : String(value);
+}
+
Object.extend(String.prototype, {
gsub: function(pattern, replacement) {
var result = '', source = this, match;
@@ -124,7 +157,7 @@
while (source.length > 0) {
if (match = source.match(pattern)) {
result += source.slice(0, match.index);
- result += (replacement(match) || '').toString();
+ result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
} else {
result += source, source = '';
@@ -189,15 +222,28 @@
unescapeHTML: function() {
var div = document.createElement('div');
div.innerHTML = this.stripTags();
- return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+ return div.childNodes[0] ? (div.childNodes.length > 1 ?
+ $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+ div.childNodes[0].nodeValue) : '';
},
- toQueryParams: function() {
- var pairs = this.match(/^\??(.*)$/)[1].split('&');
- return pairs.inject({}, function(params, pairString) {
- var pair = pairString.split('=');
- params[pair[0]] = pair[1];
- return params;
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return {};
+
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var name = decodeURIComponent(pair[0]);
+ var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+ if (hash[name] !== undefined) {
+ if (hash[name].constructor != Array)
+ hash[name] = [hash[name]];
+ if (value) hash[name].push(value);
+ }
+ else hash[name] = value;
+ }
+ return hash;
});
},
@@ -205,24 +251,43 @@
return this.split('');
},
+ succ: function() {
+ return this.slice(0, this.length - 1) +
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+ },
+
camelize: function() {
- var oStringList = this.split('-');
- if (oStringList.length == 1) return oStringList[0];
+ var parts = this.split('-'), len = parts.length;
+ if (len == 1) return parts[0];
- var camelizedString = this.indexOf('-') == 0
- ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
- : oStringList[0];
+ var camelized = this.charAt(0) == '-'
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+ : parts[0];
- for (var i = 1, len = oStringList.length; i < len; i++) {
- var s = oStringList[i];
- camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
- }
+ for (var i = 1; i < len; i++)
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
- return camelizedString;
+ return camelized;
},
- inspect: function() {
- return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'";
+ capitalize: function(){
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+ },
+
+ underscore: function() {
+ return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+ },
+
+ dasherize: function() {
+ return this.gsub(/_/,'-');
+ },
+
+ inspect: function(useDoubleQuotes) {
+ var escapedString = this.replace(/\\/g, '\\\\');
+ if (useDoubleQuotes)
+ return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ else
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}
});
@@ -246,7 +311,7 @@
return this.template.gsub(this.pattern, function(match) {
var before = match[1];
if (before == '\\') return match[2];
- return before + (object[match[3]] || '').toString();
+ return before + String.interpret(object[match[3]]);
});
}
}
@@ -268,8 +333,16 @@
} catch (e) {
if (e != $break) throw e;
}
+ return this;
},
+ eachSlice: function(number, iterator) {
+ var index = -number, slices = [], array = this.toArray();
+ while ((index += number) < array.length)
+ slices.push(array.slice(index, index+number));
+ return slices.map(iterator);
+ },
+
all: function(iterator) {
var result = true;
this.each(function(value, index) {
@@ -280,7 +353,7 @@
},
any: function(iterator) {
- var result = true;
+ var result = false;
this.each(function(value, index) {
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
@@ -291,12 +364,12 @@
collect: function(iterator) {
var results = [];
this.each(function(value, index) {
- results.push(iterator(value, index));
+ results.push((iterator || Prototype.K)(value, index));
});
return results;
},
- detect: function (iterator) {
+ detect: function(iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
@@ -337,6 +410,14 @@
return found;
},
+ inGroupsOf: function(number, fillWith) {
+ fillWith = fillWith === undefined ? null : fillWith;
+ return this.eachSlice(number, function(slice) {
+ while(slice.length < number) slice.push(fillWith);
+ return slice;
+ });
+ },
+
inject: function(memo, iterator) {
this.each(function(value, index) {
memo = iterator(memo, value, index);
@@ -346,7 +427,7 @@
invoke: function(method) {
var args = $A(arguments).slice(1);
- return this.collect(function(value) {
+ return this.map(function(value) {
return value[method].apply(value, args);
});
},
@@ -398,7 +479,7 @@
},
sortBy: function(iterator) {
- return this.collect(function(value, index) {
+ return this.map(function(value, index) {
return {value: value, criteria: iterator(value, index)};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
@@ -407,7 +488,7 @@
},
toArray: function() {
- return this.collect(Prototype.K);
+ return this.map();
},
zip: function() {
@@ -421,6 +502,10 @@
});
},
+ size: function() {
+ return this.toArray().length;
+ },
+
inspect: function() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
@@ -439,7 +524,7 @@
return iterable.toArray();
} else {
var results = [];
- for (var i = 0; i < iterable.length; i++)
+ for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
@@ -452,7 +537,7 @@
Object.extend(Array.prototype, {
_each: function(iterator) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
},
@@ -471,7 +556,7 @@
compact: function() {
return this.select(function(value) {
- return value != undefined || value != null;
+ return value != null;
});
},
@@ -490,7 +575,7 @@
},
indexOf: function(object) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
if (this[i] == object) return i;
return -1;
},
@@ -499,15 +584,88 @@
return (inline !== false ? this : this.toArray())._reverse();
},
+ reduce: function() {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function() {
+ return this.inject([], function(array, value) {
+ return array.include(value) ? array : array.concat([value]);
+ });
+ },
+
+ clone: function() {
+ return [].concat(this);
+ },
+
+ size: function() {
+ return this.length;
+ },
+
inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
});
-var Hash = {
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
+}
+
+if(window.opera){
+ Array.prototype.concat = function(){
+ var array = [];
+ for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ for(var i = 0, length = arguments.length; i < length; i++) {
+ if(arguments[i].constructor == Array) {
+ for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+ array.push(arguments[i][j]);
+ } else {
+ array.push(arguments[i]);
+ }
+ }
+ return array;
+ }
+}
+var Hash = function(obj) {
+ Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+ toQueryString: function(obj) {
+ var parts = [];
+
+ this.prototype._each.call(obj, function(pair) {
+ if (!pair.key) return;
+
+ if (pair.value && pair.value.constructor == Array) {
+ var values = pair.value.compact();
+ if (values.length < 2) pair.value = values.reduce();
+ else {
+ key = encodeURIComponent(pair.key);
+ values.each(function(value) {
+ value = value != undefined ? encodeURIComponent(value) : '';
+ parts.push(key + '=' + encodeURIComponent(value));
+ });
+ return;
+ }
+ }
+ if (pair.value == undefined) pair[1] = '';
+ parts.push(pair.map(encodeURIComponent).join('='));
+ });
+
+ return parts.join('&');
+ }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
_each: function(iterator) {
for (var key in this) {
var value = this[key];
- if (typeof value == 'function') continue;
+ if (value && value == Hash.prototype[key]) continue;
var pair = [key, value];
pair.key = key;
@@ -525,16 +683,30 @@
},
merge: function(hash) {
- return $H(hash).inject($H(this), function(mergedHash, pair) {
+ return $H(hash).inject(this, function(mergedHash, pair) {
mergedHash[pair.key] = pair.value;
return mergedHash;
});
},
+ remove: function() {
+ var result;
+ for(var i = 0, length = arguments.length; i < length; i++) {
+ var value = this[arguments[i]];
+ if (value !== undefined){
+ if (result === undefined) result = value;
+ else {
+ if (result.constructor != Array) result = [result];
+ result.push(value)
+ }
+ }
+ delete this[arguments[i]];
+ }
+ return result;
+ },
+
toQueryString: function() {
- return this.map(function(pair) {
- return pair.map(encodeURIComponent).join('=');
- }).join('&');
+ return Hash.toQueryString(this);
},
inspect: function() {
@@ -542,14 +714,12 @@
return pair.map(Object.inspect).join(': ');
}).join(', ') + '}>';
}
-}
+});
function $H(object) {
- var hash = Object.extend({}, object || {});
- Object.extend(hash, Enumerable);
- Object.extend(hash, Hash);
- return hash;
-}
+ if (object && object.constructor == Hash) return object;
+ return new Hash(object);
+};
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
@@ -561,10 +731,10 @@
_each: function(iterator) {
var value = this.start;
- do {
+ while (this.include(value)) {
iterator(value);
value = value.succ();
- } while (this.include(value));
+ }
},
include: function(value) {
@@ -599,18 +769,18 @@
this.responders._each(iterator);
},
- register: function(responderToAdd) {
- if (!this.include(responderToAdd))
- this.responders.push(responderToAdd);
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
},
- unregister: function(responderToRemove) {
- this.responders = this.responders.without(responderToRemove);
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
- if (responder[callback] && typeof responder[callback] == 'function') {
+ if (typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}
@@ -625,7 +795,6 @@
onCreate: function() {
Ajax.activeRequestCount++;
},
-
onComplete: function() {
Ajax.activeRequestCount--;
}
@@ -638,19 +807,14 @@
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
parameters: ''
}
Object.extend(this.options, options || {});
- },
- responseIsSuccess: function() {
- return this.transport.status == undefined
- || this.transport.status == 0
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- responseIsFailure: function() {
- return !this.responseIsSuccess();
+ this.options.method = this.options.method.toLowerCase();
+ if (typeof this.options.parameters == 'string')
+ this.options.parameters = this.options.parameters.toQueryParams();
}
}
@@ -659,6 +823,8 @@
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ _complete: false,
+
initialize: function(url, options) {
this.transport = Ajax.getTransport();
this.setOptions(options);
@@ -666,113 +832,148 @@
},
request: function(url) {
- var parameters = this.options.parameters || '';
- if (parameters.length > 0) parameters += '&_=';
+ this.url = url;
+ this.method = this.options.method;
+ var params = this.options.parameters;
+ if (!['get', 'post'].include(this.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.method;
+ this.method = 'post';
+ }
+
+ params = Hash.toQueryString(params);
+ if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+
+ // when GET, append parameters to URL
+ if (this.method == 'get' && params)
+ this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
try {
- this.url = url;
- if (this.options.method == 'get' && parameters.length > 0)
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
-
Ajax.Responders.dispatch('onCreate', this, this.transport);
- this.transport.open(this.options.method, this.url,
+ this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
- if (this.options.asynchronous) {
- this.transport.onreadystatechange = this.onStateChange.bind(this);
- setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
- }
+ if (this.options.asynchronous)
+ setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
+ var body = this.method == 'post' ? (this.options.postBody || params) : null;
- } catch (e) {
+ this.transport.send(body);
+
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
+ this.onStateChange();
+
+ }
+ catch (e) {
this.dispatchException(e);
}
},
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1 && !((readyState == 4) && this._complete))
+ this.respondToReadyState(this.transport.readyState);
+ },
+
setRequestHeaders: function() {
- var requestHeaders =
- ['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version,
- 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
- if (this.options.method == 'post') {
- requestHeaders.push('Content-type', this.options.contentType);
+ if (this.method == 'post') {
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
- /* Force "Connection: close" for Mozilla browsers to work around
- * a bug where XMLHttpReqeuest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
*/
- if (this.transport.overrideMimeType)
- requestHeaders.push('Connection', 'close');
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
}
- if (this.options.requestHeaders)
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
- for (var i = 0; i < requestHeaders.length; i += 2)
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
- },
+ if (typeof extras.push == 'function')
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
- onStateChange: function() {
- var readyState = this.transport.readyState;
- if (readyState != 1)
- this.respondToReadyState(this.transport.readyState);
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
},
- header: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) {}
+ success: function() {
+ return !this.transport.status
+ || (this.transport.status >= 200 && this.transport.status < 300);
},
- evalJSON: function() {
- try {
- return eval('(' + this.header('X-JSON') + ')');
- } catch (e) {}
- },
-
- evalResponse: function() {
- try {
- return eval(this.transport.responseText);
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
respondToReadyState: function(readyState) {
- var event = Ajax.Request.Events[readyState];
+ var state = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
- if (event == 'Complete') {
+ if (state == 'Complete') {
try {
+ this._complete = true;
(this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
} catch (e) {
this.dispatchException(e);
}
- if ((this.header('Content-type') || '').match(/^text\/javascript/i))
- this.evalResponse();
+ if ((this.getHeader('Content-type') || 'text/javascript').strip().
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+ this.evalResponse();
}
try {
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
} catch (e) {
this.dispatchException(e);
}
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete')
+ if (state == 'Complete') {
+ // avoid memory leak in MSIE: clean up
this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
},
+ getHeader: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) { return null }
+ },
+
+ evalJSON: function() {
+ try {
+ var json = this.getHeader('X-JSON');
+ return json ? eval('(' + json + ')') : null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
dispatchException: function(exception) {
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch('onException', this, exception);
@@ -783,41 +984,37 @@
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
- this.containers = {
- success: container.success ? $(container.success) : $(container),
- failure: container.failure ? $(container.failure) :
- (container.success ? null : $(container))
+ this.container = {
+ success: (container.success || container),
+ failure: (container.failure || (container.success ? null : container))
}
this.transport = Ajax.getTransport();
this.setOptions(options);
var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, object) {
+ this.options.onComplete = (function(transport, param) {
this.updateContent();
- onComplete(transport, object);
+ onComplete(transport, param);
}).bind(this);
this.request(url);
},
updateContent: function() {
- var receiver = this.responseIsSuccess() ?
- this.containers.success : this.containers.failure;
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
var response = this.transport.responseText;
- if (!this.options.evalScripts)
- response = response.stripScripts();
+ if (!this.options.evalScripts) response = response.stripScripts();
- if (receiver) {
- if (this.options.insertion) {
+ if (receiver = $(receiver)) {
+ if (this.options.insertion)
new this.options.insertion(receiver, response);
- } else {
- Element.update(receiver, response);
- }
+ else
+ receiver.update(response);
}
- if (this.responseIsSuccess()) {
+ if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
@@ -846,7 +1043,7 @@
},
stop: function() {
- this.updater.onComplete = undefined;
+ this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
@@ -866,25 +1063,43 @@
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
-function $() {
- var results = [], element;
- for (var i = 0; i < arguments.length; i++) {
- element = arguments[i];
- if (typeof element == 'string')
- element = document.getElementById(element);
- results.push(Element.extend(element));
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
}
- return results.length < 2 ? results[0] : results;
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ return Element.extend(element);
}
+if (Prototype.BrowserFeatures.XPath) {
+ document._getElementsByXPath = function(expression, parentElement) {
+ var results = [];
+ var query = document.evaluate(expression, $(parentElement) || document,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
+ results.push(query.snapshotItem(i));
+ return results;
+ };
+}
+
document.getElementsByClassName = function(className, parentElement) {
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- return $A(children).inject([], function(elements, child) {
- if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- elements.push(Element.extend(child));
+ if (Prototype.BrowserFeatures.XPath) {
+ var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+ return document._getElementsByXPath(q, parentElement);
+ } else {
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ var elements = [], child;
+ for (var i = 0, length = children.length; i < length; i++) {
+ child = children[i];
+ if (Element.hasClassName(child, className))
+ elements.push(Element.extend(child));
+ }
return elements;
- });
-}
+ }
+};
/*--------------------------------------------------------------------------*/
@@ -892,21 +1107,28 @@
var Element = new Object();
Element.extend = function(element) {
- if (!element) return;
- if (_nativeExtensions) return element;
+ if (!element || _nativeExtensions || element.nodeType == 3) return element;
if (!element._extended && element.tagName && element != window) {
- var methods = Element.Methods, cache = Element.extend.cache;
- for (property in methods) {
+ var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+ if (element.tagName == 'FORM')
+ Object.extend(methods, Form.Methods);
+ if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+ Object.extend(methods, Form.Element.Methods);
+
+ Object.extend(methods, Element.Methods.Simulated);
+
+ for (var property in methods) {
var value = methods[property];
- if (typeof value == 'function')
+ if (typeof value == 'function' && !(property in element))
element[property] = cache.findOrStore(value);
}
}
element._extended = true;
return element;
-}
+};
Element.extend.cache = {
findOrStore: function(value) {
@@ -914,46 +1136,45 @@
return value.apply(null, [this].concat($A(arguments)));
}
}
-}
+};
Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
},
- toggle: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- Element[Element.visible(element) ? 'hide' : 'show'](element);
- }
+ toggle: function(element) {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
},
- hide: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- element.style.display = 'none';
- }
+ hide: function(element) {
+ $(element).style.display = 'none';
+ return element;
},
- show: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- element.style.display = '';
- }
+ show: function(element) {
+ $(element).style.display = '';
+ return element;
},
remove: function(element) {
element = $(element);
element.parentNode.removeChild(element);
+ return element;
},
update: function(element, html) {
+ html = typeof html == 'undefined' ? '' : html.toString();
$(element).innerHTML = html.stripScripts();
setTimeout(function() {html.evalScripts()}, 10);
+ return element;
},
replace: function(element, html) {
element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
if (element.outerHTML) {
element.outerHTML = html.stripScripts();
} else {
@@ -963,47 +1184,168 @@
range.createContextualFragment(html.stripScripts()), element);
}
setTimeout(function() {html.evalScripts()}, 10);
+ return element;
},
- getHeight: function(element) {
+ inspect: function(element) {
element = $(element);
- return element.offsetHeight;
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
},
+ recursivelyCollect: function(element, property) {
+ element = $(element);
+ var elements = [];
+ while (element = element[property])
+ if (element.nodeType == 1)
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function(element) {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function(element) {
+ return $A($(element).getElementsByTagName('*'));
+ },
+
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
+ previousSiblings: function(element) {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function(element) {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function(element) {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function(element, selector) {
+ if (typeof selector == 'string')
+ selector = new Selector(selector);
+ return selector.match($(element));
+ },
+
+ up: function(element, expression, index) {
+ return Selector.findElement($(element).ancestors(), expression, index);
+ },
+
+ down: function(element, expression, index) {
+ return Selector.findElement($(element).descendants(), expression, index);
+ },
+
+ previous: function(element, expression, index) {
+ return Selector.findElement($(element).previousSiblings(), expression, index);
+ },
+
+ next: function(element, expression, index) {
+ return Selector.findElement($(element).nextSiblings(), expression, index);
+ },
+
+ getElementsBySelector: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ getElementsByClassName: function(element, className) {
+ return document.getElementsByClassName(className, element);
+ },
+
+ readAttribute: function(element, name) {
+ element = $(element);
+ if (document.all && !window.opera) {
+ var t = Element._attributeTranslations;
+ if (t.values[name]) return t.values[name](element, name);
+ if (t.names[name]) name = t.names[name];
+ var attribute = element.attributes[name];
+ if(attribute) return attribute.nodeValue;
+ }
+ return element.getAttribute(name);
+ },
+
+ getHeight: function(element) {
+ return $(element).getDimensions().height;
+ },
+
+ getWidth: function(element) {
+ return $(element).getDimensions().width;
+ },
+
classNames: function(element) {
return new Element.ClassNames(element);
},
hasClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).include(className);
+ var elementClassName = element.className;
+ if (elementClassName.length == 0) return false;
+ if (elementClassName == className ||
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ return true;
+ return false;
},
addClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).add(className);
+ Element.classNames(element).add(className);
+ return element;
},
removeClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).remove(className);
+ Element.classNames(element).remove(className);
+ return element;
},
+ toggleClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+ return element;
+ },
+
+ observe: function() {
+ Event.observe.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ stopObserving: function() {
+ Event.stopObserving.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
// removes whitespace-only text node children
cleanWhitespace: function(element) {
element = $(element);
- for (var i = 0; i < element.childNodes.length; i++) {
- var node = element.childNodes[i];
+ var node = element.firstChild;
+ while (node) {
+ var nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
- Element.remove(node);
+ element.removeChild(node);
+ node = nextNode;
}
+ return element;
},
empty: function(element) {
return $(element).innerHTML.match(/^\s*$/);
},
- childOf: function(element, ancestor) {
+ descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
while (element = element.parentNode)
if (element == ancestor) return true;
@@ -1012,38 +1354,69 @@
scrollTo: function(element) {
element = $(element);
- var x = element.x ? element.x : element.offsetLeft,
- y = element.y ? element.y : element.offsetTop;
- window.scrollTo(x, y);
+ var pos = Position.cumulativeOffset(element);
+ window.scrollTo(pos[0], pos[1]);
+ return element;
},
getStyle: function(element, style) {
element = $(element);
- var value = element.style[style.camelize()];
+ if (['float','cssFloat'].include(style))
+ style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+ style = style.camelize();
+ var value = element.style[style];
if (!value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css.getPropertyValue(style) : null;
+ value = css ? css[style] : null;
} else if (element.currentStyle) {
- value = element.currentStyle[style.camelize()];
+ value = element.currentStyle[style];
}
}
+ if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+ value = element['offset'+style.capitalize()] + 'px';
+
if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
if (Element.getStyle(element, 'position') == 'static') value = 'auto';
-
+ if(style == 'opacity') {
+ if(value) return parseFloat(value);
+ if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if(value[1]) return parseFloat(value[1]) / 100;
+ return 1.0;
+ }
return value == 'auto' ? null : value;
},
setStyle: function(element, style) {
element = $(element);
- for (var name in style)
- element.style[name.camelize()] = style[name];
+ for (var name in style) {
+ var value = style[name];
+ if(name == 'opacity') {
+ if (value == 1) {
+ value = (/Gecko/.test(navigator.userAgent) &&
+ !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+ } else if(value == '') {
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+ } else {
+ if(value < 0.00001) value = 0;
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+ 'alpha(opacity='+value*100+')';
+ }
+ } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+ element.style[name.camelize()] = value;
+ }
+ return element;
},
getDimensions: function(element) {
element = $(element);
- if (Element.getStyle(element, 'display') != 'none')
+ var display = $(element).getStyle('display');
+ if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
// All *Width and *Height properties give 0 on elements with display none,
@@ -1051,12 +1424,13 @@
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
+ var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
- els.display = '';
+ els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
- els.display = 'none';
+ els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
@@ -1075,6 +1449,7 @@
element.style.left = 0;
}
}
+ return element;
},
undoPositioned: function(element) {
@@ -1087,49 +1462,153 @@
element.style.bottom =
element.style.right = '';
}
+ return element;
},
makeClipping: function(element) {
element = $(element);
- if (element._overflow) return;
- element._overflow = element.style.overflow;
+ if (element._overflow) return element;
+ element._overflow = element.style.overflow || 'auto';
if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
element.style.overflow = 'hidden';
+ return element;
},
undoClipping: function(element) {
element = $(element);
- if (element._overflow) return;
- element.style.overflow = element._overflow;
- element._overflow = undefined;
+ if (!element._overflow) return element;
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+ element._overflow = null;
+ return element;
}
-}
+};
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+ colspan: "colSpan",
+ rowspan: "rowSpan",
+ valign: "vAlign",
+ datetime: "dateTime",
+ accesskey: "accessKey",
+ tabindex: "tabIndex",
+ enctype: "encType",
+ maxlength: "maxLength",
+ readonly: "readOnly",
+ longdesc: "longDesc"
+};
+
+Element._attributeTranslations.values = {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+
+ title: function(element) {
+ var node = element.getAttributeNode('title');
+ return node.specified ? node.nodeValue : null;
+ }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+ href: Element._attributeTranslations.values._getAttr,
+ src: Element._attributeTranslations.values._getAttr,
+ disabled: Element._attributeTranslations.values._flag,
+ checked: Element._attributeTranslations.values._flag,
+ readonly: Element._attributeTranslations.values._flag,
+ multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ var t = Element._attributeTranslations;
+ attribute = t.names[attribute] || attribute;
+ return $(element).getAttributeNode(attribute).specified;
+ }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+ Element.Methods.update = function(element, html) {
+ element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
+ var tagName = element.tagName.toUpperCase();
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+ var div = document.createElement('div');
+ switch (tagName) {
+ case 'THEAD':
+ case 'TBODY':
+ div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
+ depth = 2;
+ break;
+ case 'TR':
+ div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
+ depth = 3;
+ break;
+ case 'TD':
+ div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
+ depth = 4;
+ }
+ $A(element.childNodes).each(function(node){
+ element.removeChild(node)
+ });
+ depth.times(function(){ div = div.firstChild });
+
+ $A(div.childNodes).each(
+ function(node){ element.appendChild(node) });
+ } else {
+ element.innerHTML = html.stripScripts();
+ }
+ setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ }
+};
+
Object.extend(Element, Element.Methods);
var _nativeExtensions = false;
-if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- var HTMLElement = {}
- HTMLElement.prototype = document.createElement('div').__proto__;
-}
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+ var className = 'HTML' + tag + 'Element';
+ if(window[className]) return;
+ var klass = window[className] = {};
+ klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+ });
Element.addMethods = function(methods) {
Object.extend(Element.Methods, methods || {});
- if(typeof HTMLElement != 'undefined') {
- var methods = Element.Methods, cache = Element.extend.cache;
- for (property in methods) {
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
+ var cache = Element.extend.cache;
+ for (var property in methods) {
var value = methods[property];
- if (typeof value == 'function')
- HTMLElement.prototype[property] = cache.findOrStore(value);
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = cache.findOrStore(value);
}
+ }
+
+ if (typeof HTMLElement != 'undefined') {
+ copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ copy(Form.Methods, HTMLFormElement.prototype);
+ [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+ copy(Form.Element.Methods, klass.prototype);
+ });
_nativeExtensions = true;
}
}
-Element.addMethods();
-
var Toggle = new Object();
Toggle.display = Element.toggle;
@@ -1148,8 +1627,8 @@
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
- var tagName = this.element.tagName.toLowerCase();
- if (tagName == 'tbody' || tagName == 'tr') {
+ var tagName = this.element.tagName.toUpperCase();
+ if (['TBODY', 'TR'].include(tagName)) {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
@@ -1248,20 +1727,18 @@
add: function(classNameToAdd) {
if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
+ this.set($A(this).concat(classNameToAdd).join(' '));
},
remove: function(classNameToRemove) {
if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
+ this.set($A(this).without(classNameToRemove).join(' '));
},
toString: function() {
- return this.toArray().join(' ');
+ return $A(this).join(' ');
}
-}
+};
Object.extend(Element.ClassNames.prototype, Enumerable);
var Selector = Class.create();
@@ -1308,15 +1785,15 @@
if (params.wildcard)
conditions.push('true');
if (clause = params.id)
- conditions.push('element.id == ' + clause.inspect());
+ conditions.push('element.readAttribute("id") == ' + clause.inspect());
if (clause = params.tagName)
conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
if ((clause = params.classNames).length > 0)
- for (var i = 0; i < clause.length; i++)
- conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
+ for (var i = 0, length = clause.length; i < length; i++)
+ conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
if (clause = params.attributes) {
clause.each(function(attribute) {
- var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
+ var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
var splitValueBy = function(delimiter) {
return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
}
@@ -1329,7 +1806,7 @@
); break;
case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
case '':
- case undefined: conditions.push(value + ' != null'); break;
+ case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
default: throw 'Unknown operator ' + attribute.operator + ' in selector';
}
});
@@ -1340,6 +1817,7 @@
compileMatcher: function() {
this.match = new Function('element', 'if (!element.tagName) return false; \
+ element = $(element); \
return ' + this.buildMatchExpression());
},
@@ -1354,7 +1832,7 @@
scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
var results = [];
- for (var i = 0; i < scope.length; i++)
+ for (var i = 0, length = scope.length; i < length; i++)
if (this.match(element = scope[i]))
results.push(Element.extend(element));
@@ -1366,206 +1844,241 @@
}
}
-function $$() {
- return $A(arguments).map(function(expression) {
- return expression.strip().split(/\s+/).inject([null], function(results, expr) {
- var selector = new Selector(expr);
- return results.map(selector.findElements.bind(selector)).flatten();
- });
- }).flatten();
-}
-var Field = {
- clear: function() {
- for (var i = 0; i < arguments.length; i++)
- $(arguments[i]).value = '';
+Object.extend(Selector, {
+ matchElements: function(elements, expression) {
+ var selector = new Selector(expression);
+ return elements.select(selector.match.bind(selector)).map(Element.extend);
},
- focus: function(element) {
- $(element).focus();
+ findElement: function(elements, expression, index) {
+ if (typeof expression == 'number') index = expression, expression = false;
+ return Selector.matchElements(elements, expression || '*')[index || 0];
},
- present: function() {
- for (var i = 0; i < arguments.length; i++)
- if ($(arguments[i]).value == '') return false;
- return true;
- },
+ findChildElements: function(element, expressions) {
+ return expressions.map(function(expression) {
+ return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+ var selector = new Selector(expr);
+ return results.inject([], function(elements, result) {
+ return elements.concat(selector.findElements(result || element));
+ });
+ });
+ }).flatten();
+ }
+});
- select: function(element) {
- $(element).select();
+function $$() {
+ return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+ reset: function(form) {
+ $(form).reset();
+ return form;
},
- activate: function(element) {
- element = $(element);
- element.focus();
- if (element.select)
- element.select();
+ serializeElements: function(elements, getHash) {
+ var data = elements.inject({}, function(result, element) {
+ if (!element.disabled && element.name) {
+ var key = element.name, value = $(element).getValue();
+ if (value != undefined) {
+ if (result[key]) {
+ if (result[key].constructor != Array) result[key] = [result[key]];
+ result[key].push(value);
+ }
+ else result[key] = value;
+ }
+ }
+ return result;
+ });
+
+ return getHash ? data : Hash.toQueryString(data);
}
-}
+};
-/*--------------------------------------------------------------------------*/
-
-var Form = {
- serialize: function(form) {
- var elements = Form.getElements($(form));
- var queryComponents = new Array();
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
+Form.Methods = {
+ serialize: function(form, getHash) {
+ return Form.serializeElements(Form.getElements(form), getHash);
},
getElements: function(form) {
- form = $(form);
- var elements = new Array();
-
- for (var tagName in Form.Element.Serializers) {
- var tagElements = form.getElementsByTagName(tagName);
- for (var j = 0; j < tagElements.length; j++)
- elements.push(tagElements[j]);
- }
- return elements;
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
},
getInputs: function(form, typeName, name) {
form = $(form);
var inputs = form.getElementsByTagName('input');
- if (!typeName && !name)
- return inputs;
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
- var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
var input = inputs[i];
- if ((typeName && input.type != typeName) ||
- (name && input.name != name))
+ if ((typeName && input.type != typeName) || (name && input.name != name))
continue;
- matchingInputs.push(input);
+ matchingInputs.push(Element.extend(input));
}
return matchingInputs;
},
disable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form = $(form);
+ form.getElements().each(function(element) {
element.blur();
element.disabled = 'true';
- }
+ });
+ return form;
},
enable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form = $(form);
+ form.getElements().each(function(element) {
element.disabled = '';
- }
+ });
+ return form;
},
findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
+ return $(form).getElements().find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
},
focusFirstElement: function(form) {
- Field.activate(Form.findFirstElement(form));
+ form = $(form);
+ form.findFirstElement().activate();
+ return form;
+ }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+ focus: function(element) {
+ $(element).focus();
+ return element;
},
- reset: function(form) {
- $(form).reset();
+ select: function(element) {
+ $(element).select();
+ return element;
}
}
-Form.Element = {
+Form.Element.Methods = {
serialize: function(element) {
element = $(element);
+ if (!element.disabled && element.name) {
+ var value = element.getValue();
+ if (value != undefined) {
+ var pair = {};
+ pair[element.name] = value;
+ return Hash.toQueryString(pair);
+ }
+ }
+ return '';
+ },
+
+ getValue: function(element) {
+ element = $(element);
var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
+ return Form.Element.Serializers[method](element);
+ },
- if (parameter) {
- var key = encodeURIComponent(parameter[0]);
- if (key.length == 0) return;
+ clear: function(element) {
+ $(element).value = '';
+ return element;
+ },
- if (parameter[1].constructor != Array)
- parameter[1] = [parameter[1]];
+ present: function(element) {
+ return $(element).value != '';
+ },
- return parameter[1].map(function(value) {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
- }
+ activate: function(element) {
+ element = $(element);
+ element.focus();
+ if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+ !['button', 'reset', 'submit'].include(element.type) ) )
+ element.select();
+ return element;
},
- getValue: function(element) {
+ disable: function(element) {
element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
+ element.disabled = true;
+ return element;
+ },
- if (parameter)
- return parameter[1];
+ enable: function(element) {
+ element = $(element);
+ element.blur();
+ element.disabled = false;
+ return element;
}
}
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
Form.Element.Serializers = {
input: function(element) {
switch (element.type.toLowerCase()) {
- case 'submit':
- case 'hidden':
- case 'password':
- case 'text':
- return Form.Element.Serializers.textarea(element);
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element);
+ default:
+ return Form.Element.Serializers.textarea(element);
}
- return false;
},
inputSelector: function(element) {
- if (element.checked)
- return [element.name, element.value];
+ return element.checked ? element.value : null;
},
textarea: function(element) {
- return [element.name, element.value];
+ return element.value;
},
select: function(element) {
- return Form.Element.Serializers[element.type == 'select-one' ?
+ return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
},
selectOne: function(element) {
- var value = '', opt, index = element.selectedIndex;
- if (index >= 0) {
- opt = element.options[index];
- value = opt.value || opt.text;
- }
- return [element.name, value];
+ var index = element.selectedIndex;
+ return index >= 0 ? this.optionValue(element.options[index]) : null;
},
selectMany: function(element) {
- var value = [];
- for (var i = 0; i < element.length; i++) {
+ var values, length = element.length;
+ if (!length) return null;
+
+ for (var i = 0, values = []; i < length; i++) {
var opt = element.options[i];
- if (opt.selected)
- value.push(opt.value || opt.text);
+ if (opt.selected) values.push(this.optionValue(opt));
}
- return [element.name, value];
+ return values;
+ },
+
+ optionValue: function(opt) {
+ // extend element because hasAttribute may not be native
+ return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
}
/*--------------------------------------------------------------------------*/
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
initialize: function(element, frequency, callback) {
@@ -1583,7 +2096,9 @@
onTimerEvent: function() {
var value = this.getValue();
- if (this.lastValue != value) {
+ var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+ ? this.lastValue != value : String(this.lastValue) != String(value));
+ if (changed) {
this.callback(this.element, value);
this.lastValue = value;
}
@@ -1628,9 +2143,7 @@
},
registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
},
registerCallback: function(element) {
@@ -1640,11 +2153,7 @@
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
- case 'password':
- case 'text':
- case 'textarea':
- case 'select-one':
- case 'select-multiple':
+ default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
@@ -1679,6 +2188,10 @@
KEY_RIGHT: 39,
KEY_DOWN: 40,
KEY_DELETE: 46,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
element: function(event) {
return event.target || event.srcElement;
@@ -1734,7 +2247,7 @@
unloadCache: function() {
if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
+ for (var i = 0, length = Event.observers.length; i < length; i++) {
Event.stopObserving.apply(this, Event.observers[i]);
Event.observers[i][0] = null;
}
@@ -1742,7 +2255,7 @@
},
observe: function(element, name, observer, useCapture) {
- var element = $(element);
+ element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
@@ -1750,11 +2263,11 @@
|| element.attachEvent))
name = 'keydown';
- this._observeAndCache(element, name, observer, useCapture);
+ Event._observeAndCache(element, name, observer, useCapture);
},
stopObserving: function(element, name, observer, useCapture) {
- var element = $(element);
+ element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
@@ -1765,7 +2278,9 @@
if (element.removeEventListener) {
element.removeEventListener(name, observer, useCapture);
} else if (element.detachEvent) {
- element.detachEvent('on' + name, observer);
+ try {
+ element.detachEvent('on' + name, observer);
+ } catch (e) {}
}
}
});
@@ -1819,7 +2334,8 @@
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
- p = Element.getStyle(element, 'position');
+ if(element.tagName=='BODY') break;
+ var p = Element.getStyle(element, 'position');
if (p == 'relative' || p == 'absolute') break;
}
} while (element);
@@ -1875,17 +2391,6 @@
element.offsetWidth;
},
- clone: function(source, target) {
- source = $(source);
- target = $(target);
- target.style.position = 'absolute';
- var offsets = this.cumulativeOffset(source);
- target.style.top = offsets[1] + 'px';
- target.style.left = offsets[0] + 'px';
- target.style.width = source.offsetWidth + 'px';
- target.style.height = source.offsetHeight + 'px';
- },
-
page: function(forElement) {
var valueT = 0, valueL = 0;
@@ -1902,8 +2407,10 @@
element = forElement;
do {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
+ if (!window.opera || element.tagName=='BODY') {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ }
} while (element = element.parentNode);
return [valueL, valueT];
@@ -1964,10 +2471,10 @@
element._originalHeight = element.style.height;
element.style.position = 'absolute';
- element.style.top = top + 'px';;
- element.style.left = left + 'px';;
- element.style.width = width + 'px';;
- element.style.height = height + 'px';;
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.width = width + 'px';
+ element.style.height = height + 'px';
},
relativize: function(element) {
@@ -2003,4 +2510,6 @@
return [valueL, valueT];
}
-}
\ No newline at end of file
+}
+
+Element.addMethods();
\ No newline at end of file
Added: users/jberry/mpwa/public/stylesheets/scaffold.css
===================================================================
--- users/jberry/mpwa/public/stylesheets/scaffold.css (rev 0)
+++ users/jberry/mpwa/public/stylesheets/scaffold.css 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,74 @@
+body { background-color: #fff; color: #333; }
+
+body, p, ol, ul, td {
+ font-family: verdana, arial, helvetica, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+}
+
+pre {
+ background-color: #eee;
+ padding: 10px;
+ font-size: 11px;
+}
+
+a { color: #000; }
+a:visited { color: #666; }
+a:hover { color: #fff; background-color:#000; }
+
+.fieldWithErrors {
+ padding: 2px;
+ background-color: red;
+ display: table;
+}
+
+#errorExplanation {
+ width: 400px;
+ border: 2px solid red;
+ padding: 7px;
+ padding-bottom: 12px;
+ margin-bottom: 20px;
+ background-color: #f0f0f0;
+}
+
+#errorExplanation h2 {
+ text-align: left;
+ font-weight: bold;
+ padding: 5px 5px 5px 15px;
+ font-size: 12px;
+ margin: -7px;
+ background-color: #c00;
+ color: #fff;
+}
+
+#errorExplanation p {
+ color: #333;
+ margin-bottom: 0;
+ padding: 5px;
+}
+
+#errorExplanation ul li {
+ font-size: 12px;
+ list-style: square;
+}
+
+div.uploadStatus {
+ margin: 5px;
+}
+
+div.progressBar {
+ margin: 5px;
+}
+
+div.progressBar div.border {
+ background-color: #fff;
+ border: 1px solid grey;
+ width: 100%;
+}
+
+div.progressBar div.background {
+ background-color: #333;
+ height: 18px;
+ width: 0%;
+}
+
Added: users/jberry/mpwa/script/process/inspector
===================================================================
--- users/jberry/mpwa/script/process/inspector (rev 0)
+++ users/jberry/mpwa/script/process/inspector 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+require File.dirname(__FILE__) + '/../../config/boot'
+require 'commands/process/inspector'
Property changes on: users/jberry/mpwa/script/process/inspector
___________________________________________________________________
Name: svn:executable
+ *
Added: users/jberry/mpwa/test/fixtures/people.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/people.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/people.yml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/fixtures/port_pkgs.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/port_pkgs.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/port_pkgs.yml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/fixtures/ports.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/ports.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/ports.yml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/fixtures/tags.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/tags.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/tags.yml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/fixtures/users.yml
===================================================================
--- users/jberry/mpwa/test/fixtures/users.yml (rev 0)
+++ users/jberry/mpwa/test/fixtures/users.yml 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
Added: users/jberry/mpwa/test/functional/person_controller_test.rb
===================================================================
--- users/jberry/mpwa/test/functional/person_controller_test.rb (rev 0)
+++ users/jberry/mpwa/test/functional/person_controller_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'person_controller'
+
+# Re-raise errors caught by the controller.
+class PersonController; def rescue_action(e) raise e end; end
+
+class PersonControllerTest < Test::Unit::TestCase
+ fixtures :people
+
+ def setup
+ @controller = PersonController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @first_id = people(:first).id
+ end
+
+ def test_index
+ get :index
+ assert_response :success
+ assert_template 'list'
+ end
+
+ def test_list
+ get :list
+
+ assert_response :success
+ assert_template 'list'
+
+ assert_not_nil assigns(:people)
+ end
+
+ def test_show
+ get :show, :id => @first_id
+
+ assert_response :success
+ assert_template 'show'
+
+ assert_not_nil assigns(:person)
+ assert assigns(:person).valid?
+ end
+
+ def test_new
+ get :new
+
+ assert_response :success
+ assert_template 'new'
+
+ assert_not_nil assigns(:person)
+ end
+
+ def test_create
+ num_people = Person.count
+
+ post :create, :person => {}
+
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_equal num_people + 1, Person.count
+ end
+
+ def test_edit
+ get :edit, :id => @first_id
+
+ assert_response :success
+ assert_template 'edit'
+
+ assert_not_nil assigns(:person)
+ assert assigns(:person).valid?
+ end
+
+ def test_update
+ post :update, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'show', :id => @first_id
+ end
+
+ def test_destroy
+ assert_nothing_raised {
+ Person.find(@first_id)
+ }
+
+ post :destroy, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_raise(ActiveRecord::RecordNotFound) {
+ Person.find(@first_id)
+ }
+ end
+end
Added: users/jberry/mpwa/test/functional/port_controller_test.rb
===================================================================
--- users/jberry/mpwa/test/functional/port_controller_test.rb (rev 0)
+++ users/jberry/mpwa/test/functional/port_controller_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'port_controller'
+
+# Re-raise errors caught by the controller.
+class PortController; def rescue_action(e) raise e end; end
+
+class PortControllerTest < Test::Unit::TestCase
+ fixtures :ports
+
+ def setup
+ @controller = PortController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @first_id = ports(:first).id
+ end
+
+ def test_index
+ get :index
+ assert_response :success
+ assert_template 'list'
+ end
+
+ def test_list
+ get :list
+
+ assert_response :success
+ assert_template 'list'
+
+ assert_not_nil assigns(:ports)
+ end
+
+ def test_show
+ get :show, :id => @first_id
+
+ assert_response :success
+ assert_template 'show'
+
+ assert_not_nil assigns(:port)
+ assert assigns(:port).valid?
+ end
+
+ def test_new
+ get :new
+
+ assert_response :success
+ assert_template 'new'
+
+ assert_not_nil assigns(:port)
+ end
+
+ def test_create
+ num_ports = Port.count
+
+ post :create, :port => {}
+
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_equal num_ports + 1, Port.count
+ end
+
+ def test_edit
+ get :edit, :id => @first_id
+
+ assert_response :success
+ assert_template 'edit'
+
+ assert_not_nil assigns(:port)
+ assert assigns(:port).valid?
+ end
+
+ def test_update
+ post :update, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'show', :id => @first_id
+ end
+
+ def test_destroy
+ assert_nothing_raised {
+ Port.find(@first_id)
+ }
+
+ post :destroy, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_raise(ActiveRecord::RecordNotFound) {
+ Port.find(@first_id)
+ }
+ end
+end
Added: users/jberry/mpwa/test/functional/port_pkg_controller_test.rb
===================================================================
--- users/jberry/mpwa/test/functional/port_pkg_controller_test.rb (rev 0)
+++ users/jberry/mpwa/test/functional/port_pkg_controller_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'port_pkg_controller'
+
+# Re-raise errors caught by the controller.
+class PortPkgController; def rescue_action(e) raise e end; end
+
+class PortPkgControllerTest < Test::Unit::TestCase
+ fixtures :port_pkgs
+
+ def setup
+ @controller = PortPkgController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @first_id = port_pkgs(:first).id
+ end
+
+ def test_index
+ get :index
+ assert_response :success
+ assert_template 'list'
+ end
+
+ def test_list
+ get :list
+
+ assert_response :success
+ assert_template 'list'
+
+ assert_not_nil assigns(:port_pkgs)
+ end
+
+ def test_show
+ get :show, :id => @first_id
+
+ assert_response :success
+ assert_template 'show'
+
+ assert_not_nil assigns(:port_pkg)
+ assert assigns(:port_pkg).valid?
+ end
+
+ def test_new
+ get :new
+
+ assert_response :success
+ assert_template 'new'
+
+ assert_not_nil assigns(:port_pkg)
+ end
+
+ def test_create
+ num_port_pkgs = PortPkg.count
+
+ post :create, :port_pkg => {}
+
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_equal num_port_pkgs + 1, PortPkg.count
+ end
+
+ def test_edit
+ get :edit, :id => @first_id
+
+ assert_response :success
+ assert_template 'edit'
+
+ assert_not_nil assigns(:port_pkg)
+ assert assigns(:port_pkg).valid?
+ end
+
+ def test_update
+ post :update, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'show', :id => @first_id
+ end
+
+ def test_destroy
+ assert_nothing_raised {
+ PortPkg.find(@first_id)
+ }
+
+ post :destroy, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_raise(ActiveRecord::RecordNotFound) {
+ PortPkg.find(@first_id)
+ }
+ end
+end
Added: users/jberry/mpwa/test/functional/tag_controller_test.rb
===================================================================
--- users/jberry/mpwa/test/functional/tag_controller_test.rb (rev 0)
+++ users/jberry/mpwa/test/functional/tag_controller_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'tag_controller'
+
+# Re-raise errors caught by the controller.
+class TagController; def rescue_action(e) raise e end; end
+
+class TagControllerTest < Test::Unit::TestCase
+ fixtures :tags
+
+ def setup
+ @controller = TagController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @first_id = tags(:first).id
+ end
+
+ def test_index
+ get :index
+ assert_response :success
+ assert_template 'list'
+ end
+
+ def test_list
+ get :list
+
+ assert_response :success
+ assert_template 'list'
+
+ assert_not_nil assigns(:tags)
+ end
+
+ def test_show
+ get :show, :id => @first_id
+
+ assert_response :success
+ assert_template 'show'
+
+ assert_not_nil assigns(:tag)
+ assert assigns(:tag).valid?
+ end
+
+ def test_new
+ get :new
+
+ assert_response :success
+ assert_template 'new'
+
+ assert_not_nil assigns(:tag)
+ end
+
+ def test_create
+ num_tags = Tag.count
+
+ post :create, :tag => {}
+
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_equal num_tags + 1, Tag.count
+ end
+
+ def test_edit
+ get :edit, :id => @first_id
+
+ assert_response :success
+ assert_template 'edit'
+
+ assert_not_nil assigns(:tag)
+ assert assigns(:tag).valid?
+ end
+
+ def test_update
+ post :update, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'show', :id => @first_id
+ end
+
+ def test_destroy
+ assert_nothing_raised {
+ Tag.find(@first_id)
+ }
+
+ post :destroy, :id => @first_id
+ assert_response :redirect
+ assert_redirected_to :action => 'list'
+
+ assert_raise(ActiveRecord::RecordNotFound) {
+ Tag.find(@first_id)
+ }
+ end
+end
Added: users/jberry/mpwa/test/unit/person_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/person_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/person_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PersonTest < Test::Unit::TestCase
+ fixtures :people
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: users/jberry/mpwa/test/unit/port_pkg_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/port_pkg_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/port_pkg_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PortPkgTest < Test::Unit::TestCase
+ fixtures :port_pkgs
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: users/jberry/mpwa/test/unit/port_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/port_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/port_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PortTest < Test::Unit::TestCase
+ fixtures :ports
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: users/jberry/mpwa/test/unit/tag_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/tag_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/tag_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class TagTest < Test::Unit::TestCase
+ fixtures :tags
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: users/jberry/mpwa/test/unit/user_test.rb
===================================================================
--- users/jberry/mpwa/test/unit/user_test.rb (rev 0)
+++ users/jberry/mpwa/test/unit/user_test.rb 2007-04-07 23:43:09 UTC (rev 23729)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class UserTest < Test::Unit::TestCase
+ fixtures :users
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070407/75073880/attachment.html
More information about the macports-changes
mailing list