From 733987fbb6e4652c40d27fdca111f97754cc5920 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Wed, 24 Dec 2008 11:23:17 +0000 Subject: [PATCH] Merged r2168 to r2171 from trunk. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2172 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/admin_controller.rb | 2 +- app/controllers/boards_controller.rb | 6 ++++-- app/controllers/issues_controller.rb | 10 ++++++---- app/controllers/projects_controller.rb | 8 ++++++-- app/controllers/timelog_controller.rb | 7 ++++++- app/controllers/users_controller.rb | 2 +- app/helpers/queries_helper.rb | 4 ++-- app/helpers/sort_helper.rb | 18 +++++++++++++----- app/models/mailer.rb | 2 +- app/views/boards/show.rhtml | 6 +++--- app/views/issues/_list.rhtml | 2 +- app/views/issues/_sidebar.rhtml | 2 +- app/views/projects/list_files.rhtml | 8 ++++---- app/views/timelog/_list.rhtml | 8 ++++---- app/views/wiki/annotate.rhtml | 2 +- lib/redcloth3.rb | 15 +++++++++------ test/functional/issues_controller_test.rb | 10 ++++++++++ test/unit/helpers/application_helper_test.rb | 10 ++++++++++ 18 files changed, 83 insertions(+), 39 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index d3afeeea1..be260b419 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -27,7 +27,7 @@ class AdminController < ApplicationController def projects sort_init 'name', 'asc' - sort_update + sort_update %w(name is_public created_on) @status = params[:status] ? params[:status].to_i : 1 c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status]) diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 4532a88fe..c6ce934ee 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -35,8 +35,10 @@ class BoardsController < ApplicationController end def show - sort_init "#{Message.table_name}.updated_on", "desc" - sort_update + sort_init 'updated_on', 'desc' + sort_update 'created_on' => "#{Message.table_name}.created_on", + 'replies' => "#{Message.table_name}.replies_count", + 'updated_on' => "#{Message.table_name}.updated_on" @topic_count = @board.topics.count @topic_pages = Paginator.new self, @topic_count, per_page_option, params['page'] diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 916229cbc..f1f88bfdb 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -45,9 +45,10 @@ class IssuesController < ApplicationController helper :timelog def index - sort_init "#{Issue.table_name}.id", "desc" - sort_update retrieve_query + sort_init 'id', 'desc' + sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h})) + if @query.valid? limit = per_page_option respond_to do |format| @@ -78,9 +79,10 @@ class IssuesController < ApplicationController end def changes - sort_init "#{Issue.table_name}.id", "desc" - sort_update retrieve_query + sort_init 'id', 'desc' + sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h})) + if @query.valid? @journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ], :conditions => @query.statement, diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 427165a3d..efb690144 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -197,8 +197,12 @@ class ProjectsController < ApplicationController end def list_files - sort_init "#{Attachment.table_name}.filename", "asc" - sort_update + sort_init 'filename', 'asc' + sort_update 'filename' => "#{Attachment.table_name}.filename", + 'created_on' => "#{Attachment.table_name}.created_on", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + @versions = @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse render :layout => !request.xhr? end diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index c333c02bb..58df1f5bc 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -138,7 +138,12 @@ class TimelogController < ApplicationController def details sort_init 'spent_on', 'desc' - sort_update + sort_update 'spent_on' => 'spent_on', + 'user' => 'user_id', + 'activity' => 'activity_id', + 'project' => "#{Project.table_name}.name", + 'issue' => 'issue_id', + 'hours' => 'hours' cond = ARCondition.new if @project.nil? diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e2ab510fb..4c9302824 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -30,7 +30,7 @@ class UsersController < ApplicationController def list sort_init 'login', 'asc' - sort_update + sort_update %w(login firstname lastname mail admin created_on last_login_on) @status = params[:status] ? params[:status].to_i : 1 c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status]) diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index cf9819fd5..63d6a5356 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -22,8 +22,8 @@ module QueriesHelper end def column_header(column) - column.sortable ? sort_header_tag(column.sortable, :caption => column.caption, - :default_order => column.default_order) : + column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption, + :default_order => column.default_order) : content_tag('th', column.caption) end diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb index 9ca5c11bd..d0a292987 100644 --- a/app/helpers/sort_helper.rb +++ b/app/helpers/sort_helper.rb @@ -67,23 +67,31 @@ module SortHelper # Updates the sort state. Call this in the controller prior to calling # sort_clause. - # - def sort_update() - if params[:sort_key] - sort = {:key => params[:sort_key], :order => params[:sort_order]} + # sort_keys can be either an array or a hash of allowed keys + def sort_update(sort_keys) + sort_key = params[:sort_key] + sort_key = nil unless (sort_keys.is_a?(Array) ? sort_keys.include?(sort_key) : sort_keys[sort_key]) + + sort_order = (params[:sort_order] == 'desc' ? 'DESC' : 'ASC') + + if sort_key + sort = {:key => sort_key, :order => sort_order} elsif session[@sort_name] sort = session[@sort_name] # Previous sort. else sort = @sort_default end session[@sort_name] = sort + + sort_column = (sort_keys.is_a?(Hash) ? sort_keys[sort[:key]] : sort[:key]) + @sort_clause = (sort_column.blank? ? '' : "#{sort_column} #{sort[:order]}") end # Returns an SQL sort clause corresponding to the current sort state. # Use this to sort the controller's table items collection. # def sort_clause() - session[@sort_name][:key] + ' ' + (session[@sort_name][:order] || 'ASC') + @sort_clause || '' #session[@sort_name][:key] + ' ' + (session[@sort_name][:order] || 'ASC') end # Returns a link which sorts by the named column. diff --git a/app/models/mailer.rb b/app/models/mailer.rb index f17ebbdbb..9614ab094 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -57,7 +57,7 @@ class Mailer < ActionMailer::Base subject l(:mail_subject_reminder, issues.size) body :issues => issues, :days => days, - :issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'issues.due_date', :sort_order => 'asc') + :issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'due_date', :sort_order => 'asc') end def document_added(document) diff --git a/app/views/boards/show.rhtml b/app/views/boards/show.rhtml index 06bb87ac7..adf0b46b4 100644 --- a/app/views/boards/show.rhtml +++ b/app/views/boards/show.rhtml @@ -33,9 +33,9 @@ <%= l(:field_subject) %> <%= l(:field_author) %> - <%= sort_header_tag("#{Message.table_name}.created_on", :caption => l(:field_created_on)) %> - <%= sort_header_tag("#{Message.table_name}.replies_count", :caption => l(:label_reply_plural)) %> - <%= sort_header_tag("#{Message.table_name}.updated_on", :caption => l(:label_message_last)) %> + <%= sort_header_tag('created_on', :caption => l(:field_created_on)) %> + <%= sort_header_tag('replies', :caption => l(:label_reply_plural)) %> + <%= sort_header_tag('updated_on', :caption => l(:label_message_last)) %> <% @topics.each do |topic| %> diff --git a/app/views/issues/_list.rhtml b/app/views/issues/_list.rhtml index cbdd4fd72..932676015 100644 --- a/app/views/issues/_list.rhtml +++ b/app/views/issues/_list.rhtml @@ -4,7 +4,7 @@ <%= link_to image_tag('toggle_check.png'), {}, :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;', :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> - <%= sort_header_tag("#{Issue.table_name}.id", :caption => '#', :default_order => 'desc') %> + <%= sort_header_tag('id', :caption => '#', :default_order => 'desc') %> <% query.columns.each do |column| %> <%= column_header(column) %> <% end %> diff --git a/app/views/issues/_sidebar.rhtml b/app/views/issues/_sidebar.rhtml index 9b7643ba9..bbc00f091 100644 --- a/app/views/issues/_sidebar.rhtml +++ b/app/views/issues/_sidebar.rhtml @@ -20,7 +20,7 @@

<%= l(:label_query_plural) %>

<% sidebar_queries.each do |query| -%> -<%= link_to query.name, :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %>
+<%= link_to(h(query.name), :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query) %>
<% end -%> <%= call_hook(:view_issues_sidebar_queries_bottom) %> <% end -%> diff --git a/app/views/projects/list_files.rhtml b/app/views/projects/list_files.rhtml index 79e41f16d..bdd6f8a93 100644 --- a/app/views/projects/list_files.rhtml +++ b/app/views/projects/list_files.rhtml @@ -9,10 +9,10 @@ - <%= sort_header_tag("#{Attachment.table_name}.filename", :caption => l(:field_filename)) %> - <%= sort_header_tag("#{Attachment.table_name}.created_on", :caption => l(:label_date), :default_order => 'desc') %> - <%= sort_header_tag("#{Attachment.table_name}.filesize", :caption => l(:field_filesize), :default_order => 'desc') %> - <%= sort_header_tag("#{Attachment.table_name}.downloads", :caption => l(:label_downloads_abbr), :default_order => 'desc') %> + <%= sort_header_tag('filename', :caption => l(:field_filename)) %> + <%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %> + <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %> + <%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %> <% if delete_allowed %><% end %> diff --git a/app/views/timelog/_list.rhtml b/app/views/timelog/_list.rhtml index 8aebd75de..1144d42cc 100644 --- a/app/views/timelog/_list.rhtml +++ b/app/views/timelog/_list.rhtml @@ -2,10 +2,10 @@ <%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %> -<%= sort_header_tag('user_id', :caption => l(:label_member)) %> -<%= sort_header_tag('activity_id', :caption => l(:label_activity)) %> -<%= sort_header_tag("#{Project.table_name}.name", :caption => l(:label_project)) %> -<%= sort_header_tag('issue_id', :caption => l(:label_issue), :default_order => 'desc') %> +<%= sort_header_tag('user', :caption => l(:label_member)) %> +<%= sort_header_tag('activity', :caption => l(:label_activity)) %> +<%= sort_header_tag('project', :caption => l(:label_project)) %> +<%= sort_header_tag('issue', :caption => l(:label_issue), :default_order => 'desc') %> <%= sort_header_tag('hours', :caption => l(:field_hours)) %> diff --git a/app/views/wiki/annotate.rhtml b/app/views/wiki/annotate.rhtml index 1c683404b..c27451606 100644 --- a/app/views/wiki/annotate.rhtml +++ b/app/views/wiki/annotate.rhtml @@ -20,7 +20,7 @@ - + <% line_num += 1 %> <% end -%> diff --git a/lib/redcloth3.rb b/lib/redcloth3.rb index fd56a8752..038522a89 100644 --- a/lib/redcloth3.rb +++ b/lib/redcloth3.rb @@ -408,7 +408,7 @@ class RedCloth3 < String # [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing # [ /"/, '“' ], # double opening # [ /\b( )?\.{3}/, '\1…' ], # ellipsis - [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '\1' ], # 3+ uppercase acronym + # [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '\1' ], # 3+ uppercase acronym # [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^\2\3', :no_span_caps ], # 3+ uppercase caps # [ /(\.\s)?\s?--\s?/, '\1—' ], # em dash # [ /\s->\s/, ' → ' ], # right arrow @@ -448,9 +448,12 @@ class RedCloth3 < String # Search and replace for Textile glyphs (quotes, dashes, other symbols) def pgl( text ) - GLYPHS.each do |re, resub, tog| - next if tog and method( tog ).call - text.gsub! re, resub + #GLYPHS.each do |re, resub, tog| + # next if tog and method( tog ).call + # text.gsub! re, resub + #end + text.gsub!(/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/) do |m| + "#{$1}" end end @@ -467,7 +470,7 @@ class RedCloth3 < String style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN end - style << "#{ $1 };" if not filter_styles and + style << "#{ htmlesc $1 };" if not filter_styles and text.sub!( /\{([^}]*)\}/, '' ) lang = $1 if @@ -810,7 +813,7 @@ class RedCloth3 < String end atts = pba( atts ) atts = " href=\"#{ url }#{ slash }\"#{ atts }" - atts << " title=\"#{ title }\"" if title + atts << " title=\"#{ htmlesc title }\"" if title atts = shelve( atts ) if atts external = (url =~ /^https?:\/\//) ? ' class="external"' : '' diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 8bd1af565..f0f1ec6ec 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -137,6 +137,16 @@ class IssuesControllerTest < Test::Unit::TestCase assert_not_nil assigns(:issues) assert_equal 'application/pdf', @response.content_type end + + def test_index_sort + get :index, :sort_key => 'tracker' + assert_response :success + + sort_params = @request.session['issuesindex_sort'] + assert sort_params.is_a?(Hash) + assert_equal 'tracker', sort_params[:key] + assert_equal 'ASC', sort_params[:order] + end def test_gantt get :gantt, :project_id => 1 diff --git a/test/unit/helpers/application_helper_test.rb b/test/unit/helpers/application_helper_test.rb index b3bc8e40d..d2d1a1f19 100644 --- a/test/unit/helpers/application_helper_test.rb +++ b/test/unit/helpers/application_helper_test.rb @@ -76,6 +76,15 @@ class ApplicationHelperTest < HelperTestCase to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } end + def test_acronyms + to_test = { + 'this is an acronym: GPL(General Public License)' => 'this is an acronym: GPL', + 'GPL(This is a double-quoted "title")' => 'GPL', + } + to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } + + end + def test_attached_images to_test = { 'Inline image: !logo.gif!' => 'Inline image: This is a logo', @@ -90,6 +99,7 @@ class ApplicationHelperTest < HelperTestCase 'This is a "link":http://foo.bar' => 'This is a link', 'This is an intern "link":/foo/bar' => 'This is an intern link', '"link (Link title)":http://foo.bar' => 'link', + '"link (Link title with "double-quotes")":http://foo.bar' => 'link', "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":

\n\n\n\t

Another paragraph", # no multiline link text "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line
\nand another on a second line\":test"

<%=l(:field_version)%>MD5
<%= l(:field_comments) %><%= line_num %> <%= link_to line[0], :controller => 'wiki', :action => 'index', :id => @project, :page => @page.title, :version => line[0] %> <%= h(line[1]) %>
<%= line[2] %>
<%=h line[2] %>