Compare commits

..

19 Commits
0.7.2 ... 0.7.4

Author SHA1 Message Date
Jean-Philippe Lang
4e613c6c10 tagged version 0.7.4
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/tags/0.7.4@2206 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-30 11:28:31 +00:00
Jean-Philippe Lang
76bcbce2ef Updates CHANGELOG and version for 0.7.4 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2203 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-30 09:52:11 +00:00
Jean-Philippe Lang
7da7e853a3 Backported r2192 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2194 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-28 13:45:53 +00:00
Jean-Philippe Lang
6ae66f4dbf Merged r2183 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2185 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-27 14:08:09 +00:00
Jean-Philippe Lang
a98d4de1e3 Backported r2171 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2177 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 12:20:26 +00:00
Jean-Philippe Lang
5e4d66ad50 Backported r2170 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2176 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 11:56:36 +00:00
Jean-Philippe Lang
982d6bc748 Merged r2168 and r2169 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2175 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 11:44:55 +00:00
Jean-Philippe Lang
3169291039 Merged r2143 and r2144 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2174 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 11:42:05 +00:00
Jean-Philippe Lang
de86f4b965 Merged r1930 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.7-stable@2173 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 11:35:57 +00:00
Jean-Philippe Lang
bf45264131 Updated CHANGELOG.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1637 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:13:28 +00:00
Jean-Philippe Lang
1602fd0dfd Updated CHANGELOG and version number.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1636 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:12:21 +00:00
Jean-Philippe Lang
12c4119abd Merged r1609 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1635 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:10:47 +00:00
Jean-Philippe Lang
f3a52d2e98 Merged r1600 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1634 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:09:00 +00:00
Jean-Philippe Lang
ba1af78dc8 Merged r1598 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1633 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:08:02 +00:00
Jean-Philippe Lang
59427dcfbf Merged r1589 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1632 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:05:31 +00:00
Jean-Philippe Lang
50755b5913 Merged r1585 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1631 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:02:37 +00:00
Jean-Philippe Lang
5b0051e710 Merged r1583 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1630 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 11:01:06 +00:00
Jean-Philippe Lang
8af523c694 Merged r1561 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1629 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 10:58:31 +00:00
Jean-Philippe Lang
2f84506227 Merged r1612 from trunk.
git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1613 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-02 17:28:48 +00:00
32 changed files with 163 additions and 73 deletions

View File

@@ -28,7 +28,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 : 0
conditions = nil

View File

@@ -36,12 +36,13 @@ 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",
'updated_on' => "#{Message.table_name}.updated_on"
@topic_count = @board.topics.count
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
@topics = @board.topics.find :all, :order => "#{Message.table_name}.sticky DESC, #{sort_clause}",
@topics = @board.topics.find :all, :order => ["#{Message.table_name}.sticky DESC", sort_clause].compact.join(', '),
:include => [:author, {:last_reply => :author}],
:limit => @topic_pages.items_per_page,
:offset => @topic_pages.current.offset

View File

@@ -45,9 +45,10 @@ class IssuesController < ApplicationController
include IssuesHelper
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,

View File

@@ -204,8 +204,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

View File

@@ -129,7 +129,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
cond << (@issue.nil? ? @project.project_condition(Setting.display_subprojects_issues?) :
@@ -172,7 +177,7 @@ class TimelogController < ApplicationController
@time_entry.attributes = params[:time_entry]
if request.post? and @time_entry.save
flash[:notice] = l(:notice_successful_update)
redirect_to(params[:back_url] || {:action => 'details', :project_id => @time_entry.project})
redirect_to(params[:back_url].blank? ? {:action => 'details', :project_id => @time_entry.project} : params[:back_url])
return
end
@activities = Enumeration::get_values('ACTI')

View File

@@ -31,7 +31,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
conditions = "status <> 0"

View File

@@ -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

View File

@@ -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? ? nil : "#{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
end
# Returns a link which sorts by the named column.

View File

@@ -54,7 +54,7 @@ class User < ActiveRecord::Base
# Login must contain lettres, numbers, underscores only
validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
validates_length_of :login, :maximum => 30
validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
validates_length_of :firstname, :lastname, :maximum => 30
validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
validates_length_of :mail, :maximum => 60, :allow_nil => true

View File

@@ -1,7 +1,7 @@
<h2><%=h @user.name %></h2>
<p>
<%= mail_to @user.mail unless @user.pref.hide_mail %>
<%= mail_to(h(@user.mail)) unless @user.pref.hide_mail %>
<ul>
<li><%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %></li>
<% for custom_value in @custom_values %>
@@ -16,8 +16,8 @@
<h3><%=l(:label_project_plural)%></h3>
<ul>
<% for membership in @memberships %>
<li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %>
(<%= membership.role.name %>, <%= format_date(membership.created_on) %>)</li>
<li><%= link_to(h(membership.project.name), :controller => 'projects', :action => 'show', :id => membership.project) %>
(<%=h membership.role.name %>, <%= format_date(membership.created_on) %>)</li>
<% end %>
</ul>
<% end %>

View File

@@ -38,3 +38,5 @@
<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, {:controller => 'projects', :action => 'activity', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key}) %>
<% end %>
<% html_title l(:label_board_plural) %>

View File

@@ -32,9 +32,9 @@
<thead><tr>
<th><%= l(:field_subject) %></th>
<th><%= l(:field_author) %></th>
<%= sort_header_tag("#{Message.table_name}.created_on", :caption => l(:field_created_on)) %>
<%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
<th><%= l(:label_reply_plural) %></th>
<%= sort_header_tag("#{Message.table_name}.updated_on", :caption => l(:label_message_last)) %>
<%= sort_header_tag('updated_on', :caption => l(:label_message_last)) %>
</tr></thead>
<tbody>
<% @topics.each do |topic| %>
@@ -57,3 +57,5 @@
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
<% html_title h(@board.name) %>

View File

@@ -10,7 +10,11 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
@items.each do |item|
xml.entry do
url = url_for(item.event_url(:only_path => false))
xml.title truncate_single_line(item.event_title, 100)
if @project
xml.title truncate_single_line(item.event_title, 100)
else
xml.title truncate_single_line("#{item.project} - #{item.event_title}", 100)
end
xml.link "rel" => "alternate", "href" => url
xml.id url
xml.updated item.event_datetime.xmlschema

View File

@@ -4,7 +4,7 @@
<th><%= link_to image_tag('toggle_check.png'), {}, :onclick => 'toggleIssuesSelection(this.up("form")); return false;',
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
</th>
<%= 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 %>

View File

@@ -9,6 +9,6 @@
<h3><%= l(:label_query_plural) %></h3>
<% sidebar_queries.each do |query| -%>
<%= link_to query.name, :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %><br />
<%= link_to(h(query.name), :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query) %><br />
<% end -%>
<% end -%>

View File

@@ -1,6 +1,6 @@
<% form_remote_tag(:url => {}, :html => { :id => "journal-#{@journal.id}-form" }) do %>
<%= text_area_tag :notes, @journal.notes, :class => 'wiki-edit',
:rows => (@journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min) %>
<%= text_area_tag :notes, h(@journal.notes), :class => 'wiki-edit',
:rows => (@journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min) %>
<p><%= submit_tag l(:button_save) %>
<%= link_to l(:button_cancel), '#', :onclick => "Element.remove('journal-#{@journal.id}-form'); " +
"Element.show('journal-#{@journal.id}-notes'); return false;" %></p>

View File

@@ -1,12 +1,32 @@
<html>
<head>
<style>
body { font-family: Verdana, sans-serif; font-size: 0.8em; color:#484848; }
body h1 { font-family: "Trebuchet MS", Verdana, sans-serif; font-size: 1.2em; margin: 0;}
a, a:link, a:visited{ color: #2A5685; }
a:hover, a:active{ color: #c61a1a; }
hr { width: 100%; height: 1px; background: #ccc; border: 0; }
.footer { font-size: 0.8em; font-style: italic; }
body {
font-family: Verdana, sans-serif;
font-size: 0.8em;
color:#484848;
}
h1 {
font-family: "Trebuchet MS", Verdana, sans-serif;
font-size: 1.2em;
margin: 0px;
}
a, a:link, a:visited {
color: #2A5685;
}
a:hover, a:active {
color: #c61a1a;
}
hr {
width: 100%;
height: 1px;
background: #ccc;
border: 0;
}
.footer {
font-size: 0.8em;
font-style: italic;
}
</style>
</head>
<body>

View File

@@ -50,3 +50,5 @@
<div id="preview" class="wiki"></div>
</div>
<% end %>
<% html_title h(@topic.subject) %>

View File

@@ -9,10 +9,10 @@
<table class="list">
<thead><tr>
<th><%=l(:field_version)%></th>
<%= 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') %>
<th>MD5</th>
<% if delete_allowed %><th></th><% end %>
</tr></thead>

View File

@@ -3,7 +3,7 @@
<div class="splitcontentleft">
<%= textilizable @project.description %>
<ul>
<% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link @project.homepage %></li><% end %>
<% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link(h(@project.homepage)) %></li><% end %>
<% if @subprojects.any? %>
<li><%=l(:label_subproject_plural)%>: <%= @subprojects.collect{|p| link_to(h(p.name), :action => 'show', :id => p)}.join(", ") %></li>
<% end %>

View File

@@ -2,10 +2,10 @@
<thead>
<tr>
<%= 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') %>
<th><%= l(:field_comments) %></th>
<%= sort_header_tag('hours', :caption => l(:field_hours)) %>
<th></th>

View File

@@ -26,10 +26,10 @@
<tbody>
<% for user in @users -%>
<tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>">
<td class="username"><%= link_to user.login, :action => 'edit', :id => user %></td>
<td class="firstname"><%= user.firstname %></td>
<td class="lastname"><%= user.lastname %></td>
<td class="email"><%= user.mail %></td>
<td class="username"><%= link_to h(user.login), :action => 'edit', :id => user %></td>
<td class="firstname"><%= h(user.firstname) %></td>
<td class="lastname"><%= h(user.lastname) %></td>
<td class="email"><%= h(user.mail) %></td>
<td align="center"><%= image_tag('true.png') if user.admin? %></td>
<td class="created_on" align="center"><%= format_time(user.created_on) %></td>
<td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>

View File

@@ -18,7 +18,7 @@
<ul>
<% for project in @projects %>
<li>
<%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (<%= format_time(project.created_on) %>)
<%= link_to h(project.name), :controller => 'projects', :action => 'show', :id => project %> (<%= format_time(project.created_on) %>)
<%= textilizable project.short_description, :project => project %>
</li>
<% end %>

View File

@@ -20,7 +20,7 @@
<th class="line-num"><%= line_num %></th>
<td class="revision"><%= link_to line[0], :controller => 'wiki', :action => 'index', :id => @project, :page => @page.title, :version => line[0] %></td>
<td class="author"><%= h(line[1]) %></td>
<td class="line-code"><pre><%= line[2] %></pre></td>
<td class="line-code"><pre><%=h line[2] %></pre></td>
</tr>
<% line_num += 1 %>
<% end -%>

View File

@@ -12,6 +12,7 @@ production:
host: localhost
username: root
password:
encoding: utf8
development:
adapter: mysql
@@ -19,6 +20,7 @@ development:
host: localhost
username: root
password:
encoding: utf8
test:
adapter: mysql
@@ -26,6 +28,7 @@ test:
host: localhost
username: root
password:
encoding: utf8
test_pgsql:
adapter: postgresql

View File

@@ -4,6 +4,23 @@ Redmine - project management software
Copyright (C) 2006-2008 Jean-Philippe Lang
http://www.redmine.org/
== 2008-12-30 v0.7.4
* Fixed several XSS vulnerabilities
* Fixed a SQL injection vulnerability
== 2008-07-06 v0.7.3
* Allow dot in firstnames and lastnames
* Add project name to cross-project Atom feeds
* Encoding set to utf8 in example database.yml
* HTML titles on forums related views
* Fixed: various XSS vulnerabilities
* Fixed: Entourage (and some old client) fails to correctly render notification styles
* Fixed: Fixed: timelog redirects inappropriately when :back_url is blank
* Fixed: wrong relative paths to images in wiki_syntax.html
== 2008-06-15 v0.7.2

View File

@@ -433,12 +433,15 @@ class RedCloth < String
#
# Flexible HTML escaping
#
def htmlesc( str, mode )
def htmlesc( str, mode=:Quotes )
if str
str.gsub!( '&', '&amp;' )
str.gsub!( '"', '&quot;' ) if mode != :NoQuotes
str.gsub!( "'", '&#039;' ) if mode == :Quotes
str.gsub!( '<', '&lt;')
str.gsub!( '>', '&gt;')
end
str
end
# Search and replace for Textile glyphs (quotes, dashes, other symbols)
@@ -462,8 +465,7 @@ class RedCloth < String
style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
end
style << "#{ $1 };" if not filter_styles and
text.sub!( /\{([^}]*)\}/, '' )
style << "#{ htmlesc $1 };" if text.sub!( /\{([^}]*)\}/, '' ) && !filter_styles
lang = $1 if
text.sub!( /\[([^)]+?)\]/, '' )
@@ -783,7 +785,7 @@ class RedCloth < String
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"' : ''
@@ -890,6 +892,7 @@ class RedCloth < String
def inline_textile_image( text )
text.gsub!( IMAGE_RE ) do |m|
stln,algn,atts,url,title,href,href_a1,href_a2 = $~[1..8]
htmlesc title
atts = pba( atts )
atts = " src=\"#{ url }\"#{ atts }"
atts << " title=\"#{ title }\"" if title
@@ -1027,7 +1030,7 @@ class RedCloth < String
else
htmlesc( aftertag, :NoQuotes ) if aftertag and not used_offtags['notextile']
line = "<redpre##{ @pre_list.length }>"
@pre_list << "#{ $3 }#{ aftertag }"
@pre_list << "#{ $3.gsub(/<(#{ OFFTAGS })[^>]*>/, '<\\1>') }#{ aftertag }"
end
elsif $1 and codepre > 0
if codepre - used_offtags.length > 0

View File

@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc:
MAJOR = 0
MINOR = 7
TINY = 2
TINY = 4
def self.revision
revision = nil

View File

@@ -32,6 +32,7 @@ module Redmine
super
self.hard_breaks=true
self.no_span_caps=true
self.filter_styles=true
end
def to_html(*rules, &block)

View File

@@ -22,13 +22,13 @@ table td h3 { font-size: 1.2em; text-align: left; }
<table width="100%">
<tr><th colspan="3">Font Styles</th></tr>
<tr><th><img src="../../images/jstoolbar/bt_strong.png" style="border: 1px solid #bbb;" alt="Strong" /></th><td width="50%">*Strong*</td><td width="50%"><strong>Strong</strong></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_em.png" style="border: 1px solid #bbb;" alt="Italic" /></th><td>_Italic_</td><td><em>Italic</em></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_ins.png" style="border: 1px solid #bbb;" alt="Underline" /></th><td>+Underline+</td><td><ins>Underline</ins></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_del.png" style="border: 1px solid #bbb;" alt="Deleted" /></th><td>-Deleted-</td><td><del>Deleted</del></td></tr>
<tr><th><img src="../images/jstoolbar/bt_strong.png" style="border: 1px solid #bbb;" alt="Strong" /></th><td width="50%">*Strong*</td><td width="50%"><strong>Strong</strong></td></tr>
<tr><th><img src="../images/jstoolbar/bt_em.png" style="border: 1px solid #bbb;" alt="Italic" /></th><td>_Italic_</td><td><em>Italic</em></td></tr>
<tr><th><img src="../images/jstoolbar/bt_ins.png" style="border: 1px solid #bbb;" alt="Underline" /></th><td>+Underline+</td><td><ins>Underline</ins></td></tr>
<tr><th><img src="../images/jstoolbar/bt_del.png" style="border: 1px solid #bbb;" alt="Deleted" /></th><td>-Deleted-</td><td><del>Deleted</del></td></tr>
<tr><th></th><td>??Quote??</td><td><cite>Quote</cite></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_code.png" style="border: 1px solid #bbb;" alt="Inline Code" /></th><td>@Inline Code@</td><td><code>Inline Code</code></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_pre.png" style="border: 1px solid #bbb;" alt="Preformatted text" /></th><td>&lt;pre><br />&nbsp;lines<br />&nbsp;of code<br />&lt;/pre></td><td>
<tr><th><img src="../images/jstoolbar/bt_code.png" style="border: 1px solid #bbb;" alt="Inline Code" /></th><td>@Inline Code@</td><td><code>Inline Code</code></td></tr>
<tr><th><img src="../images/jstoolbar/bt_pre.png" style="border: 1px solid #bbb;" alt="Preformatted text" /></th><td>&lt;pre><br />&nbsp;lines<br />&nbsp;of code<br />&lt;/pre></td><td>
<pre>
lines
of code
@@ -36,27 +36,27 @@ table td h3 { font-size: 1.2em; text-align: left; }
</td></tr>
<tr><th colspan="3">Lists</th></tr>
<tr><th><img src="../../images/jstoolbar/bt_ul.png" style="border: 1px solid #bbb;" alt="Unordered list" /></th><td>* Item 1<br />* Item 2</td><td><ul><li>Item 1</li><li>Item 2</li></ul></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_ol.png" style="border: 1px solid #bbb;" alt="Ordered list" /></th><td># Item 1<br /># Item 2</td><td><ol><li>Item 1</li><li>Item 2</li></ol></td></tr>
<tr><th><img src="../images/jstoolbar/bt_ul.png" style="border: 1px solid #bbb;" alt="Unordered list" /></th><td>* Item 1<br />* Item 2</td><td><ul><li>Item 1</li><li>Item 2</li></ul></td></tr>
<tr><th><img src="../images/jstoolbar/bt_ol.png" style="border: 1px solid #bbb;" alt="Ordered list" /></th><td># Item 1<br /># Item 2</td><td><ol><li>Item 1</li><li>Item 2</li></ol></td></tr>
<tr><th colspan="3">Headings</th></tr>
<tr><th><img src="../../images/jstoolbar/bt_h1.png" style="border: 1px solid #bbb;" alt="Heading 1" /></th><td>h1. Title 1</td><td><h1>Title 1</h1></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_h2.png" style="border: 1px solid #bbb;" alt="Heading 2" /></th><td>h2. Title 2</td><td><h2>Title 2</h2></td></tr>
<tr><th><img src="../../images/jstoolbar/bt_h3.png" style="border: 1px solid #bbb;" alt="Heading 3" /></th><td>h3. Title 3</td><td><h3>Title 3</h3></td></tr>
<tr><th><img src="../images/jstoolbar/bt_h1.png" style="border: 1px solid #bbb;" alt="Heading 1" /></th><td>h1. Title 1</td><td><h1>Title 1</h1></td></tr>
<tr><th><img src="../images/jstoolbar/bt_h2.png" style="border: 1px solid #bbb;" alt="Heading 2" /></th><td>h2. Title 2</td><td><h2>Title 2</h2></td></tr>
<tr><th><img src="../images/jstoolbar/bt_h3.png" style="border: 1px solid #bbb;" alt="Heading 3" /></th><td>h3. Title 3</td><td><h3>Title 3</h3></td></tr>
<tr><th colspan="3">Links</th></tr>
<tr><th></th><td>http://foo.bar</td><td><a href="#">http://foo.bar</a></td></tr>
<tr><th></th><td>"Foo":http://foo.bar</td><td><a href="#">Foo</a></td></tr>
<tr><th colspan="3">Redmine links</th></tr>
<tr><th><img src="../../images/jstoolbar/bt_link.png" style="border: 1px solid #bbb;" alt="Link to a Wiki page" /></th><td>[[Wiki page]]</td><td><a href="#">Wiki page</a></td></tr>
<tr><th><img src="../images/jstoolbar/bt_link.png" style="border: 1px solid #bbb;" alt="Link to a Wiki page" /></th><td>[[Wiki page]]</td><td><a href="#">Wiki page</a></td></tr>
<tr><th></th><td>Issue #12</td><td>Issue <a href="#">#12</a></td></tr>
<tr><th></th><td>Revision r43</td><td>Revision <a href="#">r43</a></td></tr>
<tr><th></th><td>commit:"f30e13e43"</td><td><a href="#">f30e13e4</a></td></tr>
<tr><th></th><td>source:some/file</td><td><a href="#">source:some/file</a></td></tr>
<tr><th colspan="3">Inline images</th></tr>
<tr><th><img src="../../images/jstoolbar/bt_img.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>!<em>image_url</em>!</td><td></td></tr>
<tr><th><img src="../images/jstoolbar/bt_img.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>!<em>image_url</em>!</td><td></td></tr>
<tr><th></th><td>!<em>attached_image</em>!</td><td></td></tr>
</table>

View File

@@ -124,6 +124,16 @@ class IssuesControllerTest < Test::Unit::TestCase
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_changes
get :changes, :project_id => 1
assert_response :success

View File

@@ -49,7 +49,10 @@ class ApplicationHelperTest < HelperTestCase
'!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height100px;" alt="" />',
# inline styles should be stripped
'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
}
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
end
@@ -59,6 +62,7 @@ class ApplicationHelperTest < HelperTestCase
'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
'"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
'"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
# 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<br />\nand another on a second line\":test"
}
@@ -146,7 +150,9 @@ class ApplicationHelperTest < HelperTestCase
"<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
"<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
"HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
"<!-- opening comment" => "<p>&lt;!-- opening comment</p>"
"<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
# remove attributes
"<pre class='foo'>some text</pre>" => "<pre>some text</pre>",
}
to_test.each { |text, result| assert_equal result, textilizable(text) }
end