Attachments can now be added to wiki pages (original patch by Pavol Murin). Only authorized users can add/delete attachments.
Attached images can be displayed inline, using textile image tag (for wiki pages, issue descriptions and forum messages). git-svn-id: http://redmine.rubyforge.org/svn/trunk@541 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
6446c312be
commit
f8ef65e8f6
|
@ -0,0 +1,39 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class AttachmentsController < ApplicationController
|
||||||
|
before_filter :find_project, :check_project_privacy
|
||||||
|
|
||||||
|
# sends an attachment
|
||||||
|
def download
|
||||||
|
send_file @attachment.diskfile, :filename => @attachment.filename
|
||||||
|
end
|
||||||
|
|
||||||
|
# sends an image to be displayed inline
|
||||||
|
def show
|
||||||
|
render(:nothing => true, :status => 404) and return unless @attachment.diskfile =~ /\.(jpeg|jpg|gif|png)$/i
|
||||||
|
send_file @attachment.diskfile, :type => "image/#{$1}", :disposition => 'inline'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@attachment = Attachment.find(params[:id])
|
||||||
|
@project = @attachment.project
|
||||||
|
rescue
|
||||||
|
render_404
|
||||||
|
end
|
||||||
|
end
|
|
@ -29,6 +29,8 @@ class IssuesController < ApplicationController
|
||||||
include IssueRelationsHelper
|
include IssueRelationsHelper
|
||||||
helper :watchers
|
helper :watchers
|
||||||
include WatchersHelper
|
include WatchersHelper
|
||||||
|
helper :attachments
|
||||||
|
include AttachmentsHelper
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
|
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
|
||||||
|
@ -146,14 +148,6 @@ class IssuesController < ApplicationController
|
||||||
redirect_to :action => 'show', :id => @issue
|
redirect_to :action => 'show', :id => @issue
|
||||||
end
|
end
|
||||||
|
|
||||||
# Send the file in stream mode
|
|
||||||
def download
|
|
||||||
@attachment = @issue.attachments.find(params[:attachment_id])
|
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename
|
|
||||||
rescue
|
|
||||||
render_404
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_project
|
def find_project
|
||||||
@issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
|
@issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
|
||||||
|
|
|
@ -22,6 +22,9 @@ class MessagesController < ApplicationController
|
||||||
|
|
||||||
verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show }
|
verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show }
|
||||||
|
|
||||||
|
helper :attachments
|
||||||
|
include AttachmentsHelper
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@reply = Message.new(:subject => "RE: #{@message.subject}")
|
@reply = Message.new(:subject => "RE: #{@message.subject}")
|
||||||
render :action => "show", :layout => false if request.xhr?
|
render :action => "show", :layout => false if request.xhr?
|
||||||
|
@ -48,13 +51,6 @@ class MessagesController < ApplicationController
|
||||||
redirect_to :action => 'show', :id => @message
|
redirect_to :action => 'show', :id => @message
|
||||||
end
|
end
|
||||||
|
|
||||||
def download
|
|
||||||
@attachment = @message.attachments.find(params[:attachment_id])
|
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename
|
|
||||||
rescue
|
|
||||||
render_404
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_project
|
def find_project
|
||||||
@board = Board.find(params[:board_id], :include => :project)
|
@board = Board.find(params[:board_id], :include => :project)
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
|
|
||||||
class WikiController < ApplicationController
|
class WikiController < ApplicationController
|
||||||
layout 'base'
|
layout 'base'
|
||||||
before_filter :find_wiki, :check_project_privacy, :except => [:preview]
|
before_filter :find_wiki, :check_project_privacy
|
||||||
before_filter :authorize, :only => :destroy
|
before_filter :authorize, :only => [:destroy, :add_attachment, :destroy_attachment]
|
||||||
|
|
||||||
verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :index }
|
verify :method => :post, :only => [:destroy, :destroy_attachment], :redirect_to => { :action => :index }
|
||||||
|
|
||||||
|
helper :attachments
|
||||||
|
include AttachmentsHelper
|
||||||
|
|
||||||
# display a page (in editing mode if it doesn't exist)
|
# display a page (in editing mode if it doesn't exist)
|
||||||
def index
|
def index
|
||||||
|
@ -107,10 +110,28 @@ class WikiController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def preview
|
def preview
|
||||||
|
page = @wiki.find_page(params[:page])
|
||||||
|
@attachements = page.attachments if page
|
||||||
@text = params[:content][:text]
|
@text = params[:content][:text]
|
||||||
render :partial => 'preview'
|
render :partial => 'preview'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_attachment
|
||||||
|
@page = @wiki.find_page(params[:page])
|
||||||
|
# Save the attachments
|
||||||
|
params[:attachments].each { |file|
|
||||||
|
next unless file.size > 0
|
||||||
|
a = Attachment.create(:container => @page, :file => file, :author => logged_in_user)
|
||||||
|
} if params[:attachments] and params[:attachments].is_a? Array
|
||||||
|
redirect_to :action => 'index', :page => @page.title
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_attachment
|
||||||
|
@page = @wiki.find_page(params[:page])
|
||||||
|
@page.attachments.find(params[:attachment_id]).destroy
|
||||||
|
redirect_to :action => 'index', :page => @page.title
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_wiki
|
def find_wiki
|
||||||
|
|
|
@ -147,6 +147,23 @@ module ApplicationHelper
|
||||||
# r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (@project.id is 6)
|
# r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (@project.id is 6)
|
||||||
text = text.gsub(/(?=\b)r(\d+)(?=\b)/) {|m| link_to "r#{$1}", :controller => 'repositories', :action => 'revision', :id => @project.id, :rev => $1} if @project
|
text = text.gsub(/(?=\b)r(\d+)(?=\b)/) {|m| link_to "r#{$1}", :controller => 'repositories', :action => 'revision', :id => @project.id, :rev => $1} if @project
|
||||||
|
|
||||||
|
# when using an image link, try to use an attachment, if possible
|
||||||
|
attachments = options[:attachments]
|
||||||
|
if attachments
|
||||||
|
text = text.gsub(/!([<>=]*)(\S+\.(gif|jpg|jpeg|png))!/) do |m|
|
||||||
|
align = $1
|
||||||
|
filename = $2
|
||||||
|
rf = Regexp.new(filename, Regexp::IGNORECASE)
|
||||||
|
# search for the picture in attachments
|
||||||
|
if found = attachments.detect { |att| att.filename =~ rf }
|
||||||
|
image_url = url_for :controller => 'attachments', :action => 'show', :id => found.id
|
||||||
|
"!#{align}#{image_url}!"
|
||||||
|
else
|
||||||
|
"!#{align}#{filename}!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# finally textilize text
|
# finally textilize text
|
||||||
@do_textilize ||= (Setting.text_formatting == 'textile') && (ActionView::Helpers::TextHelper.method_defined? "textilize")
|
@do_textilize ||= (Setting.text_formatting == 'textile') && (ActionView::Helpers::TextHelper.method_defined? "textilize")
|
||||||
text = @do_textilize ? auto_link(RedCloth.new(text, [:hard_breaks]).to_html) : simple_format(auto_link(h(text)))
|
text = @do_textilize ? auto_link(RedCloth.new(text, [:hard_breaks]).to_html) : simple_format(auto_link(h(text)))
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module AttachmentsHelper
|
||||||
|
# displays the links to a collection of attachments
|
||||||
|
def link_to_attachments(attachments, options = {})
|
||||||
|
if attachments.any?
|
||||||
|
render :partial => 'attachments/links', :locals => {:attachments => attachments, :options => options}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -78,6 +78,10 @@ class Attachment < ActiveRecord::Base
|
||||||
find(:all, :limit => 5, :order => "downloads DESC")
|
find(:all, :limit => 5, :order => "downloads DESC")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
container.is_a?(Project) ? container : container.project
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def sanitize_filename(value)
|
def sanitize_filename(value)
|
||||||
# get only the filename, not the whole path
|
# get only the filename, not the whole path
|
||||||
|
|
|
@ -34,4 +34,8 @@ class Message < ActiveRecord::Base
|
||||||
board.increment! :topics_count
|
board.increment! :topics_count
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
board.project
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,7 +31,8 @@ class Wiki < ActiveRecord::Base
|
||||||
|
|
||||||
# find the page with the given title
|
# find the page with the given title
|
||||||
def find_page(title)
|
def find_page(title)
|
||||||
pages.find_by_title(Wiki.titleize(title || start_page))
|
title = start_page if title.blank?
|
||||||
|
pages.find_by_title(Wiki.titleize(title))
|
||||||
end
|
end
|
||||||
|
|
||||||
# turn a string into a valid page title
|
# turn a string into a valid page title
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
class WikiPage < ActiveRecord::Base
|
class WikiPage < ActiveRecord::Base
|
||||||
belongs_to :wiki
|
belongs_to :wiki
|
||||||
has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
|
has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
|
||||||
|
has_many :attachments, :as => :container, :dependent => :destroy
|
||||||
|
|
||||||
validates_presence_of :title
|
validates_presence_of :title
|
||||||
validates_format_of :title, :with => /^[^,\.\/\?\;\|\s]*$/
|
validates_format_of :title, :with => /^[^,\.\/\?\;\|\s]*$/
|
||||||
|
@ -41,4 +42,8 @@ class WikiPage < ActiveRecord::Base
|
||||||
def self.pretty_title(str)
|
def self.pretty_title(str)
|
||||||
(str && str.is_a?(String)) ? str.tr('_', ' ') : str
|
(str && str.is_a?(String)) ? str.tr('_', ' ') : str
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
wiki.project
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<p id="attachments_p"><label for="attachment_file"><%=l(:label_attachment)%>
|
||||||
|
<%= image_to_function "add.png", "addFileField();return false" %></label>
|
||||||
|
|
||||||
|
<%= file_field_tag 'attachments[]', :size => 30 %> <em>(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)</em></p>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="attachments">
|
||||||
|
<% for attachment in attachments %>
|
||||||
|
<p><%= link_to attachment.filename, {:controller => 'attachments', :action => 'download', :id => attachment }, :class => 'icon icon-attachment' %>
|
||||||
|
(<%= number_to_human_size attachment.filesize %>)
|
||||||
|
<% unless options[:no_author] %>
|
||||||
|
<em><%= attachment.author.display_name %>, <%= format_date(attachment.created_on) %></em>
|
||||||
|
<% end %>
|
||||||
|
<% if options[:delete_url] %>
|
||||||
|
<%= link_to image_tag('delete.png'), options[:delete_url].update({:attachment_id => attachment}), :confirm => l(:text_are_you_sure), :method => :post %>
|
||||||
|
<% end %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -52,7 +52,7 @@ end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<b><%=l(:field_description)%> :</b><br /><br />
|
<b><%=l(:field_description)%> :</b><br /><br />
|
||||||
<%= textilizable @issue.description %>
|
<%= textilizable @issue.description, :attachments => @issue.attachments %>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
|
@ -92,24 +92,14 @@ end %>
|
||||||
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<h3><%=l(:label_attachment_plural)%></h3>
|
<h3><%=l(:label_attachment_plural)%></h3>
|
||||||
<table width="100%">
|
<%= link_to_attachments @issue.attachments, :delete_url => (authorize_for('issues', 'destroy_attachment') ? {:controller => 'issues', :action => 'destroy_attachment', :id => @issue} : nil) %>
|
||||||
<% for attachment in @issue.attachments %>
|
|
||||||
<tr>
|
|
||||||
<td><%= link_to attachment.filename, { :action => 'download', :id => @issue, :attachment_id => attachment }, :class => 'icon icon-attachment' %> (<%= number_to_human_size(attachment.filesize) %>)</td>
|
|
||||||
<td><%= format_date(attachment.created_on) %></td>
|
|
||||||
<td><%= attachment.author.display_name %></td>
|
|
||||||
<td><div class="contextual"><%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy_attachment', :id => @issue, :attachment_id => attachment }, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %></div></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</table>
|
|
||||||
<br />
|
|
||||||
<% if authorize_for('issues', 'add_attachment') %>
|
<% if authorize_for('issues', 'add_attachment') %>
|
||||||
<% form_tag({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true, :class => "tabular") do %>
|
<p><%= toggle_link l(:label_attachment_new), "add_attachment_form" %></p>
|
||||||
<p id="attachments_p"><label><%=l(:label_attachment_new)%>
|
<% form_tag({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true, :class => "tabular", :id => "add_attachment_form", :style => "display:none;") do %>
|
||||||
<%= image_to_function "add.png", "addFileField();return false" %></label>
|
<%= render :partial => 'attachments/form' %>
|
||||||
<%= file_field_tag 'attachments[]', :size => 30 %> <em>(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)</em></p>
|
<%= submit_tag l(:button_add) %>
|
||||||
<%= submit_tag l(:button_add) %>
|
<% end %>
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,5 @@
|
||||||
<!--[eoform:message]-->
|
<!--[eoform:message]-->
|
||||||
|
|
||||||
<span class="tabular">
|
<span class="tabular">
|
||||||
<p id="attachments_p"><label><%=l(:label_attachment)%>
|
<%= render :partial => 'attachments/form' %>
|
||||||
<%= image_to_function "add.png", "addFileField();return false" %></label>
|
|
||||||
<%= file_field_tag 'attachments[]', :size => 30 %> <em>(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)</em></p>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,15 +2,10 @@
|
||||||
|
|
||||||
<p><em><%= @message.author.name %>, <%= format_time(@message.created_on) %></em></p>
|
<p><em><%= @message.author.name %>, <%= format_time(@message.created_on) %></em></p>
|
||||||
<div class="wiki">
|
<div class="wiki">
|
||||||
<%= textilizable(@message.content) %>
|
<%= textilizable(@message.content, :attachments => @message.attachments) %>
|
||||||
</div>
|
</div>
|
||||||
<div class="attachments">
|
<%= link_to_attachments @message.attachments, :no_author => true %>
|
||||||
<% @message.attachments.each do |attachment| %>
|
|
||||||
<%= link_to attachment.filename, { :action => 'download', :id => @message, :attachment_id => attachment }, :class => 'icon icon-attachment' %>
|
|
||||||
(<%= number_to_human_size(attachment.filesize) %>)<br />
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<h3 class="icon22 icon22-comment"><%= l(:label_reply_plural) %></h3>
|
<h3 class="icon22 icon22-comment"><%= l(:label_reply_plural) %></h3>
|
||||||
<% @message.children.each do |message| %>
|
<% @message.children.each do |message| %>
|
||||||
<a name="<%= "message-#{message.id}" %>"></a>
|
<a name="<%= "message-#{message.id}" %>"></a>
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
<fieldset class="preview"><legend><%= l(:label_preview) %></legend>
|
<fieldset class="preview"><legend><%= l(:label_preview) %></legend>
|
||||||
<%= textilizable @text %>
|
<%= textilizable @text, :attachments => @attachements %>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
@ -21,12 +21,22 @@
|
||||||
|
|
||||||
<div class="wiki">
|
<div class="wiki">
|
||||||
<% cache "wiki/show/#{@page.id}/#{@content.version}" do %>
|
<% cache "wiki/show/#{@page.id}/#{@content.version}" do %>
|
||||||
<%= textilizable @content.text %>
|
<%= textilizable @content.text, :attachments => @page.attachments %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= link_to_attachments @page.attachments, :delete_url => (authorize_for('wiki', 'destroy_attachment') ? {:controller => 'wiki', :action => 'destroy_attachment', :page => @page.title} : nil) %>
|
||||||
|
|
||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
<%= l(:label_export_to) %>
|
<%= l(:label_export_to) %>
|
||||||
<%= link_to 'HTML', {:export => 'html', :version => @content.version}, :class => 'icon icon-html' %>,
|
<%= link_to 'HTML', {:export => 'html', :version => @content.version}, :class => 'icon icon-html' %>,
|
||||||
<%= link_to 'TXT', {:export => 'txt', :version => @content.version}, :class => 'icon icon-txt' %>
|
<%= link_to 'TXT', {:export => 'txt', :version => @content.version}, :class => 'icon icon-txt' %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% if authorize_for('wiki', 'add_attachment') %>
|
||||||
|
<p><%= toggle_link l(:label_attachment_new), "add_attachment_form" %></p>
|
||||||
|
<% form_tag({ :controller => 'wiki', :action => 'add_attachment', :page => @page.title }, :multipart => true, :class => "tabular", :id => "add_attachment_form", :style => "display:none;") do %>
|
||||||
|
<%= render :partial => 'attachments/form' %>
|
||||||
|
<%= submit_tag l(:button_add) %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
class AddWikiAttachmentsPermissions < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
Permission.create :controller => 'wiki', :action => 'add_attachment', :description => 'label_attachment_new', :sort => 1750, :is_public => false, :mail_option => 0, :mail_enabled => 0
|
||||||
|
Permission.create :controller => 'wiki', :action => 'destroy_attachment', :description => 'label_attachment_delete', :sort => 1755, :is_public => false, :mail_option => 0, :mail_enabled => 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
Permission.find_by_controller_and_action('wiki', 'add_attachment').destroy
|
||||||
|
Permission.find_by_controller_and_action('wiki', 'destroy_attachment').destroy
|
||||||
|
end
|
||||||
|
end
|
|
@ -475,7 +475,8 @@ position: relative;
|
||||||
margin: 0 5px 5px;
|
margin: 0 5px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.attachments {padding-left: 6px; border-left: 2px solid #ccc;}
|
div.attachments {padding-left: 6px; border-left: 2px solid #ccc; margin-bottom: 8px;}
|
||||||
|
div.attachments p {margin-bottom:2px;}
|
||||||
|
|
||||||
.overlay{
|
.overlay{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
Loading…
Reference in New Issue