mirror of
https://github.com/TracksApp/tracks.git
synced 2026-01-31 05:05:18 +01:00
Quite a few improvements to Ajax handling here:
* Installed the RJS plugin http://www.codyfauser.com/articles/2005/12/05/rjs-templates-plugin-subversion-repository * Used the RJS templates to update multiple page elements on addition and deletion of actions: the new action gets added, the count 'badge' is updated correctly, and a status area provides helpful information. * If your data entry triggers validation errors e.g. no description for the next action), the errors are displayed in the status area (not very prettily as yet...) * The message about the context/project having no uncompleted actions automagically appears/disappears without refreshing the page. The editing and toggling of actions hasn't been updated yet. git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@171 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
e5d9a413d5
commit
c58f41775c
65 changed files with 3539 additions and 124 deletions
|
|
@ -30,12 +30,6 @@ class ApplicationController < ActionController::Base
|
|||
total = Todo.find_all("done=0").length - sub
|
||||
end
|
||||
|
||||
# Returns all the errors on the page for an object...
|
||||
#
|
||||
def errors_for( obj )
|
||||
error_messages_for( obj ) unless instance_eval("@#{obj}").nil?
|
||||
end
|
||||
|
||||
# Reverses the urlize() method by substituting underscores for spaces
|
||||
#
|
||||
def deurlize(name)
|
||||
|
|
@ -59,4 +53,21 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
|
||||
# Renders the given hash as xml. Primarily used to send multiple
|
||||
# partials back to an ajax request
|
||||
#
|
||||
# * +renders+ is a Hash where the keys are string identifiers,
|
||||
# and the values are partials rendered as a strings (see
|
||||
# <tt>render_to_string</tt>).
|
||||
def renders_to_xml(renders)
|
||||
xml = '<?xml version="1.0" encoding="ISO-8859-1"?><renders>'
|
||||
renders.each_key do |key|
|
||||
xml += "<" + key.to_s +
|
||||
"><![CDATA[#{renders[key]}]]></" +
|
||||
key.to_s + ">"
|
||||
end
|
||||
xml += '</renders>'
|
||||
render(:text => xml)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -42,6 +42,71 @@ class ContextController < ApplicationController
|
|||
render :text => "#{flash["warning"]}"
|
||||
end
|
||||
end
|
||||
|
||||
# Called by a form button
|
||||
# Parameters from form fields are passed to create new action
|
||||
# in the selected context.
|
||||
def add_item
|
||||
self.init
|
||||
@item = @user.todos.build
|
||||
@item.attributes = @params["todo"]
|
||||
|
||||
if @item.due?
|
||||
@item.due = Date.strptime(@params["todo"]["due"], DATE_FORMAT)
|
||||
else
|
||||
@item.due = ""
|
||||
end
|
||||
|
||||
@saved = @item.save
|
||||
@on_page = "context"
|
||||
@up_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 0 and todos.context_id IN (?)", @user.id, @item.context_id]).size.to_s
|
||||
|
||||
return if request.xhr?
|
||||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["warning"] = 'Added new next action'
|
||||
redirect_to :action => 'show', :id => @item
|
||||
else
|
||||
#render :action => 'new'
|
||||
end
|
||||
|
||||
rescue
|
||||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
#render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
# Delete a next action
|
||||
#
|
||||
def destroy_action
|
||||
self.init
|
||||
@item = check_user_return_item
|
||||
|
||||
@saved = @item.destroy
|
||||
@down_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 0 and todos.context_id IN (?)", @user.id, @item.context_id]).size.to_s
|
||||
|
||||
return if request.xhr?
|
||||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["warning"] = 'Successfully deleted next action'
|
||||
redirect_to :controller => 'todo', :action => 'list'
|
||||
else
|
||||
render :controller => 'todo', :action => 'list'
|
||||
end
|
||||
|
||||
rescue
|
||||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
render :controller => 'todo', :action => 'list'
|
||||
end
|
||||
end
|
||||
|
||||
# Edit the details of the context
|
||||
#
|
||||
|
|
@ -112,11 +177,23 @@ class ContextController < ApplicationController
|
|||
render_text ""
|
||||
end
|
||||
end
|
||||
|
||||
def check_user_return_item
|
||||
item = Todo.find( @params['id'] )
|
||||
if @session['user'] == item.user
|
||||
return item
|
||||
else
|
||||
flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@session['user'].name}!"
|
||||
render_text ""
|
||||
end
|
||||
end
|
||||
|
||||
def init
|
||||
@user = @session['user']
|
||||
@projects = @user.projects.collect { |x| x.done? ? nil:x }.compact
|
||||
@contexts = @user.contexts
|
||||
@todos = @user.todos
|
||||
@done = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 1", @user.id], :include => [:project], :order => "completed DESC")
|
||||
end
|
||||
|
||||
def init_todos
|
||||
|
|
|
|||
|
|
@ -62,6 +62,71 @@ class ProjectController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Called by a form button
|
||||
# Parameters from form fields are passed to create new action
|
||||
# in the selected context.
|
||||
def add_item
|
||||
self.init
|
||||
@item = @user.todos.build
|
||||
@item.attributes = @params["todo"]
|
||||
|
||||
if @item.due?
|
||||
@item.due = Date.strptime(@params["todo"]["due"], DATE_FORMAT)
|
||||
else
|
||||
@item.due = ""
|
||||
end
|
||||
|
||||
@saved = @item.save
|
||||
@on_page = "project"
|
||||
@up_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 0 and todos.project_id IN (?)", @user.id, @item.project_id]).size.to_s
|
||||
|
||||
return if request.xhr?
|
||||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["warning"] = 'Added new next action'
|
||||
redirect_to :action => 'show', :name => urlize(@item.project.name)
|
||||
else
|
||||
#render :action => 'new'
|
||||
end
|
||||
|
||||
rescue
|
||||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
#render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
# Delete a next action
|
||||
#
|
||||
def destroy_action
|
||||
self.init
|
||||
@item = check_user_return_item
|
||||
|
||||
@saved = @item.destroy
|
||||
@down_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 0 and todos.project_id IN (?)", @user.id, @item.project_id]).size.to_s
|
||||
|
||||
return if request.xhr?
|
||||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["warning"] = 'Successfully deleted next action'
|
||||
redirect_to :controller => 'todo', :action => 'list'
|
||||
else
|
||||
render :controller => 'todo', :action => 'list'
|
||||
end
|
||||
|
||||
rescue
|
||||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
render :controller => 'todo', :action => 'list'
|
||||
end
|
||||
end
|
||||
|
||||
# Edit the details of the project
|
||||
#
|
||||
def update
|
||||
|
|
@ -142,10 +207,22 @@ class ProjectController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def check_user_return_item
|
||||
item = Todo.find( @params['id'] )
|
||||
if @session['user'] == item.user
|
||||
return item
|
||||
else
|
||||
flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@session['user'].name}!"
|
||||
render_text ""
|
||||
end
|
||||
end
|
||||
|
||||
def init
|
||||
@user = @session['user']
|
||||
@projects = @user.projects
|
||||
@projects = @user.projects.collect { |x| x.done? ? nil:x }.compact
|
||||
@contexts = @user.contexts
|
||||
@todos = @user.todos
|
||||
@done = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 1", @user.id], :include => [:project], :order => "completed DESC")
|
||||
end
|
||||
|
||||
def init_todos
|
||||
|
|
|
|||
|
|
@ -32,29 +32,44 @@ class TodoController < ApplicationController
|
|||
@count = @todos.collect { |x| ( !x.done? and !x.context.hidden? ) ? x:nil }.compact.size
|
||||
end
|
||||
|
||||
def update_element
|
||||
end
|
||||
|
||||
# Called by a form button
|
||||
# Parameters from form fields are passed to create new action
|
||||
# in the selected context.
|
||||
def add_item
|
||||
self.init
|
||||
if @params["on_project_page"]
|
||||
@on_page = "project"
|
||||
end
|
||||
item = @user.todos.build
|
||||
item.attributes = @params["new_item"]
|
||||
@item = @user.todos.build
|
||||
@item.attributes = @params["todo"]
|
||||
|
||||
if item.due?
|
||||
item.due = Date.strptime(@params["new_item"]["due"], DATE_FORMAT)
|
||||
if @item.due?
|
||||
@item.due = Date.strptime(@params["todo"]["due"], DATE_FORMAT)
|
||||
else
|
||||
item.due = ""
|
||||
@item.due = ""
|
||||
end
|
||||
|
||||
if item.save
|
||||
render :partial => 'item', :object => item
|
||||
|
||||
@saved = @item.save
|
||||
@on_page = "home"
|
||||
@up_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 0", @user.id]).size.to_s
|
||||
|
||||
return if request.xhr?
|
||||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["warning"] = 'Added new next action'
|
||||
redirect_to :action => 'list'
|
||||
else
|
||||
flash["warning"] = "Couldn't add next action \"#{item.description}\""
|
||||
render_text ""
|
||||
render :action => 'list'
|
||||
end
|
||||
|
||||
rescue
|
||||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
render :action => 'list'
|
||||
end
|
||||
end
|
||||
|
||||
def edit_action
|
||||
|
|
@ -101,16 +116,32 @@ class TodoController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Delete a next action in a context
|
||||
# Delete a next action
|
||||
#
|
||||
def destroy_action
|
||||
item = check_user_return_item
|
||||
if item.destroy
|
||||
render_text ""
|
||||
self.init
|
||||
@item = check_user_return_item
|
||||
|
||||
@saved = @item.destroy
|
||||
@down_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 0", @user.id]).size.to_s
|
||||
|
||||
return if request.xhr?
|
||||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["warning"] = 'Successfully deleted next action'
|
||||
redirect_to :action => 'list'
|
||||
else
|
||||
flash["warning"] = "Couldn't delete next action \"#{item.description}\""
|
||||
render_text ""
|
||||
render :action => 'list'
|
||||
end
|
||||
|
||||
rescue
|
||||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
render :action => 'list'
|
||||
end
|
||||
end
|
||||
|
||||
# List the completed tasks, sorted by completion date
|
||||
|
|
|
|||
|
|
@ -41,17 +41,10 @@ module TodoHelper
|
|||
)
|
||||
end
|
||||
|
||||
def link_to_remote_todo( item )
|
||||
def link_to_remote_todo( item, handled_by)
|
||||
str = link_to_remote( image_tag("blank", :title =>"Delete action", :class=>"delete_item"),
|
||||
{
|
||||
:update => "item-#{item.id}-container",
|
||||
:loading => visual_effect(:fade, "item-#{item.id}-container"),
|
||||
:url => { :controller => "todo", :action => "destroy_action", :id => item.id },
|
||||
:confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?"
|
||||
},
|
||||
{
|
||||
:class => "icon"
|
||||
}) + "\n"
|
||||
{:url => { :controller => handled_by, :action => "destroy_action", :id => item.id }},
|
||||
{:class => "icon"}) + "\n"
|
||||
if !item.done?
|
||||
str << link_to_remote( image_tag("blank", :title =>"Edit action", :class=>"edit_item", :id=>"action-#{item.id}-edit-icon"),
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,10 +7,9 @@
|
|||
<%= link_to( sanitize("#{context.name}"), { :controller => "context", :action => "show", :name => urlize(context.name) }, { :title => "Go to the #{context.name} context page" } ) %>
|
||||
</h2>
|
||||
<div class="items toggle_target">
|
||||
<div class="empty-nd" style="display:<%= @not_done.empty? ? 'block' : 'none'%>;">
|
||||
<%= render :partial => "shared/empty",
|
||||
:locals => { :message => "Currently there are no uncompleted actions in this context"} %>
|
||||
<div id="empty-nd" style="display:<%= @not_done.empty? ? 'block' : 'none'%>;">
|
||||
<div class="message"><p>Currently there are no uncompleted actions in this context</p></div>
|
||||
</div>
|
||||
<%= render :partial => "todo/item", :collection => @not_done %>
|
||||
</div><!-- [end:items] -->
|
||||
</div><!-- [end:c<%= context.id %>] -->
|
||||
</div><!-- [end:c<%= context.id %>] -->
|
||||
14
tracks/app/views/context/add_item.rjs
Normal file
14
tracks/app/views/context/add_item.rjs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
if @saved
|
||||
page.insert_html :bottom, "c#{@item.context_id}", :partial => 'todo/item'
|
||||
page.hide "status"
|
||||
page.replace_html "status", content_tag("div", "Added new next action", "class" => "confirmation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
page.replace_html "badge_count", @up_count
|
||||
page.visual_effect :highlight, "item-#{@item.id}-container", :duration => 3
|
||||
page.hide "empty-nd" # If we are adding an new action, the uncompleted actions must be > 0
|
||||
page.send :record, "Form.reset('todo-form-new-action');Form.focusFirstElement('todo-form-new-action')"
|
||||
else
|
||||
page.hide "status"
|
||||
page.replace_html "status", content_tag("div", content_tag("h2", "#{pluralize(@item.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @item.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
end
|
||||
11
tracks/app/views/context/destroy_action.rjs
Normal file
11
tracks/app/views/context/destroy_action.rjs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
if @saved
|
||||
page.alert "Are you sure that you want to delete the next action: \'#{@item.description}\'?"
|
||||
page.visual_effect :fade, "item-#{@item.id}-container", :duration => 2.0
|
||||
page.remove "item-#{@item.id}-container"
|
||||
page.replace_html "badge_count", @down_count
|
||||
if @down_count == "0"
|
||||
page.show 'empty-nd'
|
||||
end
|
||||
else
|
||||
page.replace_html "status", content_tag("div", content_tag("h2", "#{pluralize(@item.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @item.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
end
|
||||
1
tracks/app/views/context/error.rjs
Normal file
1
tracks/app/views/context/error.rjs
Normal file
|
|
@ -0,0 +1 @@
|
|||
page.replace_html "status", "A server error has occurred"
|
||||
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
<div id="input_box">
|
||||
|
||||
<%= render "shared/add_new_item_form" %>
|
||||
<%= render :partial => "shared/add_new_item_form", :locals => {:hide_link => false, :msg => ""} %>
|
||||
<%= render "shared/sidebar" %>
|
||||
</div><!-- End of input box -->
|
||||
|
||||
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
|
||||
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>
|
||||
<% if @flash["warning"] %>
|
||||
<div id="warning_box" class="warning"><%= @flash["warning"] %></div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<div>
|
||||
<h1>
|
||||
<% if @count %>
|
||||
<span class="badge"><%= @count %></span>
|
||||
<span id="badge_count" class="badge"><%= @count %></span>
|
||||
<% end %>
|
||||
<%= Time.now.strftime("%A, %d %B %Y") %></h1>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<% @not_done = project.find_not_done_todos -%>
|
||||
|
||||
<div id="p<%= project.id %>" class="container project">
|
||||
<h2>
|
||||
<% if collapsible %>
|
||||
|
|
@ -14,10 +15,8 @@
|
|||
<p class="project_completed">Project has been marked as completed</p>
|
||||
<% end -%>
|
||||
<div class="items toggle_target">
|
||||
|
||||
<div id="empty-nd" style="display:<%= @not_done.empty? ? 'block' : 'none'%>;">
|
||||
<%= render :partial => "shared/empty",
|
||||
:locals => { :message => "Currently there are no uncompleted actions in this project"} %>
|
||||
<div class="message"><p>Currently there are no uncompleted actions in this project</p></div>
|
||||
</div>
|
||||
<%= render :partial => "todo/item", :collection => @not_done %>
|
||||
</div><!-- [end:items] -->
|
||||
|
|
|
|||
14
tracks/app/views/project/add_item.rjs
Normal file
14
tracks/app/views/project/add_item.rjs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
if @saved
|
||||
page.insert_html :bottom, "p#{@item.project_id}", :partial => 'todo/item'
|
||||
page.hide "status"
|
||||
page.replace_html "status", content_tag("div", "Added new next action", "class" => "confirmation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
page.replace_html "badge_count", @up_count
|
||||
page.visual_effect :highlight, "item-#{@item.id}-container", :duration => 3
|
||||
page.hide "empty-nd" # If we are adding an new action, the uncompleted actions must be > 0
|
||||
page.send :record, "Form.reset('todo-form-new-action');Form.focusFirstElement('todo-form-new-action')"
|
||||
else
|
||||
page.hide "status"
|
||||
page.replace_html "status", content_tag("div", content_tag("h2", "#{pluralize(@item.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @item.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
end
|
||||
11
tracks/app/views/project/destroy_action.rjs
Normal file
11
tracks/app/views/project/destroy_action.rjs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
if @saved
|
||||
page.alert "Are you sure that you want to delete the next action: \'#{@item.description}\'?"
|
||||
page.visual_effect :fade, "item-#{@item.id}-container", :duration => 2.0
|
||||
page.remove "item-#{@item.id}-container"
|
||||
page.replace_html "badge_count", @down_count
|
||||
if @down_count == "0"
|
||||
page.show 'empty-nd'
|
||||
end
|
||||
else
|
||||
page.replace_html "status", content_tag("div", content_tag("h2", "#{pluralize(@item.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @item.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
end
|
||||
1
tracks/app/views/project/error.rjs
Normal file
1
tracks/app/views/project/error.rjs
Normal file
|
|
@ -0,0 +1 @@
|
|||
page.replace_html "status", "A server error has occurred"
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
<div id="input_box">
|
||||
|
||||
<%= render "shared/add_new_item_form" %>
|
||||
<%= render "shared/_add_new_item_form" %>
|
||||
<%= render "shared/sidebar" %>
|
||||
</div><!-- End of input box -->
|
||||
|
||||
|
|
|
|||
57
tracks/app/views/shared/_add_new_item_form.rhtml
Normal file
57
tracks/app/views/shared/_add_new_item_form.rhtml
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<%
|
||||
case controller.controller_name
|
||||
when "context"
|
||||
add_string = "Add a next action in this context »"
|
||||
when "project"
|
||||
add_string = "Add a next action in this project »"
|
||||
else
|
||||
add_string = "Add a next action »"
|
||||
end
|
||||
%>
|
||||
|
||||
<% unless hide_link -%>
|
||||
<%= link_to_function(
|
||||
add_string,
|
||||
"Element.toggle('todo_new_action');Form.focusFirstElement('todo-form-new-action');",
|
||||
{:title => "Add the next action", :accesskey => "n"}) %>
|
||||
<% end -%>
|
||||
|
||||
<div id="todo_new_action" class="context_new" style="display:<%= hide_link ? 'block' : 'none'%>">
|
||||
<div id="status">
|
||||
</div>
|
||||
<!--[form:todo]-->
|
||||
<%= form_remote_tag(
|
||||
:url => { :controller => controller.controller_name, :action => "add_item" },
|
||||
:html=> { :id=>'todo-form-new-action', :name=>'todo', :class => 'inline-form' }) %>
|
||||
|
||||
<label for="todo_description">Description</label><br />
|
||||
<%= text_field( "todo", "description", "size" => 25, "tabindex" => 1) %><br />
|
||||
|
||||
<label for="todo_notes">Notes</label><br />
|
||||
<%= text_area( "todo", "notes", "cols" => 25, "rows" => 10, "tabindex" => 2) %><br />
|
||||
|
||||
<% unless controller.controller_name == "context" -%>
|
||||
<label for="todo_context_id">Context</label><br />
|
||||
<%= collection_select( "todo", "context_id", @contexts, "id", "name",
|
||||
{}, {"tabindex" => 3}) %><br />
|
||||
<% end -%>
|
||||
|
||||
<% unless controller.controller_name == "project" -%>
|
||||
<label for="todo_project_id">Project</label><br />
|
||||
<%= collection_select( "todo", "project_id", @projects, "id", "name",
|
||||
{ :include_blank => true }, {"tabindex" => 4}) %><br />
|
||||
<% end -%>
|
||||
|
||||
<label for="item_due">Due</label><br />
|
||||
<%= text_field("todo", "due", "size" => 10, "class" => "Date", "onFocus" => "Calendar.setup", "tabindex" => 5) %>
|
||||
|
||||
<% if controller.controller_name == "project" -%>
|
||||
<%= hidden_field( "todo", "project_id", "value" => "#{@project.id}") %>
|
||||
<% elsif controller.controller_name == "context" -%>
|
||||
<%= hidden_field( "todo", "context_id", "value" => "#{@context.id}") %>
|
||||
<% end -%>
|
||||
<br /><br />
|
||||
<input type="submit" value="Add item" tabindex="6">
|
||||
<%= end_form_tag %><!--[eoform:todo]-->
|
||||
<%= calendar_setup( "todo_due" ) %>
|
||||
</div><!-- [end:todo-new-action] -->
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
<%
|
||||
case controller.controller_name
|
||||
when "context"
|
||||
add_string = "Add a next action in this context »"
|
||||
update_div = "c" + @context.id.to_s
|
||||
when "project"
|
||||
add_string = "Add a next action in this project »"
|
||||
update_div = "p" + @project.id.to_s
|
||||
else
|
||||
add_string = "Add a next action »"
|
||||
update_div = "new_actions"
|
||||
end
|
||||
%>
|
||||
|
||||
<%= link_to_function(
|
||||
add_string,
|
||||
"Element.toggle('todo_new_action');Form.focusFirstElement('todo-form-new-action');",
|
||||
{:title => "Add the next action", :accesskey => "n"}) %>
|
||||
|
||||
<div id="todo_new_action" class="context_new" style="display:none">
|
||||
<!--[form:todo]-->
|
||||
<%= form_remote_tag(
|
||||
:url => { :controller => "todo", :action => "add_item" },
|
||||
:update => update_div,
|
||||
:position => "bottom",
|
||||
:loading => "ensureVisibleWithEffectAppear('#{update_div}');",
|
||||
:complete => "Form.focusFirstElement('todo-form-new-action');",
|
||||
:html=> { :id=>'todo-form-new-action', :name=>'todo', :class => 'inline-form' }) %>
|
||||
|
||||
<label for="new_item_description">Description</label><br />
|
||||
<%= text_field( "new_item", "description", "size" => 25, "tabindex" => 1) %><br />
|
||||
|
||||
<label for="new_item_notes">Notes</label><br />
|
||||
<%= text_area( "new_item", "notes", "cols" => 25, "rows" => 10, "tabindex" => 2) %><br />
|
||||
|
||||
<% unless controller.controller_name == "context" -%>
|
||||
<label for="new_item_context_id">Context</label><br />
|
||||
<%= collection_select( "new_item", "context_id", @contexts, "id", "name",
|
||||
{}, {"tabindex" => 3}) %><br />
|
||||
<% end -%>
|
||||
|
||||
<% unless controller.controller_name == "project" -%>
|
||||
<label for="new_item_project_id">Project</label><br />
|
||||
<%= collection_select( "new_item", "project_id", @projects, "id", "name",
|
||||
{ :include_blank => true }, {"tabindex" => 4}) %><br />
|
||||
<% end -%>
|
||||
|
||||
<label for="item_due">Due</label><br />
|
||||
<%= text_field("new_item", "due", "size" => 10, "class" => "Date", "onFocus" => "Calendar.setup", "tabindex" => 5) %>
|
||||
|
||||
<% if controller.controller_name == "project" -%>
|
||||
<%= hidden_field( "new_item", "project_id", "value" => "#{@project.id}") %>
|
||||
<input type="hidden" name="on_project_page" value="true" />
|
||||
<% elsif controller.controller_name == "context" -%>
|
||||
<%= hidden_field( "new_item", "context_id", "value" => "#{@context.id}") %>
|
||||
<% end -%>
|
||||
<br /><br />
|
||||
<input type="submit" value="Add item" tabindex="6">
|
||||
<%= end_form_tag %><!--[eoform:todo]-->
|
||||
<%= calendar_setup( "new_item_due" ) %>
|
||||
</div><!-- [end:todo-new-action] -->
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<%= form_remote_tag_toggle_todo( item ) %>
|
||||
<%= form_tag( { :controller => "todo", :action => "toggle_check", :id => item.id },
|
||||
{ :class => "inline-form" }) %>
|
||||
<%= link_to_remote_todo( item ) %>
|
||||
<%= link_to_remote_todo( item, controller.controller_name ) %>
|
||||
<input type="checkbox" class="item-checkbox" name="item_id" value="<%= item.id %>"<% if item.done? %> checked="checked" <% end %> />
|
||||
<div class="description<%= staleness_class( item ) %>"><% # start of div which has a class 'description', and possibly 'stale_11', 'stale_12', 'stale_13' etc %>
|
||||
<% if item.done? -%>
|
||||
|
|
|
|||
13
tracks/app/views/todo/add_item.rjs
Normal file
13
tracks/app/views/todo/add_item.rjs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
if @saved
|
||||
page.insert_html :bottom, "c#{@item.context_id}", :partial => 'todo/item'
|
||||
page.hide "status"
|
||||
page.replace_html "status", content_tag("div", "Added new next action", "class" => "confirmation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
page.replace_html "badge_count", @up_count
|
||||
page.visual_effect :highlight, "item-#{@item.id}-container", :duration => 3
|
||||
page.send :record, "Form.reset('todo-form-new-action');Form.focusFirstElement('todo-form-new-action')"
|
||||
else
|
||||
page.hide "status"
|
||||
page.replace_html "status", content_tag("div", content_tag("h2", "#{pluralize(@item.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @item.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
end
|
||||
8
tracks/app/views/todo/destroy_action.rjs
Normal file
8
tracks/app/views/todo/destroy_action.rjs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
if @saved
|
||||
page.alert "Are you sure that you want to delete the next action: \'#{@item.description}\'?"
|
||||
page.visual_effect :fade, "item-#{@item.id}-container", :duration => 2.0
|
||||
page.remove "item-#{@item.id}-container"
|
||||
page.replace_html "badge_count", @down_count
|
||||
else
|
||||
page.replace_html "status", content_tag("div", content_tag("h2", "#{pluralize(@item.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @item.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
end
|
||||
1
tracks/app/views/todo/error.rjs
Normal file
1
tracks/app/views/todo/error.rjs
Normal file
|
|
@ -0,0 +1 @@
|
|||
page.replace_html "status", "An error occurred on the server."
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
<div id="display_box">
|
||||
<div id="new_actions" class="next_actions container" style="display:none">
|
||||
<h2>Fresh actions (hit <a href="javascript:window.location.reload()">refresh</a> to sort)</h2>
|
||||
</div>
|
||||
<%= render :partial => "context/context", :collection => @contexts_to_show,
|
||||
:locals => { :collapsible => true } %>
|
||||
<%= render :partial => "todo/completed",
|
||||
|
|
@ -9,13 +6,11 @@
|
|||
</div><!-- End of display_box -->
|
||||
|
||||
<div id="input_box">
|
||||
<%= render "shared/add_new_item_form" %>
|
||||
<%= render :partial => "shared/add_new_item_form", :locals => {:hide_link => false, :msg => ""} %>
|
||||
<%= render "shared/sidebar" %>
|
||||
</div><!-- End of input box -->
|
||||
|
||||
<% if @flash["confirmation"] -%>
|
||||
<div class="confirmation"><%= @flash["confirmation"] %></div>
|
||||
<% end -%>
|
||||
<div class="status-box" id="confirmation-box"></div>
|
||||
<% if @flash["warning"] -%>
|
||||
<div class="warning"><%= @flash["warning"] %></div>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ ActionController::Routing::Routes.draw do |map|
|
|||
map.connect 'feed/:action/:name/:user', :controller => 'feed'
|
||||
|
||||
|
||||
map.connect 'add_item', :controller => 'todo', :action => 'add_item'
|
||||
#map.connect 'add_item', :controller => 'todo', :action => 'add_item'
|
||||
|
||||
# Install the default route as the lowest priority.
|
||||
map.connect ':controller/:action/:id'
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ Wiki (deprecated - please use Trac): http://www.rousette.org.uk/projects/wiki/
|
|||
13. The TXT view is now sorted by position, just as the home page is.
|
||||
14. <b>Contributed by lolindrath</b>: Items that are overdue are coloured red, and have the text 'Overdue by X days' in the badge. Other due dates are given as days from now (up to a week away in orange, more than a week away in green), and the tool tip shows the actual date.
|
||||
15. Projects and Contexts in [tracks_url]/projects and [tracks_url]/contexts can now be rearranged in order by dragging and dropping. Just pick the item up by the 'DRAG' label and drop it where you want.
|
||||
16. Got rid of the 'fresh actions' box on the home page. When you create a new action, it is now automatically inserted (via the magic of Ajax and RJS templates) at the bottom of the correct context box.
|
||||
17. The next action count badge is now dynamically updated whenever you add or delete a next action, so that you don't have to refresh to see the count updated.
|
||||
18. Validation errors are now reported in a status box (just above the new next action form).
|
||||
|
||||
== Version 1.03
|
||||
|
||||
|
|
|
|||
|
|
@ -273,21 +273,17 @@ a.footer_link:hover {color: #fff; background-color: #cc3334 !important;}
|
|||
|
||||
/* The alert box notifications */
|
||||
.confirmation {
|
||||
margin: 20px 50px 20px 490px;
|
||||
border: 1px solid #007E00;
|
||||
background-color: #c2ffc2;
|
||||
padding: 5px;
|
||||
color: #007E00;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.warning {
|
||||
margin: 20px 50px 20px 490px;
|
||||
border: 1px solid #ED2E38;
|
||||
background-color: #F6979C;
|
||||
padding: 5px;
|
||||
color: #ED2E38;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.project_completed {
|
||||
|
|
@ -519,4 +515,43 @@ div.message {
|
|||
text-align: center;
|
||||
font-size: 1em;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
/* Error message styles */
|
||||
.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;
|
||||
}
|
||||
|
||||
ul.warning { list-style-type: circle; font-size: 1em; }
|
||||
|
|
|
|||
15
tracks/vendor/plugins/javascript_generator_templates/CHANGELOG
vendored
Normal file
15
tracks/vendor/plugins/javascript_generator_templates/CHANGELOG
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
December 25, 2005
|
||||
* Added changeset 3316: http://dev.rubyonrails.org/changeset/3316
|
||||
* Added tests for javascript_generator_templates up to changeset 3116
|
||||
* Added changeset 3319: http://dev.rubyonrails.org/changeset/3319
|
||||
* Adds support for alert, redirect_to, call, assign, <<
|
||||
* Added changeset 3329 and 3335
|
||||
* Adds support for toggle, delay
|
||||
|
||||
December 15, 2005
|
||||
* Updated prototype.js to 1.4.0
|
||||
* Enabled the test test_render_file_with_locals
|
||||
* Add CHANGELOG file
|
||||
* Update README to reflect version 1.0 of Rails
|
||||
* Added MIT-LICENSE
|
||||
|
||||
20
tracks/vendor/plugins/javascript_generator_templates/MIT-LICENSE
vendored
Normal file
20
tracks/vendor/plugins/javascript_generator_templates/MIT-LICENSE
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2004 David Heinemeier Hansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
15
tracks/vendor/plugins/javascript_generator_templates/README
vendored
Normal file
15
tracks/vendor/plugins/javascript_generator_templates/README
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
JavaScriptGeneratorTemplates
|
||||
============================
|
||||
|
||||
This plugin allows the usage of the new RJS templates without having to run
|
||||
edge rails. For more information about RJS templates please check out these
|
||||
resources on the web:
|
||||
|
||||
http://rails.techno-weenie.net/tip/2005/11/29/ajaxed_forms_with_rjs_templates
|
||||
http://www.codyfauser.com/articles/2005/11/20/rails-rjs-templates
|
||||
http://dev.rubyonrails.org/changeset/3078
|
||||
|
||||
The RJS templates need at least version 1.4.0_rc4 of the prototype library to
|
||||
function correctly. Run rake update_prototype from this source directory to
|
||||
update your project's version of prototype to 1.4.0.
|
||||
|
||||
27
tracks/vendor/plugins/javascript_generator_templates/Rakefile
vendored
Normal file
27
tracks/vendor/plugins/javascript_generator_templates/Rakefile
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the javascript_generator_templates plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Generate documentation for the javascript_generator_templates plugin.'
|
||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = 'JavaScriptGeneratorTemplates'
|
||||
rdoc.options << '--line-numbers --inline-source'
|
||||
rdoc.rdoc_files.include('README')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
||||
desc "Install prototype.js file to public/javascripts"
|
||||
task :update_prototype do
|
||||
FileUtils.cp(File.dirname(__FILE__) + "/javascripts/prototype.js", File.dirname(__FILE__) + '/../../../public/javascripts/')
|
||||
end
|
||||
3
tracks/vendor/plugins/javascript_generator_templates/init.rb
vendored
Normal file
3
tracks/vendor/plugins/javascript_generator_templates/init.rb
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
require 'add_rjs_to_action_view'
|
||||
require 'add_rjs_to_action_controller'
|
||||
require 'add_rjs_to_javascript_helper'
|
||||
1785
tracks/vendor/plugins/javascript_generator_templates/javascripts/prototype.js
vendored
Normal file
1785
tracks/vendor/plugins/javascript_generator_templates/javascripts/prototype.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
67
tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb
vendored
Normal file
67
tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#--
|
||||
# Copyright (c) 2004 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
module ActionController #:nodoc:
|
||||
class Base
|
||||
protected
|
||||
def render_action(action_name, status = nil, with_layout = true)
|
||||
template = default_template_name(action_name)
|
||||
if with_layout && !template_exempt_from_layout?(template)
|
||||
render_with_layout(template, status)
|
||||
else
|
||||
render_without_layout(template, status)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def template_exempt_from_layout?(template_name = default_template_name)
|
||||
@template.javascript_template_exists?(template_name)
|
||||
end
|
||||
|
||||
def default_template_name(default_action_name = action_name)
|
||||
default_action_name = default_action_name.dup
|
||||
strip_out_controller!(default_action_name) if template_path_includes_controller?(default_action_name)
|
||||
"#{self.class.controller_path}/#{default_action_name}"
|
||||
end
|
||||
|
||||
def strip_out_controller!(path)
|
||||
path.replace path.split('/', 2).last
|
||||
end
|
||||
|
||||
def template_path_includes_controller?(path)
|
||||
path.to_s['/'] && self.class.controller_path.split('/')[-1] == path.split('/')[0]
|
||||
end
|
||||
end
|
||||
|
||||
module Layout #:nodoc:
|
||||
private
|
||||
def apply_layout?(template_with_options, options)
|
||||
template_with_options ? candidate_for_layout?(options) : !template_exempt_from_layout?
|
||||
end
|
||||
|
||||
def candidate_for_layout?(options)
|
||||
(options.has_key?(:layout) && options[:layout] != false) ||
|
||||
options.values_at(:text, :file, :inline, :partial, :nothing).compact.empty? &&
|
||||
!template_exempt_from_layout?(default_template_name(options[:action] || options[:template]))
|
||||
end
|
||||
end
|
||||
end
|
||||
142
tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb
vendored
Normal file
142
tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#--
|
||||
# Copyright (c) 2004 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
module ActionView
|
||||
class Base
|
||||
def pick_template_extension(template_path)#:nodoc:
|
||||
if match = delegate_template_exists?(template_path)
|
||||
match.first
|
||||
elsif erb_template_exists?(template_path): 'rhtml'
|
||||
elsif builder_template_exists?(template_path): 'rxml'
|
||||
elsif javascript_template_exists?(template_path): 'rjs'
|
||||
else
|
||||
raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path}"
|
||||
end
|
||||
end
|
||||
|
||||
def javascript_template_exists?(template_path)#:nodoc:
|
||||
template_exists?(template_path, :rjs)
|
||||
end
|
||||
|
||||
def file_exists?(template_path)#:nodoc:
|
||||
%w(erb builder javascript delegate).any? do |template_type|
|
||||
send("#{template_type}_template_exists?", template_path)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Create source code for given template
|
||||
def create_template_source(extension, template, render_symbol, locals)
|
||||
if template_requires_setup?(extension)
|
||||
body = case extension.to_sym
|
||||
when :rxml
|
||||
"xml = Builder::XmlMarkup.new(:indent => 2)\n" +
|
||||
"@controller.headers['Content-Type'] ||= 'text/xml'\n" +
|
||||
template
|
||||
when :rjs
|
||||
"@controller.headers['Content-Type'] ||= 'text/javascript'\n" +
|
||||
"update_page do |page|\n#{template}\nend"
|
||||
end
|
||||
else
|
||||
body = ERB.new(template, nil, @@erb_trim_mode).src
|
||||
end
|
||||
|
||||
@@template_args[render_symbol] ||= {}
|
||||
locals_keys = @@template_args[render_symbol].keys | locals
|
||||
@@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h }
|
||||
|
||||
locals_code = ""
|
||||
locals_keys.each do |key|
|
||||
locals_code << "#{key} = local_assigns[:#{key}] if local_assigns.has_key?(:#{key})\n"
|
||||
end
|
||||
|
||||
"def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
|
||||
end
|
||||
|
||||
def template_requires_setup?(extension)
|
||||
templates_requiring_setup.include? extension.to_s
|
||||
end
|
||||
|
||||
def templates_requiring_setup
|
||||
%w(rxml rjs)
|
||||
end
|
||||
|
||||
def assign_method_name(extension, template, file_name)
|
||||
method_name = '_run_'
|
||||
method_name << "#{extension}_" if extension
|
||||
|
||||
if file_name
|
||||
file_path = File.expand_path(file_name)
|
||||
base_path = File.expand_path(@base_path)
|
||||
|
||||
i = file_path.index(base_path)
|
||||
l = base_path.length
|
||||
|
||||
method_name_file_part = i ? file_path[i+l+1,file_path.length-l-1] : file_path.clone
|
||||
method_name_file_part.sub!(/\.r(html|xml|js)$/,'')
|
||||
method_name_file_part.tr!('/:-', '_')
|
||||
method_name_file_part.gsub!(/[^a-zA-Z0-9_]/){|s| s[0].to_s}
|
||||
|
||||
method_name += method_name_file_part
|
||||
else
|
||||
@@inline_template_count += 1
|
||||
method_name << @@inline_template_count.to_s
|
||||
end
|
||||
|
||||
@@method_names[file_name || template] = method_name.intern
|
||||
end
|
||||
|
||||
def compile_template(extension, template, file_name, local_assigns)
|
||||
method_key = file_name || template
|
||||
|
||||
render_symbol = @@method_names[method_key] || assign_method_name(extension, template, file_name)
|
||||
render_source = create_template_source(extension, template, render_symbol, local_assigns.keys)
|
||||
|
||||
line_offset = @@template_args[render_symbol].size
|
||||
if extension
|
||||
case extension.to_sym
|
||||
when :rxml, :rjs
|
||||
line_offset += 2
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
unless file_name.blank?
|
||||
CompiledTemplates.module_eval(render_source, file_name, -line_offset)
|
||||
else
|
||||
CompiledTemplates.module_eval(render_source, 'compiled-template', -line_offset)
|
||||
end
|
||||
rescue Object => e
|
||||
if logger
|
||||
logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
|
||||
logger.debug "Function body: #{render_source}"
|
||||
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
||||
end
|
||||
|
||||
raise TemplateError.new(@base_path, method_key, @assigns, template, e)
|
||||
end
|
||||
|
||||
@@compile_time[render_symbol] = Time.now
|
||||
# logger.debug "Compiled template #{method_key}\n ==> #{render_symbol}" if logger
|
||||
end
|
||||
end
|
||||
end
|
||||
204
tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb
vendored
Normal file
204
tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb
vendored
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
#--
|
||||
# Copyright (c) 2004 David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
module ActionView
|
||||
module Helpers
|
||||
module JavaScriptHelper
|
||||
# JavaScriptGenerator generates blocks of JavaScript code that allow you
|
||||
# to change the content and presentation of multiple DOM elements. Use
|
||||
# this in your Ajax response bodies, either in a <script> tag or as plain
|
||||
# JavaScript sent with a Content-type of "text/javascript".
|
||||
#
|
||||
# Create new instances with PrototypeHelper#update_page, then call
|
||||
# #insert_html, #replace_html, #remove, #show, or #hide on the yielded
|
||||
# generator in any order you like to modify the content and appearance of
|
||||
# the current page. (You can also call other helper methods which
|
||||
# return JavaScript, such as
|
||||
# ActionView::Helpers::ScriptaculousHelper#visual_effect.)
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# update_page do |page|
|
||||
# page.insert_html :bottom, 'list', '<li>Last item</li>'
|
||||
# page.visual_effect :highlight, 'list'
|
||||
# page.hide 'status-indicator', 'cancel-link'
|
||||
# end
|
||||
#
|
||||
# generates the following JavaScript:
|
||||
#
|
||||
# new Insertion.Bottom("list", "<li>Last item</li>");
|
||||
# new Effect.Highlight("list");
|
||||
# ["status-indicator", "cancel-link"].each(Element.hide);
|
||||
#
|
||||
# You can also use PrototypeHelper#update_page_tag instead of
|
||||
# PrototypeHelper#update_page to wrap the generated JavaScript in a
|
||||
# <script> tag.
|
||||
class JavaScriptGenerator
|
||||
def initialize(context) #:nodoc:
|
||||
@context, @lines = context, []
|
||||
yield self
|
||||
end
|
||||
|
||||
def to_s #:nodoc:
|
||||
@lines * $/
|
||||
end
|
||||
|
||||
# Inserts HTML at the specified +position+ relative to the DOM element
|
||||
# identified by the given +id+.
|
||||
#
|
||||
# +position+ may be one of:
|
||||
#
|
||||
# <tt>:top</tt>:: HTML is inserted inside the element, before the
|
||||
# element's existing content.
|
||||
# <tt>:bottom</tt>:: HTML is inserted inside the element, after the
|
||||
# element's existing content.
|
||||
# <tt>:before</tt>:: HTML is inserted immediately preceeding the element.
|
||||
# <tt>:after</tt>:: HTML is inserted immediately following the element.
|
||||
#
|
||||
# +options_for_render+ may be either a string of HTML to insert, or a hash
|
||||
# of options to be passed to ActionView::Base#render. For example:
|
||||
#
|
||||
# # Insert the rendered 'navigation' partial just before the DOM
|
||||
# # element with ID 'content'.
|
||||
# insert_html :before, 'content', :partial => 'navigation'
|
||||
#
|
||||
# # Add a list item to the bottom of the <ul> with ID 'list'.
|
||||
# insert_html :bottom, 'list', '<li>Last item</li>'
|
||||
#
|
||||
def insert_html(position, id, *options_for_render)
|
||||
insertion = position.to_s.camelize
|
||||
call "new Insertion.#{insertion}", id, render(*options_for_render)
|
||||
end
|
||||
|
||||
# Replaces the inner HTML of the DOM element with the given +id+.
|
||||
#
|
||||
# +options_for_render+ may be either a string of HTML to insert, or a hash
|
||||
# of options to be passed to ActionView::Base#render. For example:
|
||||
#
|
||||
# # Replace the HTML of the DOM element having ID 'person-45' with the
|
||||
# # 'person' partial for the appropriate object.
|
||||
# replace_html 'person-45', :partial => 'person', :object => @person
|
||||
#
|
||||
def replace_html(id, *options_for_render)
|
||||
call 'Element.update', id, render(*options_for_render)
|
||||
end
|
||||
|
||||
# Removes the DOM elements with the given +ids+ from the page.
|
||||
def remove(*ids)
|
||||
record "#{javascript_object_for(ids)}.each(Element.remove)"
|
||||
end
|
||||
|
||||
# Shows hidden DOM elements with the given +ids+.
|
||||
def show(*ids)
|
||||
call 'Element.show', *ids
|
||||
end
|
||||
|
||||
# Hides the visible DOM elements with the given +ids+.
|
||||
def hide(*ids)
|
||||
call 'Element.hide', *ids
|
||||
end
|
||||
|
||||
# Toggles the visibility of the DOM elements with the given +ids+.
|
||||
def toggle(*ids)
|
||||
call 'Element.toggle', *ids
|
||||
end
|
||||
|
||||
# Displays an alert dialog with the given +message+.
|
||||
def alert(message)
|
||||
call 'alert', message
|
||||
end
|
||||
|
||||
# Redirects the browser to the given +location+, in the same form as
|
||||
# +url_for+.
|
||||
def redirect_to(location)
|
||||
assign 'window.location.href', @context.url_for(location)
|
||||
end
|
||||
|
||||
# Calls the JavaScript +function+, optionally with the given
|
||||
# +arguments+.
|
||||
def call(function, *arguments)
|
||||
record "#{function}(#{arguments_for_call(arguments)})"
|
||||
end
|
||||
|
||||
# Assigns the JavaScript +variable+ the given +value+.
|
||||
def assign(variable, value)
|
||||
record "#{variable} = #{javascript_object_for(value)}"
|
||||
end
|
||||
|
||||
# Writes raw JavaScript to the page.
|
||||
def <<(javascript)
|
||||
@lines << javascript
|
||||
end
|
||||
|
||||
# Executes the content of the block after a delay of +seconds+. Example:
|
||||
#
|
||||
# page.delay(20) do
|
||||
# page.visual_effect :fade, 'notice'
|
||||
# end
|
||||
def delay(seconds = 1)
|
||||
record "setTimeout(function() {\n\n"
|
||||
yield
|
||||
record "}, #{(seconds * 1000).to_i})"
|
||||
end
|
||||
|
||||
private
|
||||
def method_missing(method, *arguments, &block)
|
||||
record(@context.send(method, *arguments, &block))
|
||||
end
|
||||
|
||||
def record(line)
|
||||
returning line = "#{line.to_s.chomp.gsub /\;$/, ''};" do
|
||||
self << line
|
||||
end
|
||||
end
|
||||
|
||||
def render(*options_for_render)
|
||||
Hash === options_for_render.first ?
|
||||
@context.render(*options_for_render) :
|
||||
options_for_render.first.to_s
|
||||
end
|
||||
|
||||
def javascript_object_for(object)
|
||||
object.respond_to?(:to_json) ? object.to_json : object.inspect
|
||||
end
|
||||
|
||||
def arguments_for_call(arguments)
|
||||
arguments.map { |argument| javascript_object_for(argument) }.join ', '
|
||||
end
|
||||
end
|
||||
|
||||
# Yields a JavaScriptGenerator and returns the generated JavaScript code.
|
||||
# Use this to update multiple elements on a page in an Ajax response.
|
||||
# See JavaScriptGenerator for more information.
|
||||
def update_page(&block)
|
||||
JavaScriptGenerator.new(@template, &block).to_s
|
||||
end
|
||||
|
||||
# Works like update_page but wraps the generated JavaScript in a <script>
|
||||
# tag. Use this to include generated JavaScript in an ERb template.
|
||||
# See JavaScriptGenerator for more information.
|
||||
def update_page_tag(&block)
|
||||
javascript_tag update_page(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
tracks/vendor/plugins/javascript_generator_templates/test/abstract_unit.rb
vendored
Normal file
20
tracks/vendor/plugins/javascript_generator_templates/test/abstract_unit.rb
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
$:.unshift(File.dirname(__FILE__) + '/..lib')
|
||||
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
|
||||
|
||||
rails_dir = File.dirname(__FILE__) + '/../../../rails'
|
||||
if File.directory?(rails_dir)
|
||||
lib_dir = rails_dir + '/actionpack/lib'
|
||||
require lib_dir + '/action_controller'
|
||||
require lib_dir + '/action_controller/test_process'
|
||||
else
|
||||
require 'rubygems'
|
||||
require 'action_controller'
|
||||
require 'action_controller/test_process'
|
||||
end
|
||||
require 'test/unit'
|
||||
require 'init'
|
||||
|
||||
ActionController::Base.logger = nil
|
||||
ActionController::Base.ignore_missing_templates = false
|
||||
ActionController::Routing::Routes.reload rescue nil
|
||||
|
||||
477
tracks/vendor/plugins/javascript_generator_templates/test/controller/new_render_test.rb
vendored
Normal file
477
tracks/vendor/plugins/javascript_generator_templates/test/controller/new_render_test.rb
vendored
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
require File.dirname(__FILE__) + '/../abstract_unit'
|
||||
|
||||
silence_warnings { Customer = Struct.new("Customer", :name) }
|
||||
|
||||
module Fun
|
||||
class GamesController < ActionController::Base
|
||||
def hello_world
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class NewRenderTestController < ActionController::Base
|
||||
layout :determine_layout
|
||||
|
||||
def self.controller_name; "test"; end
|
||||
def self.controller_path; "test"; end
|
||||
|
||||
def hello_world
|
||||
end
|
||||
|
||||
def render_hello_world
|
||||
render :template => "test/hello_world"
|
||||
end
|
||||
|
||||
def render_hello_world_from_variable
|
||||
@person = "david"
|
||||
render :text => "hello #{@person}"
|
||||
end
|
||||
|
||||
def render_action_hello_world
|
||||
render :action => "hello_world"
|
||||
end
|
||||
|
||||
def render_text_hello_world
|
||||
render :text => "hello world"
|
||||
end
|
||||
|
||||
def render_text_hello_world_with_layout
|
||||
@variable_for_layout = ", I'm here!"
|
||||
render :text => "hello world", :layout => true
|
||||
end
|
||||
|
||||
def render_custom_code
|
||||
render :text => "hello world", :status => "404 Moved"
|
||||
end
|
||||
|
||||
def render_file_with_instance_variables
|
||||
@secret = 'in the sauce'
|
||||
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.rhtml')
|
||||
render :file => path
|
||||
end
|
||||
|
||||
def render_file_with_locals
|
||||
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.rhtml')
|
||||
render :file => path, :locals => {:secret => 'in the sauce'}
|
||||
end
|
||||
|
||||
def render_file_not_using_full_path
|
||||
@secret = 'in the sauce'
|
||||
render :file => 'test/render_file_with_ivar', :use_full_path => true
|
||||
end
|
||||
|
||||
def render_xml_hello
|
||||
@name = "David"
|
||||
render :template => "test/hello"
|
||||
end
|
||||
|
||||
def greeting
|
||||
# let's just rely on the template
|
||||
end
|
||||
|
||||
def layout_test
|
||||
render :action => "hello_world"
|
||||
end
|
||||
|
||||
def layout_test_with_different_layout
|
||||
render :action => "hello_world", :layout => "standard"
|
||||
end
|
||||
|
||||
def rendering_without_layout
|
||||
render :action => "hello_world", :layout => false
|
||||
end
|
||||
|
||||
def layout_overriding_layout
|
||||
render :action => "hello_world", :layout => "standard"
|
||||
end
|
||||
|
||||
def rendering_nothing_on_layout
|
||||
render :nothing => true
|
||||
end
|
||||
|
||||
def builder_layout_test
|
||||
render :action => "hello"
|
||||
end
|
||||
|
||||
def partials_list
|
||||
@test_unchanged = 'hello'
|
||||
@customers = [ Customer.new("david"), Customer.new("mary") ]
|
||||
render :action => "list"
|
||||
end
|
||||
|
||||
def partial_only
|
||||
render :partial => true
|
||||
end
|
||||
|
||||
def partial_only_with_layout
|
||||
render :partial => "partial_only", :layout => true
|
||||
end
|
||||
|
||||
def partial_with_locals
|
||||
render :partial => "customer", :locals => { :customer => Customer.new("david") }
|
||||
end
|
||||
|
||||
def partial_collection
|
||||
render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
|
||||
end
|
||||
|
||||
def partial_collection_with_locals
|
||||
render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
|
||||
end
|
||||
|
||||
def empty_partial_collection
|
||||
render :partial => "customer", :collection => []
|
||||
end
|
||||
|
||||
def partial_with_hash_object
|
||||
render :partial => "hash_object", :object => {:first_name => "Sam"}
|
||||
end
|
||||
|
||||
def partial_with_implicit_local_assignment
|
||||
@customer = Customer.new("Marcel")
|
||||
render :partial => "customer"
|
||||
end
|
||||
|
||||
def hello_in_a_string
|
||||
@customers = [ Customer.new("david"), Customer.new("mary") ]
|
||||
render :text => "How's there? #{render_to_string("test/list")}"
|
||||
end
|
||||
|
||||
def accessing_params_in_template
|
||||
render :inline => "Hello: <%= params[:name] %>"
|
||||
end
|
||||
|
||||
def accessing_params_in_template_with_layout
|
||||
render :layout => nil, :inline => "Hello: <%= params[:name] %>"
|
||||
end
|
||||
|
||||
def render_with_explicit_template
|
||||
render "test/hello_world"
|
||||
end
|
||||
|
||||
def double_render
|
||||
render :text => "hello"
|
||||
render :text => "world"
|
||||
end
|
||||
|
||||
def double_redirect
|
||||
redirect_to :action => "double_render"
|
||||
redirect_to :action => "double_render"
|
||||
end
|
||||
|
||||
def render_and_redirect
|
||||
render :text => "hello"
|
||||
redirect_to :action => "double_render"
|
||||
end
|
||||
|
||||
def rendering_with_conflicting_local_vars
|
||||
@name = "David"
|
||||
def @template.name() nil end
|
||||
render :action => "potential_conflicts"
|
||||
end
|
||||
|
||||
def delete_with_js
|
||||
@project_id = 4
|
||||
end
|
||||
|
||||
def render_js_with_explicit_template
|
||||
@project_id = 4
|
||||
render :template => 'test/delete_with_js'
|
||||
end
|
||||
|
||||
def render_js_with_explicit_action_template
|
||||
@project_id = 4
|
||||
render :action => 'delete_with_js'
|
||||
end
|
||||
|
||||
def action_talk_to_layout
|
||||
# Action template sets variable that's picked up by layout
|
||||
end
|
||||
|
||||
def render_text_with_assigns
|
||||
@hello = "world"
|
||||
render :text => "foo"
|
||||
end
|
||||
|
||||
def yield_content_for
|
||||
render :action => "content_for", :layout => "yield"
|
||||
end
|
||||
|
||||
def rescue_action(e) raise end
|
||||
|
||||
private
|
||||
def determine_layout
|
||||
case action_name
|
||||
when "hello_world", "layout_test", "rendering_without_layout",
|
||||
"rendering_nothing_on_layout", "render_text_hello_world",
|
||||
"render_text_hello_world_with_layout",
|
||||
"partial_only", "partial_only_with_layout",
|
||||
"accessing_params_in_template",
|
||||
"accessing_params_in_template_with_layout",
|
||||
"render_with_explicit_template",
|
||||
"render_js_with_explicit_template",
|
||||
"render_js_with_explicit_action_template",
|
||||
"delete_with_js"
|
||||
|
||||
"layouts/standard"
|
||||
when "builder_layout_test"
|
||||
"layouts/builder"
|
||||
when "action_talk_to_layout", "layout_overriding_layout"
|
||||
"layouts/talk_from_action"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
NewRenderTestController.template_root = File.dirname(__FILE__) + "/../fixtures/"
|
||||
Fun::GamesController.template_root = File.dirname(__FILE__) + "/../fixtures/"
|
||||
|
||||
class NewRenderTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = NewRenderTestController.new
|
||||
|
||||
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
||||
# a more accurate simulation of what happens in "real life".
|
||||
@controller.logger = Logger.new(nil)
|
||||
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
|
||||
@request.host = "www.nextangle.com"
|
||||
end
|
||||
|
||||
def test_simple_show
|
||||
get :hello_world
|
||||
assert_response :success
|
||||
assert_template "test/hello_world"
|
||||
assert_equal "<html>Hello world!</html>", @response.body
|
||||
end
|
||||
|
||||
def test_do_with_render
|
||||
get :render_hello_world
|
||||
assert_template "test/hello_world"
|
||||
end
|
||||
|
||||
def test_do_with_render_from_variable
|
||||
get :render_hello_world_from_variable
|
||||
assert_equal "hello david", @response.body
|
||||
end
|
||||
|
||||
def test_do_with_render_action
|
||||
get :render_action_hello_world
|
||||
assert_template "test/hello_world"
|
||||
end
|
||||
|
||||
def test_do_with_render_text
|
||||
get :render_text_hello_world
|
||||
assert_equal "hello world", @response.body
|
||||
end
|
||||
|
||||
def test_do_with_render_text_and_layout
|
||||
get :render_text_hello_world_with_layout
|
||||
assert_equal "<html>hello world, I'm here!</html>", @response.body
|
||||
end
|
||||
|
||||
def test_do_with_render_custom_code
|
||||
get :render_custom_code
|
||||
assert_response :missing
|
||||
end
|
||||
|
||||
def test_render_file_with_instance_variables
|
||||
get :render_file_with_instance_variables
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
def test_render_file_not_using_full_path
|
||||
get :render_file_not_using_full_path
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
def test_render_file_with_locals
|
||||
get :render_file_with_locals
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
def test_attempt_to_access_object_method
|
||||
assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { get :clone }
|
||||
end
|
||||
|
||||
def test_private_methods
|
||||
assert_raises(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout }
|
||||
end
|
||||
|
||||
def test_access_to_request_in_view
|
||||
view_internals_old_value = ActionController::Base.view_controller_internals
|
||||
|
||||
ActionController::Base.view_controller_internals = false
|
||||
ActionController::Base.protected_variables_cache = nil
|
||||
|
||||
get :hello_world
|
||||
assert_nil(assigns["request"])
|
||||
|
||||
ActionController::Base.view_controller_internals = true
|
||||
ActionController::Base.protected_variables_cache = nil
|
||||
|
||||
get :hello_world
|
||||
assert_kind_of ActionController::AbstractRequest, assigns["request"]
|
||||
|
||||
ActionController::Base.view_controller_internals = view_internals_old_value
|
||||
ActionController::Base.protected_variables_cache = nil
|
||||
end
|
||||
|
||||
def test_render_xml
|
||||
get :render_xml_hello
|
||||
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
|
||||
end
|
||||
|
||||
def test_render_xml_with_default
|
||||
get :greeting
|
||||
assert_equal "<p>This is grand!</p>\n", @response.body
|
||||
end
|
||||
|
||||
def test_render_rjs_with_default
|
||||
get :delete_with_js
|
||||
assert_equal %!["person"].each(Element.remove);\nnew Effect.Highlight('project-4',{});!, @response.body
|
||||
end
|
||||
|
||||
def test_render_rjs_template_explicitly
|
||||
get :render_js_with_explicit_template
|
||||
assert_equal %!["person"].each(Element.remove);\nnew Effect.Highlight('project-4',{});!, @response.body
|
||||
end
|
||||
|
||||
def test_rendering_rjs_action_explicitly
|
||||
get :render_js_with_explicit_action_template
|
||||
assert_equal %!["person"].each(Element.remove);\nnew Effect.Highlight('project-4',{});!, @response.body
|
||||
end
|
||||
|
||||
def test_layout_rendering
|
||||
get :layout_test
|
||||
assert_equal "<html>Hello world!</html>", @response.body
|
||||
end
|
||||
|
||||
def test_layout_test_with_different_layout
|
||||
get :layout_test_with_different_layout
|
||||
assert_equal "<html>Hello world!</html>", @response.body
|
||||
end
|
||||
|
||||
def test_rendering_without_layout
|
||||
get :rendering_without_layout
|
||||
assert_equal "Hello world!", @response.body
|
||||
end
|
||||
|
||||
def test_layout_overriding_layout
|
||||
get :layout_overriding_layout
|
||||
assert_no_match %r{<title>}, @response.body
|
||||
end
|
||||
|
||||
def test_rendering_nothing_on_layout
|
||||
get :rendering_nothing_on_layout
|
||||
assert_equal " ", @response.body
|
||||
end
|
||||
|
||||
def test_render_xml_with_layouts
|
||||
get :builder_layout_test
|
||||
assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
|
||||
end
|
||||
|
||||
def test_partial_only
|
||||
get :partial_only
|
||||
assert_equal "only partial", @response.body
|
||||
end
|
||||
|
||||
def test_partial_only_with_layout
|
||||
get :partial_only_with_layout
|
||||
assert_equal "<html>only partial</html>", @response.body
|
||||
end
|
||||
|
||||
def test_render_to_string
|
||||
get :hello_in_a_string
|
||||
assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
|
||||
end
|
||||
|
||||
def test_nested_rendering
|
||||
get :hello_world
|
||||
assert_equal "Living in a nested world", Fun::GamesController.process(@request, @response).body
|
||||
end
|
||||
|
||||
def test_accessing_params_in_template
|
||||
get :accessing_params_in_template, :name => "David"
|
||||
assert_equal "Hello: David", @response.body
|
||||
end
|
||||
|
||||
def test_accessing_params_in_template_with_layout
|
||||
get :accessing_params_in_template_with_layout, :name => "David"
|
||||
assert_equal "<html>Hello: David</html>", @response.body
|
||||
end
|
||||
|
||||
def test_render_with_explicit_template
|
||||
get :render_with_explicit_template
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_double_render
|
||||
assert_raises(ActionController::DoubleRenderError) { get :double_render }
|
||||
end
|
||||
|
||||
def test_double_redirect
|
||||
assert_raises(ActionController::DoubleRenderError) { get :double_redirect }
|
||||
end
|
||||
|
||||
def test_render_and_redirect
|
||||
assert_raises(ActionController::DoubleRenderError) { get :render_and_redirect }
|
||||
end
|
||||
|
||||
def test_rendering_with_conflicting_local_vars
|
||||
get :rendering_with_conflicting_local_vars
|
||||
assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body)
|
||||
end
|
||||
|
||||
def test_action_talk_to_layout
|
||||
get :action_talk_to_layout
|
||||
assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
|
||||
end
|
||||
|
||||
def test_partials_list
|
||||
get :partials_list
|
||||
assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body
|
||||
end
|
||||
|
||||
def test_partial_with_locals
|
||||
get :partial_with_locals
|
||||
assert_equal "Hello: david", @response.body
|
||||
end
|
||||
|
||||
def test_partial_collection
|
||||
get :partial_collection
|
||||
assert_equal "Hello: davidHello: mary", @response.body
|
||||
end
|
||||
|
||||
def test_partial_collection_with_locals
|
||||
get :partial_collection_with_locals
|
||||
assert_equal "Bonjour: davidBonjour: mary", @response.body
|
||||
end
|
||||
|
||||
def test_empty_partial_collection
|
||||
get :empty_partial_collection
|
||||
assert_equal " ", @response.body
|
||||
end
|
||||
|
||||
def test_partial_with_hash_object
|
||||
get :partial_with_hash_object
|
||||
assert_equal "Sam", @response.body
|
||||
end
|
||||
|
||||
def test_partial_with_implicit_local_assignment
|
||||
get :partial_with_implicit_local_assignment
|
||||
assert_equal "Hello: Marcel", @response.body
|
||||
end
|
||||
|
||||
def test_render_text_with_assigns
|
||||
get :render_text_with_assigns
|
||||
assert_equal "world", assigns["hello"]
|
||||
end
|
||||
|
||||
def test_yield_content_for
|
||||
get :yield_content_for
|
||||
assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
Living in a nested world
|
||||
5
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/helpers/abc_helper.rb
vendored
Normal file
5
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/helpers/abc_helper.rb
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
module AbcHelper
|
||||
def bare_a() end
|
||||
def bare_b() end
|
||||
def bare_c() end
|
||||
end
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module Fun::GamesHelper
|
||||
def stratego() "Iz guuut!" end
|
||||
end
|
||||
3
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/helpers/fun/pdf_helper.rb
vendored
Normal file
3
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/helpers/fun/pdf_helper.rb
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module Fun::PDFHelper
|
||||
def foobar() 'baz' end
|
||||
end
|
||||
3
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/layouts/builder.rxml
vendored
Normal file
3
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/layouts/builder.rxml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
xml.wrapper do
|
||||
xml << @content_for_layout
|
||||
end
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/layouts/standard.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/layouts/standard.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<html><%= @content_for_layout %><%= @variable_for_layout %></html>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<title><%= @title || @content_for_title %></title>
|
||||
<%= @content_for_layout -%>
|
||||
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/layouts/yield.rhtml
vendored
Normal file
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/layouts/yield.rhtml
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<title><%= yield :title %></title>
|
||||
<%= yield %>
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_customer.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_customer.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
Hello: <%= customer.name %>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<%= greeting %>: <%= customer_greeting.name %>
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_hash_object.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_hash_object.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<%= hash_object[:first_name] %>
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_partial_only.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_partial_only.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
only partial
|
||||
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_person.rhtml
vendored
Normal file
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/_person.rhtml
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Second: <%= name %>
|
||||
Third: <%= @name %>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<% @title = "Talking to the layout" -%>
|
||||
Action was here!
|
||||
4
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/capturing.rhtml
vendored
Normal file
4
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/capturing.rhtml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<% days = capture do %>
|
||||
Dreamy days
|
||||
<% end %>
|
||||
<%= days %>
|
||||
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/content_for.rhtml
vendored
Normal file
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/content_for.rhtml
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<% content_for :title do %>Putting stuff in the title!<% end %>
|
||||
Great stuff!
|
||||
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/delete_with_js.rjs
vendored
Normal file
2
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/delete_with_js.rjs
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
page.remove 'person'
|
||||
page.visual_effect :highlight, "project-#{@project_id}"
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/greeting.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/greeting.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<p>This is grand!</p>
|
||||
4
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/hello.rxml
vendored
Normal file
4
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/hello.rxml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
xml.html do
|
||||
xml.p "Hello #{@name}"
|
||||
xml << render_file("test/greeting")
|
||||
end
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/hello_world.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/hello_world.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
Hello world!
|
||||
11
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/hello_xml_world.rxml
vendored
Normal file
11
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/hello_xml_world.rxml
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
xml.html do
|
||||
xml.head do
|
||||
xml.title "Hello World"
|
||||
end
|
||||
|
||||
xml.body do
|
||||
xml.p "abes"
|
||||
xml.p "monks"
|
||||
xml.p "wiseguys"
|
||||
end
|
||||
end
|
||||
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/list.rhtml
vendored
Normal file
1
tracks/vendor/plugins/javascript_generator_templates/test/fixtures/test/list.rhtml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<%= @test_unchanged = 'goodbye' %><%= render_collection_of_partials "customer", @customers %><%= @test_unchanged %>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
First: <%= @name %>
|
||||
<%= render :partial => "person", :locals => { :name => "Stephan" } -%>
|
||||
Fourth: <%= @name %>
|
||||
Fifth: <%= name %>
|
||||
|
|
@ -0,0 +1 @@
|
|||
The secret is <%= @secret %>
|
||||
|
|
@ -0,0 +1 @@
|
|||
The secret is <%= secret %>
|
||||
|
|
@ -0,0 +1 @@
|
|||
The value of foo is: ::<%= @foo %>::
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<% replacement_function = update_element_function("products", :action => :update) do %>
|
||||
<p>Product 1</p>
|
||||
<p>Product 2</p>
|
||||
<% end %>
|
||||
<%= javascript_tag(replacement_function) %>
|
||||
|
||||
<% update_element_function("status", :action => :update, :binding => binding) do %>
|
||||
<b>You bought something!</b>
|
||||
<% end %>
|
||||
279
tracks/vendor/plugins/javascript_generator_templates/test/template/javascript_helper_test.rb
vendored
Normal file
279
tracks/vendor/plugins/javascript_generator_templates/test/template/javascript_helper_test.rb
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
require File.dirname(__FILE__) + '/../abstract_unit'
|
||||
|
||||
module BaseTest
|
||||
include ActionView::Helpers::JavaScriptHelper
|
||||
|
||||
include ActionView::Helpers::UrlHelper
|
||||
include ActionView::Helpers::TagHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ActionView::Helpers::FormHelper
|
||||
include ActionView::Helpers::CaptureHelper
|
||||
|
||||
def setup
|
||||
@controller = Class.new do
|
||||
def url_for(options, *parameters_for_method_reference)
|
||||
url = "http://www.example.com/"
|
||||
url << options[:action].to_s if options and options[:action]
|
||||
url
|
||||
end
|
||||
end.new
|
||||
end
|
||||
|
||||
protected
|
||||
def create_generator
|
||||
block = Proc.new { |*args| yield *args if block_given? }
|
||||
JavaScriptGenerator.new self, &block
|
||||
end
|
||||
end
|
||||
|
||||
class JavaScriptHelperTest < Test::Unit::TestCase
|
||||
include BaseTest
|
||||
|
||||
def test_define_javascript_functions
|
||||
# check if prototype.js is included first
|
||||
assert_not_nil define_javascript_functions.split("\n")[1].match(/Prototype JavaScript framework/)
|
||||
|
||||
# check that scriptaculous.js is not in here, only needed if loaded remotely
|
||||
assert_nil define_javascript_functions.split("\n")[1].match(/var Scriptaculous = \{/)
|
||||
end
|
||||
|
||||
def test_escape_javascript
|
||||
assert_equal %(This \\"thing\\" is really\\n netos\\'), escape_javascript(%(This "thing" is really\n netos'))
|
||||
end
|
||||
|
||||
def test_link_to_function
|
||||
assert_dom_equal %(<a href="#" onclick="alert('Hello world!'); return false;">Greeting</a>),
|
||||
link_to_function("Greeting", "alert('Hello world!')")
|
||||
end
|
||||
|
||||
def test_link_to_remote
|
||||
assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outpost</a>),
|
||||
link_to_remote("Remote outpost", { :url => { :action => "whatnot" }}, { :class => "fine" })
|
||||
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.reponseText)}}); return false;\">Remote outpost</a>),
|
||||
link_to_remote("Remote outpost", :complete => "alert(request.reponseText)", :url => { :action => "whatnot" })
|
||||
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.reponseText)}}); return false;\">Remote outpost</a>),
|
||||
link_to_remote("Remote outpost", :success => "alert(request.reponseText)", :url => { :action => "whatnot" })
|
||||
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}}); return false;\">Remote outpost</a>),
|
||||
link_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot" })
|
||||
end
|
||||
|
||||
def test_periodically_call_remote
|
||||
assert_dom_equal %(<script type="text/javascript">\n//<![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Updater('schremser_bier', 'http://www.example.com/mehr_bier', {asynchronous:true, evalScripts:true})}, 10)\n//]]>\n</script>),
|
||||
periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" })
|
||||
end
|
||||
|
||||
def test_form_remote_tag
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast })
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
|
||||
form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast })
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
|
||||
form_remote_tag(:update => { :failure => "glass_of_water" }, :url => { :action => :fast })
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
|
||||
form_remote_tag(:update => { :success => 'glass_of_beer', :failure => "glass_of_water" }, :url => { :action => :fast })
|
||||
end
|
||||
|
||||
def test_on_callbacks
|
||||
callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :success, :failure]
|
||||
callbacks.each do |callback|
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();")
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => { :failure => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();")
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast }, callback=>"monkeys();")
|
||||
end
|
||||
|
||||
#HTTP status codes 200 up to 599 have callbacks
|
||||
#these should work
|
||||
100.upto(599) do |callback|
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
|
||||
end
|
||||
|
||||
#test 200 and 404
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, 200=>"monkeys();", 404=>"bananas();")
|
||||
|
||||
#these shouldn't
|
||||
1.upto(99) do |callback|
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
|
||||
end
|
||||
600.upto(999) do |callback|
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
|
||||
end
|
||||
|
||||
#test ultimate combo
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, onComplete:function(request){c();}, onFailure:function(request){f();}, onLoading:function(request){c1()}, onSuccess:function(request){s()}, parameters:Form.serialize(this)}); return false;\">),
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();")
|
||||
|
||||
end
|
||||
|
||||
def test_submit_to_remote
|
||||
assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); return false;\" type=\"button\" value=\"1000000\" />),
|
||||
submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle")
|
||||
end
|
||||
|
||||
def test_observe_field
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/reorder_if_empty', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>),
|
||||
observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" })
|
||||
end
|
||||
|
||||
def test_observe_form
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>),
|
||||
observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" })
|
||||
end
|
||||
|
||||
def test_effect
|
||||
assert_equal "new Effect.Highlight('posts',{});", visual_effect(:highlight, "posts")
|
||||
assert_equal "new Effect.Highlight('posts',{});", visual_effect("highlight", :posts)
|
||||
assert_equal "new Effect.Highlight('posts',{});", visual_effect(:highlight, :posts)
|
||||
assert_equal "new Effect.Fade('fademe',{duration:4.0});", visual_effect(:fade, "fademe", :duration => 4.0)
|
||||
assert_equal "new Effect.Shake(element,{});", visual_effect(:shake)
|
||||
assert_equal "new Effect.DropOut('dropme',{queue:'end'});", visual_effect(:drop_out, 'dropme', :queue => :end)
|
||||
end
|
||||
|
||||
def test_sortable_element
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create('mylist', {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize('mylist')})}})\n//]]>\n</script>),
|
||||
sortable_element("mylist", :url => { :action => "order" })
|
||||
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create('mylist', {constraint:'horizontal', onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize('mylist')})}, tag:'div'})\n//]]>\n</script>),
|
||||
sortable_element("mylist", :tag => "div", :constraint => "horizontal", :url => { :action => "order" })
|
||||
assert_dom_equal %|<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create('mylist', {constraint:'horizontal', containment:['list1','list2'], onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize('mylist')})}})\n//]]>\n</script>|,
|
||||
sortable_element("mylist", :containment => ['list1','list2'], :constraint => "horizontal", :url => { :action => "order" })
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create('mylist', {constraint:'horizontal', containment:'list1', onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize('mylist')})}})\n//]]>\n</script>),
|
||||
sortable_element("mylist", :containment => 'list1', :constraint => "horizontal", :url => { :action => "order" })
|
||||
end
|
||||
|
||||
def test_draggable_element
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Draggable('product_13', {})\n//]]>\n</script>),
|
||||
draggable_element('product_13')
|
||||
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Draggable('product_13', {revert:true})\n//]]>\n</script>),
|
||||
draggable_element('product_13', :revert => true)
|
||||
end
|
||||
|
||||
def test_drop_receiving_element
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add('droptarget1', {onDrop:function(element){new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
|
||||
drop_receiving_element('droptarget1')
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add('droptarget1', {accept:'products', onDrop:function(element){new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
|
||||
drop_receiving_element('droptarget1', :accept => 'products')
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add('droptarget1', {accept:'products', onDrop:function(element){new Ajax.Updater('infobox', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
|
||||
drop_receiving_element('droptarget1', :accept => 'products', :update => 'infobox')
|
||||
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add('droptarget1', {accept:['tshirts','mugs'], onDrop:function(element){new Ajax.Updater('infobox', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
|
||||
drop_receiving_element('droptarget1', :accept => ['tshirts','mugs'], :update => 'infobox')
|
||||
end
|
||||
|
||||
def test_update_element_function
|
||||
assert_equal %($('myelement').innerHTML = 'blub';\n),
|
||||
update_element_function('myelement', :content => 'blub')
|
||||
assert_equal %($('myelement').innerHTML = 'blub';\n),
|
||||
update_element_function('myelement', :action => :update, :content => 'blub')
|
||||
assert_equal %($('myelement').innerHTML = '';\n),
|
||||
update_element_function('myelement', :action => :empty)
|
||||
assert_equal %(Element.remove('myelement');\n),
|
||||
update_element_function('myelement', :action => :remove)
|
||||
|
||||
assert_equal %(new Insertion.Bottom('myelement','blub');\n),
|
||||
update_element_function('myelement', :position => 'bottom', :content => 'blub')
|
||||
assert_equal %(new Insertion.Bottom('myelement','blub');\n),
|
||||
update_element_function('myelement', :action => :update, :position => :bottom, :content => 'blub')
|
||||
|
||||
_erbout = ""
|
||||
assert_equal %($('myelement').innerHTML = 'test';\n),
|
||||
update_element_function('myelement') { _erbout << "test" }
|
||||
|
||||
_erbout = ""
|
||||
assert_equal %($('myelement').innerHTML = 'blockstuff';\n),
|
||||
update_element_function('myelement', :content => 'paramstuff') { _erbout << "blockstuff" }
|
||||
end
|
||||
|
||||
def test_update_page
|
||||
block = Proc.new { |page| page.replace_html('foo', 'bar') }
|
||||
assert_equal create_generator(&block).to_s, update_page(&block)
|
||||
end
|
||||
|
||||
def test_update_page_tag
|
||||
block = Proc.new { |page| page.replace_html('foo', 'bar') }
|
||||
assert_equal javascript_tag(create_generator(&block).to_s), update_page_tag(&block)
|
||||
end
|
||||
end
|
||||
|
||||
class JavaScriptGeneratorTest < Test::Unit::TestCase
|
||||
include BaseTest
|
||||
|
||||
def setup
|
||||
super
|
||||
@generator = create_generator
|
||||
end
|
||||
|
||||
def test_insert_html_with_string
|
||||
assert_equal 'new Insertion.Top("element", "<p>This is a test</p>");',
|
||||
@generator.insert_html(:top, 'element', '<p>This is a test</p>')
|
||||
assert_equal 'new Insertion.Bottom("element", "<p>This is a test</p>");',
|
||||
@generator.insert_html(:bottom, 'element', '<p>This is a test</p>')
|
||||
assert_equal 'new Insertion.Before("element", "<p>This is a test</p>");',
|
||||
@generator.insert_html(:before, 'element', '<p>This is a test</p>')
|
||||
assert_equal 'new Insertion.After("element", "<p>This is a test</p>");',
|
||||
@generator.insert_html(:after, 'element', '<p>This is a test</p>')
|
||||
end
|
||||
|
||||
def test_replace_html_with_string
|
||||
assert_equal 'Element.update("element", "<p>This is a test</p>");',
|
||||
@generator.replace_html('element', '<p>This is a test</p>')
|
||||
end
|
||||
|
||||
def test_remove
|
||||
assert_equal '["foo"].each(Element.remove);',
|
||||
@generator.remove('foo')
|
||||
assert_equal '["foo", "bar", "baz"].each(Element.remove);',
|
||||
@generator.remove('foo', 'bar', 'baz')
|
||||
end
|
||||
|
||||
def test_show
|
||||
assert_equal 'Element.show("foo");',
|
||||
@generator.show('foo')
|
||||
assert_equal 'Element.show("foo", "bar", "baz");',
|
||||
@generator.show('foo', 'bar', 'baz')
|
||||
end
|
||||
|
||||
def test_hide
|
||||
assert_equal 'Element.hide("foo");',
|
||||
@generator.hide('foo')
|
||||
assert_equal 'Element.hide("foo", "bar", "baz");',
|
||||
@generator.hide('foo', 'bar', 'baz')
|
||||
end
|
||||
|
||||
def test_alert
|
||||
assert_equal 'alert("hello");', @generator.alert('hello')
|
||||
end
|
||||
|
||||
def test_redirect_to
|
||||
assert_equal 'window.location.href = "http://www.example.com/welcome";',
|
||||
@generator.redirect_to(:action => 'welcome')
|
||||
end
|
||||
|
||||
def test_delay
|
||||
@generator.delay(20) do
|
||||
@generator.hide('foo')
|
||||
end
|
||||
|
||||
assert_equal "setTimeout(function() {\n;\nElement.hide(\"foo\");\n}, 20000);", @generator.to_s
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
@generator.insert_html(:top, 'element', '<p>This is a test</p>')
|
||||
@generator.insert_html(:bottom, 'element', '<p>This is a test</p>')
|
||||
@generator.remove('foo', 'bar')
|
||||
@generator.replace_html('baz', '<p>This is a test</p>')
|
||||
|
||||
assert_equal <<-EOS.chomp, @generator.to_s
|
||||
new Insertion.Top("element", "<p>This is a test</p>");
|
||||
new Insertion.Bottom("element", "<p>This is a test</p>");
|
||||
["foo", "bar"].each(Element.remove);
|
||||
Element.update("baz", "<p>This is a test</p>");
|
||||
EOS
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue