Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e613c6c10 | ||
|
|
76bcbce2ef | ||
|
|
7da7e853a3 | ||
|
|
6ae66f4dbf | ||
|
|
a98d4de1e3 | ||
|
|
5e4d66ad50 | ||
|
|
982d6bc748 | ||
|
|
3169291039 | ||
|
|
de86f4b965 | ||
|
|
bf45264131 | ||
|
|
1602fd0dfd | ||
|
|
12c4119abd | ||
|
|
f3a52d2e98 | ||
|
|
ba1af78dc8 | ||
|
|
59427dcfbf | ||
|
|
50755b5913 | ||
|
|
5b0051e710 | ||
|
|
8af523c694 | ||
|
|
2f84506227 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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) %>
|
||||
|
||||
@@ -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) %>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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 -%>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -50,3 +50,5 @@
|
||||
<div id="preview" class="wiki"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% html_title h(@topic.subject) %>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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 -%>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -433,12 +433,15 @@ class RedCloth < String
|
||||
#
|
||||
# Flexible HTML escaping
|
||||
#
|
||||
def htmlesc( str, mode )
|
||||
def htmlesc( str, mode=:Quotes )
|
||||
if str
|
||||
str.gsub!( '&', '&' )
|
||||
str.gsub!( '"', '"' ) if mode != :NoQuotes
|
||||
str.gsub!( "'", ''' ) if mode == :Quotes
|
||||
str.gsub!( '<', '<')
|
||||
str.gsub!( '>', '>')
|
||||
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
|
||||
|
||||
@@ -4,7 +4,7 @@ module Redmine
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 0
|
||||
MINOR = 7
|
||||
TINY = 2
|
||||
TINY = 4
|
||||
|
||||
def self.revision
|
||||
revision = nil
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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><pre><br /> lines<br /> of code<br /></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><pre><br /> lines<br /> of code<br /></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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "title"" alt="This is a double-quoted "title"" />',
|
||||
}
|
||||
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 "double-quotes"" 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><div>content</div></pre>",
|
||||
"HTML comment: <!-- no comments -->" => "<p>HTML comment: <!-- no comments --></p>",
|
||||
"<!-- opening comment" => "<p><!-- opening comment</p>"
|
||||
"<!-- opening comment" => "<p><!-- 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
|
||||
|
||||
Reference in New Issue
Block a user