Merge pull request #678 from warpc/579-code_line_comments
[refs #579] code line comments
This commit is contained in:
commit
00e92d9672
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
|
@ -1,17 +1,19 @@
|
|||
$(document).ready(function() {
|
||||
$('.buttons a.edit_comment').live('click', function() {
|
||||
$(this).parent().parent().parent().hide();
|
||||
$('#open-comment'+'.comment.'+$(this).attr('id')).show();
|
||||
var new_comment = $('#open-comment.comment.hidden.new_line_comment');
|
||||
|
||||
$(document).on('click', '.buttons a.edit_comment', function() {
|
||||
$(this).parents('div.activity').hide()
|
||||
.next().show();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.cancel_edit_comment.button').live('click', function() {
|
||||
$(this).parent().parent().parent().hide();
|
||||
$('.buttons a.edit_comment#'+$(this).attr('id')).parent().parent().parent().show();
|
||||
$(document).on('click', '.cancel_edit_comment.button', function() {
|
||||
$(this).parents('#open-comment.comment').hide()
|
||||
.prev().show();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('form.edit_comment').live('submit', function() {
|
||||
$(document).on('submit', 'form.edit_comment', function() {
|
||||
var form = $(this);
|
||||
form.parent().find('.flash').remove();
|
||||
$.ajax({
|
||||
|
@ -20,8 +22,9 @@ $(document).ready(function() {
|
|||
data: form.serialize(),
|
||||
success: function(data){
|
||||
var cancel_button = form.find('.cancel_edit_comment.button');
|
||||
var id = cancel_button.attr('id').match(/\d+$/)[0];
|
||||
cancel_button.click();
|
||||
$('.buttons a.edit_comment#'+cancel_button.attr('id')).parent().parent().find('.cm-s-default.md_and_cm').html(data).find('code').each(function (code) { CodeMirrorRun(this); })
|
||||
$('#comment'+id+', #diff-comment'+id).parent().find('.cm-s-default.md_and_cm').html(data).find('code').each(function (code) { CodeMirrorRun(this); })
|
||||
},
|
||||
error: function(data){
|
||||
form.before(data.responseText);
|
||||
|
@ -30,5 +33,69 @@ $(document).ready(function() {
|
|||
return false;
|
||||
});
|
||||
|
||||
$('.new_inline_comment.button').on('click', function() {
|
||||
$(this).parents('tr').prev('tr').find("a[href='"+$(this).attr('href')+"']").click();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.add_line-comment').on('click', function() {
|
||||
function ProcessData(data) {
|
||||
if(yield) {
|
||||
var str = "<tr class='inline-comments'><td class='line_numbers' colspan='2'></td>"+"<td>"+data+"</td></tr>";
|
||||
par.after(str);
|
||||
par = par.next();
|
||||
}
|
||||
else {
|
||||
par.find('td:last').append(data);
|
||||
}
|
||||
par.find('#md_tabs.nav.nav-tabs').each(function(i) {
|
||||
$(this).find('a:first').tab('show');
|
||||
$(this).parent().find('#new_line_edit_input').focus();
|
||||
});
|
||||
}
|
||||
var line = $(this);
|
||||
var tmp = line.parents('tr');
|
||||
var yield = false;
|
||||
var par = null;
|
||||
|
||||
if(tmp.hasClass('inline-comments')) {
|
||||
par = tmp;
|
||||
}
|
||||
else {
|
||||
par = tmp.next('tr.inline-comments');
|
||||
}
|
||||
|
||||
if(par.length == 0) {
|
||||
par = tmp;
|
||||
yield = true;
|
||||
}
|
||||
|
||||
// Hide visible new comment form
|
||||
$('#open-comment.new_line_comment').parents('.inline-comments').each(function(i) {
|
||||
if($(this).find('.line-comments').length > 0) {
|
||||
$(this).find('#open-comment.new_line_comment').remove();
|
||||
$(this).find('.new_inline_comment.button').show();
|
||||
}
|
||||
else {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
par.find('.new_inline_comment.button').hide();
|
||||
|
||||
$.get(line.attr('href'), null, ProcessData);
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('click', '.cancel_inline_comment.button', function() {
|
||||
var tr = $(this).parents('.inline-comments');
|
||||
if(tr.find('.line-comments').length > 0) {
|
||||
tr.find('#open-comment.new_line_comment').remove();
|
||||
tr.find('.new_inline_comment.button').show();
|
||||
}
|
||||
else {
|
||||
tr.remove();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ $(document).ready(function() {
|
|||
var preview_url = $('#preview_url').val();
|
||||
$('#md_tabs.nav.nav-tabs').each(function(i) { $(this).find('a:first').tab('show') });
|
||||
|
||||
$('#md_tabs a[data-toggle="tab"]').on('shown', function (e) {
|
||||
$(document).on('shown','#md_tabs a[data-toggle="tab"]', function (e) {
|
||||
if(e.relatedTarget) { var hash = e.relatedTarget.hash; }
|
||||
else { var hash = e.currentTarget.hash; }
|
||||
var el = $(hash+'_input');
|
||||
|
|
|
@ -24,4 +24,9 @@ $(document).ready(function() {
|
|||
location.hash = href;
|
||||
}
|
||||
});
|
||||
|
||||
var diff_tab = $('#pull_tabs a[href="#diff"]');
|
||||
$('.link_to_full_changes').on('click', function(){
|
||||
diff_tab.tab('show');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -119,6 +119,7 @@ div.activity, .commits_activity {
|
|||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.data-expander.collapsed {
|
||||
background: #FFF image-url('expand-gray.png') no-repeat;
|
||||
|
@ -1612,6 +1613,48 @@ table.tablesorter.platform-maintainers.static-search thead tr.search th input[ty
|
|||
}
|
||||
}
|
||||
|
||||
#repo-wrapper .add_line-comment {
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 18px;
|
||||
margin-left: -103px;
|
||||
margin-top: 0;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
filter: alpha(Opacity=0);
|
||||
-moz-opacity:0;
|
||||
}
|
||||
|
||||
#repo-wrapper tr:hover .add_line-comment {
|
||||
opacity: 1;
|
||||
filter: alpha(Opacity=100);
|
||||
-moz-opacity:1;
|
||||
}
|
||||
|
||||
div.file .inline-comments {
|
||||
.top {
|
||||
height:auto;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.activity {
|
||||
border-radius: 0;
|
||||
max-width: 752px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
tr.inline-comments td {
|
||||
border: solid #DDD;
|
||||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
.inline-comments #open-comment {
|
||||
max-width: 754px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#repo-wrapper .edit_form.issue div.comment div.wrapper {
|
||||
background: 0;
|
||||
border: 0;
|
||||
|
@ -1654,10 +1697,15 @@ form#new_pull_request {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.new_inline_comment.button {
|
||||
margin: 10px 0 10px 10px;
|
||||
}
|
||||
|
||||
.niceRadio input {
|
||||
display:none;
|
||||
}
|
||||
|
||||
table#myTable thead tr.search th form.button_to div input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,19 +4,22 @@ class Projects::CommentsController < Projects::BaseController
|
|||
load_and_authorize_resource :project
|
||||
before_filter :find_commentable
|
||||
before_filter :find_or_build_comment
|
||||
load_and_authorize_resource #:through => :commentable
|
||||
load_and_authorize_resource :new => :new_line
|
||||
|
||||
include CommentsHelper
|
||||
|
||||
def create
|
||||
if @comment.save
|
||||
anchor = ''
|
||||
if !@comment.set_additional_data params
|
||||
flash[:error] = I18n.t("flash.comment.save_error")
|
||||
elsif @comment.save
|
||||
flash[:notice] = I18n.t("flash.comment.saved")
|
||||
redirect_to project_commentable_path(@project, @commentable)
|
||||
anchor = view_context.comment_anchor(@comment)
|
||||
else
|
||||
flash[:error] = I18n.t("flash.comment.save_error")
|
||||
flash[:warning] = @comment.errors.full_messages.join('. ')
|
||||
redirect_to project_commentable_path(@project, @commentable)
|
||||
end
|
||||
redirect_to "#{project_commentable_path(@project, @commentable)}##{anchor}"
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -37,6 +40,11 @@ class Projects::CommentsController < Projects::BaseController
|
|||
redirect_to project_commentable_path(@project, @commentable)
|
||||
end
|
||||
|
||||
def new_line
|
||||
@path = view_context.project_commentable_comments_path(@project, @commentable)
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def find_commentable
|
||||
|
|
|
@ -9,10 +9,12 @@ class Projects::Git::CommitsController < Projects::Git::BaseController
|
|||
end
|
||||
|
||||
def show
|
||||
@commit = @project.repo.commit(params[:id])
|
||||
@commit = @commentable = @project.repo.commit(params[:id]) || raise(ActiveRecord::RecordNotFound)
|
||||
@comments, @diff = Comment.for_commit(@commit), @commit.diffs
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.diff { render :text => (@commit.diffs.map(&:diff).join("\n") rescue ''), :content_type => "text/plain" }
|
||||
format.diff { render :text => (@diff.map(&:diff).join("\n") rescue ''), :content_type => "text/plain" }
|
||||
format.patch { render :text => (@commit.to_patch rescue ''), :content_type => "text/plain" }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,7 +104,7 @@ class Projects::ProjectsController < Projects::BaseController
|
|||
end
|
||||
|
||||
def preview
|
||||
render :inline => view_context.markdown(params[:text]), :layout => false
|
||||
render :inline => view_context.markdown(params[:text] || ''), :layout => false
|
||||
end
|
||||
|
||||
def refs_list
|
||||
|
|
|
@ -128,16 +128,12 @@ class Projects::PullRequestsController < Projects::BaseController
|
|||
end
|
||||
|
||||
def load_diff_commits_data
|
||||
repo = Grit::Repo.new(@pull.path)
|
||||
@base_commit = @pull.common_ancestor
|
||||
@head_commit = repo.commits(@pull.head_branch).first
|
||||
|
||||
@commits = repo.commits_between(repo.commits(@pull.to_ref).first, @head_commit)
|
||||
@commits = @pull.repo.commits_between(@pull.to_commit, @pull.from_commit)
|
||||
@total_commits = @commits.count
|
||||
@commits = @commits.last(100)
|
||||
|
||||
@diff = @pull.diff repo, @base_commit, @head_commit
|
||||
@stats = @pull.diff_stats repo, @base_commit, @head_commit
|
||||
@diff, @stats = @pull.diff, @pull.diff_stats
|
||||
@comments, @commentable = @issue.comments, @issue
|
||||
end
|
||||
|
||||
def find_destination_project bang=true
|
||||
|
|
|
@ -1,20 +1,30 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
module CommentsHelper
|
||||
def project_commentable_comment_path(project, commentable, comment)
|
||||
case
|
||||
when Comment.issue_comment?(commentable.class)
|
||||
if Comment.issue_comment?(commentable.class)
|
||||
project_issue_comment_path(project, commentable, comment)
|
||||
when Comment.commit_comment?(commentable.class)
|
||||
elsif Comment.commit_comment?(commentable.class)
|
||||
project_commit_comment_path(project, commentable, comment)
|
||||
end
|
||||
end
|
||||
|
||||
def project_commentable_path(project, commentable)
|
||||
case
|
||||
when Comment.issue_comment?(commentable.class)
|
||||
if Comment.issue_comment?(commentable.class)
|
||||
polymorphic_path [project, commentable.pull_request ? commentable.pull_request : commentable]
|
||||
when Comment.commit_comment?(commentable.class)
|
||||
elsif Comment.commit_comment?(commentable.class)
|
||||
commit_path project, commentable.id
|
||||
end
|
||||
end
|
||||
|
||||
def project_commentable_comments_path(project, commentable)
|
||||
if commentable.is_a? Issue
|
||||
project_issue_comments_path(@project, @commentable)
|
||||
elsif commentable.is_a? Grit::Commit
|
||||
project_commit_comments_path(@project, @commentable)
|
||||
end
|
||||
end
|
||||
|
||||
def comment_anchor c
|
||||
"#{(c.data.present? && c.actual_inline_comment?(@diff)) ? 'diff-' : ''}comment#{c.id}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,23 +1,5 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
module DiffHelper
|
||||
|
||||
def render_diff(diff, diff_counter)
|
||||
diff_display ||= Diff::Display::Unified.new(diff.diff)
|
||||
path = if @pull
|
||||
@pull.id ? polymorphic_path([@project, @pull]) : ''
|
||||
elsif @commit
|
||||
commit_path @project, @commit
|
||||
end
|
||||
|
||||
res = "<table class='diff inline' cellspacing='0' cellpadding='0'>"
|
||||
res += "<tbody>"
|
||||
res += diff_display.render(Git::Diff::InlineCallback.new(diff_counter, path))
|
||||
res += "</tbody>"
|
||||
res += "</table>"
|
||||
|
||||
res.html_safe
|
||||
end
|
||||
|
||||
def render_diff_stats(stats)
|
||||
path = @pull.id ? polymorphic_path([@project, @pull]) : ''
|
||||
res = ["<table class='commit_stats'>"]
|
||||
|
@ -38,4 +20,248 @@ module DiffHelper
|
|||
res.join("\n").html_safe.default_encoding!
|
||||
end
|
||||
|
||||
#include Git::Diff::InlineCallback
|
||||
def render_diff(diff, args = {})#diff_counter, comments, opts = nil diffpath = nil)
|
||||
if diff.respond_to?(:diff)
|
||||
diff, filepath, in_discussion = diff.diff, diff.a_path, false
|
||||
comments = (args[:comments] || []).select{|c| c.data.try('[]', :path) == filepath}
|
||||
else
|
||||
filepath, in_discussion, comments = args[:diffpath], true, args[:comments]
|
||||
end
|
||||
|
||||
diff_display ||= Diff::Display::Unified.new(diff)
|
||||
url = if @pull
|
||||
@pull.id ? polymorphic_path([@project, @pull]) : ''
|
||||
elsif @commit
|
||||
commit_path @project, @commit
|
||||
end
|
||||
prepare(args.merge({:filepath => filepath, :comments => comments, :in_discussion => in_discussion}))
|
||||
|
||||
res = "<table class='diff inline' cellspacing='0' cellpadding='0'>"
|
||||
res += "<tbody>"
|
||||
res += renderer diff_display.data #diff_display.render(Git::Diff::InlineCallback.new comments, path)
|
||||
res += tr_line_comments(comments) if in_discussion
|
||||
res += "</tbody>"
|
||||
res += "</table>"
|
||||
res.html_safe
|
||||
end
|
||||
|
||||
########################################################
|
||||
# FIXME: Just to dev, remove to lib. Really need it?
|
||||
########################################################
|
||||
def prepare(args)
|
||||
@url, @diff_counter, @in_discussion = args[:url], args[:diff_counter], args[:in_discussion]
|
||||
@filepath, @line_comments, @in_wiki = args[:filepath], args[:comments], args[:in_wiki]
|
||||
@add_reply_id, @num_line = if @in_discussion
|
||||
[@line_comments[0].id, @line_comments[0].data[:line].to_i - @line_comments[0].data[:strings].lines.count.to_i-1]
|
||||
else
|
||||
[nil, -1]
|
||||
end
|
||||
end
|
||||
|
||||
def headerline(line)
|
||||
set_line_number
|
||||
"<tr class='header'>
|
||||
<td class='line_numbers'>...</td>
|
||||
<td class='line_numbers'>...</td>
|
||||
<td class='header'>#{line}</td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def addline(line)
|
||||
set_line_number
|
||||
"<tr class='changes'>
|
||||
<td class='line_numbers'></td>
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code ins'>
|
||||
#{line_comment}
|
||||
<pre>#{render_line(line)}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
#{render_line_comments}"
|
||||
end
|
||||
|
||||
def remline(line)
|
||||
set_line_number
|
||||
"<tr class='changes'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
<td class='line_numbers'></td>
|
||||
<td class='code del'>
|
||||
#{line_comment}
|
||||
<pre>#{render_line(line)}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
#{render_line_comments}"
|
||||
end
|
||||
|
||||
def modline(line)
|
||||
set_line_number
|
||||
"<tr clas='chanes line'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code unchanged modline'>
|
||||
#{line_comment}
|
||||
<pre>#{render_line(line)}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
#{render_line_comments}"
|
||||
end
|
||||
|
||||
def unmodline(line)
|
||||
set_line_number
|
||||
"<tr class='changes unmodline'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code unchanged unmodline'>
|
||||
#{line_comment}
|
||||
<pre>#{render_line(line)}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
#{render_line_comments}"
|
||||
end
|
||||
|
||||
def sepline(line)
|
||||
"<tr class='changes hunk-sep'>
|
||||
<td class='line_numbers line_num_cut'>…</td>
|
||||
<td class='line_numbers line_num_cut'>…</td>
|
||||
<td class='code cut-line'></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def nonewlineline(line)
|
||||
set_line_number
|
||||
"<tr class='changes'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code modline unmodline'>
|
||||
#{line_comment}
|
||||
<pre>#{render_line(line)}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
#{render_line_comments}"
|
||||
end
|
||||
|
||||
def before_headerblock(block)
|
||||
end
|
||||
|
||||
def after_headerblock(block)
|
||||
end
|
||||
|
||||
def before_unmodblock(block)
|
||||
end
|
||||
|
||||
def before_modblock(block)
|
||||
end
|
||||
|
||||
def before_remblock(block)
|
||||
end
|
||||
|
||||
def before_addblock(block)
|
||||
end
|
||||
|
||||
def before_sepblock(block)
|
||||
end
|
||||
|
||||
def before_nonewlineblock(block)
|
||||
end
|
||||
|
||||
def after_unmodblock(block)
|
||||
end
|
||||
|
||||
def after_modblock(block)
|
||||
end
|
||||
|
||||
def after_remblock(block)
|
||||
end
|
||||
|
||||
def after_addblock(block)
|
||||
end
|
||||
|
||||
def after_sepblock(block)
|
||||
end
|
||||
|
||||
def after_nonewlineblock(block)
|
||||
end
|
||||
|
||||
def new_line
|
||||
""
|
||||
end
|
||||
|
||||
def renderer(data)
|
||||
result = []
|
||||
data.each do |block|
|
||||
result << send("before_" + classify(block), block)
|
||||
result << block.map { |line| send(classify(line), line) }
|
||||
result << send("after_" + classify(block), block)
|
||||
end
|
||||
result.compact.join(new_line)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def classify(object)
|
||||
object.class.name[/\w+$/].downcase
|
||||
end
|
||||
|
||||
def escape(str)
|
||||
str.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>').gsub('"', '"')
|
||||
end
|
||||
|
||||
def render_line(line)
|
||||
res = '<span class="diff-content">'
|
||||
if line.inline_changes?
|
||||
prefix, changed, postfix = line.segments.map{|segment| escape(segment) }
|
||||
res += "#{prefix}<span class='idiff'>#{changed}</span>#{postfix}"
|
||||
else
|
||||
res += escape(line)
|
||||
end
|
||||
res += '</span>'
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def set_line_number
|
||||
@num_line = @num_line.succ
|
||||
end
|
||||
|
||||
def line_comment
|
||||
return if @in_wiki || (@in_discussion && @add_reply_id && @line_comments[0].data[:line].to_i != @num_line)
|
||||
link_to image_tag('line_comment.png', :alt => t('layout.comments.new_header')), new_comment_path, :class => 'add_line-comment'
|
||||
end
|
||||
|
||||
def render_line_comments
|
||||
unless @in_wiki || @in_discussion
|
||||
comments = @line_comments.select do |c|
|
||||
c.data.try('[]', :line) == @num_line.to_s && c.actual_inline_comment?(@diff)
|
||||
end
|
||||
tr_line_comments(comments) if comments.count > 0
|
||||
end
|
||||
end
|
||||
|
||||
def td_line_link id, num
|
||||
"<td class='line_numbers' id='#{id}'><a href='#{@url}##{id}'>#{num}</a></td>"
|
||||
end
|
||||
|
||||
def tr_line_comments comments
|
||||
return if @in_wiki
|
||||
res="<tr class='inline-comments'>
|
||||
<td class='line_numbers' colspan='2'>#{comments.count}</td>
|
||||
<td>"
|
||||
comments.each do |comment|
|
||||
res << "<div class='line-comments'>
|
||||
#{render 'projects/comments/comment', :comment => comment, :data => {:project => @project, :commentable => @commentable, :add_anchor => 'inline', :in_discussion => @in_discussion}}
|
||||
</div>"
|
||||
end
|
||||
res << link_to(t('layout.comments.new_inline'), new_comment_path, :class => 'new_inline_comment button')
|
||||
res << "</td></tr>"
|
||||
end
|
||||
|
||||
def new_comment_path
|
||||
hash = {:path => @filepath, :line => @num_line}
|
||||
if @commentable.is_a? Issue
|
||||
project_new_line_pull_comment_path(@project, @commentable, hash.merge({:in_reply => @add_reply_id}))
|
||||
elsif @commentable.is_a? Grit::Commit
|
||||
new_line_commit_comment_path(@project, @commentable, hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
module PullRequestHelper
|
||||
def merge_activity comments, commits
|
||||
issue_comments = @issue.comments.map{ |c| [c.created_at, c] }
|
||||
commits = @commits.map{ |c| [(c.committed_date || c.authored_date), c] }
|
||||
(issue_comments + commits).sort_by{ |c| c[0] }.map{ |c| c[1] }
|
||||
common_comments, pull_comments = comments.partition {|c| c.data.blank?}
|
||||
common_comments = common_comments.map{ |c| [c.created_at, c] }
|
||||
pull_comments = pull_comments.group_by(&:data).map{|data, c| [c.first.created_at, [data || {}, [c].flatten]]}
|
||||
commits = commits.map{ |c| [(c.committed_date || c.authored_date), c] }
|
||||
(common_comments + pull_comments + commits).sort_by{ |c| c[0] }.map{ |c| c[1] }
|
||||
end
|
||||
|
||||
def pull_status_label pull
|
||||
|
|
|
@ -133,8 +133,8 @@ class Ability
|
|||
can :create, PullRequest
|
||||
can([:update, :merge], PullRequest) {|pull| pull.user_id == user.id or local_admin?(pull.to_project)}
|
||||
|
||||
can(:create, Comment) {|comment| can? :read, comment.project}
|
||||
can(:update, Comment) {|comment| comment.user == user or comment.project.owner == user or local_admin?(comment.project)}
|
||||
can([:create, :new_line], Comment) {|comment| can? :read, comment.project}
|
||||
can([:update, :destroy], Comment) {|comment| comment.user == user or comment.project.owner == user or local_admin?(comment.project)}
|
||||
cannot :manage, Comment do |c|
|
||||
c.commentable_type == 'Issue' && !c.project.has_issues && !c.commentable.pull_request # when switch off issues
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@ class Comment < ActiveRecord::Base
|
|||
belongs_to :commentable, :polymorphic => true
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
serialize :data
|
||||
|
||||
validates :body, :user_id, :commentable_id, :commentable_type, :project_id, :presence => true
|
||||
|
||||
|
@ -12,7 +13,7 @@ class Comment < ActiveRecord::Base
|
|||
after_create :subscribe_on_reply, :unless => lambda {|c| c.commit_comment?}
|
||||
after_create :subscribe_users
|
||||
|
||||
attr_accessible :body
|
||||
attr_accessible :body, :data
|
||||
|
||||
def commentable
|
||||
# raise commentable_id.inspect
|
||||
|
@ -53,6 +54,79 @@ class Comment < ActiveRecord::Base
|
|||
User.find(subscribe.user).notifier.new_comment && User.find(subscribe.user).notifier.can_notify
|
||||
end
|
||||
|
||||
def actual_inline_comment?(diff, force = false)
|
||||
unless force
|
||||
raise "This is not inline comment!" if data.blank? # for debug
|
||||
return data[:actual] unless data[:actual].nil?
|
||||
end
|
||||
filepath, line_number = data[:path], data[:line]
|
||||
diff_path = (diff || commentable.diffs ).select {|d| d.a_path == data[:path]}
|
||||
comment_line = data[:line].to_i
|
||||
# NB! also dont create a comment to the diff header
|
||||
return data[:actual] = false if diff_path.blank? || comment_line == 0
|
||||
return data[:actual] = true if commentable_type == 'Grit::Commit'
|
||||
res, ind = true, 0
|
||||
diff_path[0].diff.each_line do |line|
|
||||
if self.persisted? && (comment_line-2..comment_line+2).include?(ind) && data.try('[]', "line#{ind-comment_line}") != line.chomp
|
||||
break res = false
|
||||
end
|
||||
ind = ind + 1
|
||||
end
|
||||
if ind < comment_line
|
||||
return data[:actual] = false
|
||||
else
|
||||
return data[:actual] = res
|
||||
end
|
||||
end
|
||||
|
||||
def inline_diff
|
||||
data[:strings] + data['line0']
|
||||
end
|
||||
|
||||
def pull_comment?
|
||||
return true if commentable.is_a?(Issue) && commentable.pull_request.present?
|
||||
end
|
||||
|
||||
def set_additional_data params
|
||||
return true if params[:path].blank? && params[:line].blank? # not inline comment
|
||||
if params[:in_reply].present? && reply = Comment.where(:id => params[:in_reply]).first
|
||||
self.data = reply.data
|
||||
return true
|
||||
end
|
||||
self.data = {:path => params[:path], :line => params[:line]}
|
||||
if commentable.is_a?(Issue) && pull = commentable.pull_request
|
||||
diff_path = pull.diff.select {|d| d.a_path == params[:path]}
|
||||
return false unless actual_inline_comment?(pull.diff, true)
|
||||
|
||||
comment_line, line_number, strings = params[:line].to_i, -1, []
|
||||
diff_path[0].diff.each_line do |line|
|
||||
line_number = line_number.succ
|
||||
# Save 2 lines above and bottom of the diff comment line
|
||||
break if line_number > comment_line + 2
|
||||
if (comment_line-2..comment_line+2).include? line_number
|
||||
data["line#{line_number-comment_line}"] = line.chomp
|
||||
end
|
||||
|
||||
# Save lines from the closest header for rendering in the discussion
|
||||
if line_number < comment_line
|
||||
# Header is the line like "@@ -47,9 +50,8 @@ def initialize(user)"
|
||||
if line =~ Diff::Display::Unified::Generator::LINE_NUM_RE
|
||||
strings = [line]
|
||||
else
|
||||
strings << line
|
||||
end
|
||||
end
|
||||
end
|
||||
## Bug with numbers of diff lines, now store all diff
|
||||
data[:strings] = strings.join
|
||||
# Limit stored diff to 10 lines (see inline_diff)
|
||||
#data[:strings] = ((strings.count) <= 9 ? strings : [strings[0]] + strings.last(8)).join
|
||||
##
|
||||
data[:view_path] = h(diff_path[0].renamed_file ? "#{diff_path[0].a_path.rtruncate 60} -> #{diff_path[0].b_path.rtruncate 60}" : diff_path[0].a_path.rtruncate(120))
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def subscribe_on_reply
|
||||
|
|
|
@ -20,10 +20,6 @@ class PullRequest < ActiveRecord::Base
|
|||
scope :needed_checking, includes(:issue).where(:issues => {:status => ['open', 'blocked', 'ready']})
|
||||
|
||||
state_machine :status, :initial => :open do
|
||||
#after_transition [:ready, :blocked] => [:merged, :closed] do |pull, transition|
|
||||
# FileUtils.rm_rf(pull.path) # What about diff?
|
||||
#end
|
||||
|
||||
event :ready do
|
||||
transition [:ready, :open, :blocked] => :ready
|
||||
end
|
||||
|
@ -65,11 +61,8 @@ class PullRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
if do_transaction
|
||||
if new_status == 'already'
|
||||
ready; merging
|
||||
else
|
||||
send(new_status)
|
||||
end
|
||||
new_status == 'already' ? (ready; merging) : send(new_status)
|
||||
self.update_inline_comments
|
||||
else
|
||||
self.status = new_status == 'block' ? 'blocked' : new_status
|
||||
end
|
||||
|
@ -93,7 +86,7 @@ class PullRequest < ActiveRecord::Base
|
|||
File.join(APP_CONFIG['root_path'], 'pull_requests', to_project.owner.uname, to_project.name, filename)
|
||||
end
|
||||
|
||||
def head_branch
|
||||
def from_branch
|
||||
if to_project != from_project
|
||||
"head_#{from_ref}"
|
||||
else
|
||||
|
@ -103,16 +96,15 @@ class PullRequest < ActiveRecord::Base
|
|||
|
||||
def common_ancestor
|
||||
return @common_ancestor if @common_ancestor
|
||||
repo = Grit::Repo.new(path)
|
||||
base_commit = repo.commits(to_ref).first
|
||||
head_commit = repo.commits(head_branch).first
|
||||
@common_ancestor = repo.commit(repo.git.merge_base({}, base_commit, head_commit)) || base_commit
|
||||
@common_ancestor = repo.commit(repo.git.merge_base({}, base_commit, from_commit)) || base_commit
|
||||
end
|
||||
alias_method :to_commit, :common_ancestor
|
||||
|
||||
def diff_stats(repo, a,b)
|
||||
def diff_stats
|
||||
stats = []
|
||||
Dir.chdir(path) do
|
||||
lines = repo.git.native(:diff, {:numstat => true, :M => true}, "#{a.id}...#{b.id}").split("\n")
|
||||
lines = repo.git.native(:diff, {:numstat => true, :M => true}, "#{to_commit.id}...#{from_commit.id}").split("\n")
|
||||
while !lines.empty?
|
||||
files = []
|
||||
while lines.first =~ /^([-\d]+)\s+([-\d]+)\s+(.+)/
|
||||
|
@ -127,15 +119,16 @@ class PullRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
# FIXME maybe move to warpc/grit?
|
||||
def diff(repo, a, b)
|
||||
diff = repo.git.native('diff', {:M => true}, "#{a}...#{b}")
|
||||
def diff
|
||||
return @diff if @diff.present?
|
||||
diff = repo.git.native('diff', {:M => true}, "#{to_commit.id}...#{from_commit.id}")
|
||||
|
||||
if diff =~ /diff --git a/
|
||||
diff = diff.sub(/.*?(diff --git a)/m, '\1')
|
||||
else
|
||||
diff = ''
|
||||
end
|
||||
Grit::Diff.list_from_string(repo, diff)
|
||||
@diff = Grit::Diff.list_from_string(repo, diff)
|
||||
end
|
||||
|
||||
def set_user_and_time user
|
||||
|
@ -154,12 +147,21 @@ class PullRequest < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def repo
|
||||
return @repo if @repo.present? #&& !id_changed?
|
||||
@repo = Grit::Repo.new path
|
||||
end
|
||||
|
||||
def from_commit
|
||||
repo.commits(from_branch).first
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def merge
|
||||
clone
|
||||
message = "Merge pull request ##{serial_id} from #{from_project.name_with_owner}:#{from_ref}\r\n #{title}"
|
||||
%x(cd #{path} && git checkout #{to_ref} && git merge --no-ff #{head_branch} -m '#{message}')
|
||||
%x(cd #{path} && git checkout #{to_ref} && git merge --no-ff #{from_branch} -m '#{message}')
|
||||
end
|
||||
|
||||
def clone
|
||||
|
@ -175,7 +177,7 @@ class PullRequest < ActiveRecord::Base
|
|||
system 'git', 'remote', 'add', 'head', from_project.path
|
||||
end
|
||||
end
|
||||
clean
|
||||
clean # Need testing
|
||||
end
|
||||
|
||||
Dir.chdir(path) do
|
||||
|
@ -185,7 +187,7 @@ class PullRequest < ActiveRecord::Base
|
|||
system 'git', 'checkout', from_ref
|
||||
system 'git', 'pull', 'origin', from_ref
|
||||
else
|
||||
system 'git', 'fetch', 'head', "+#{from_ref}:#{head_branch}"
|
||||
system 'git', 'fetch', 'head', "+#{from_ref}:#{from_branch}"
|
||||
end
|
||||
end
|
||||
# TODO catch errors
|
||||
|
@ -197,10 +199,10 @@ class PullRequest < ActiveRecord::Base
|
|||
system 'git', 'checkout', to_ref
|
||||
|
||||
to_project.repo.branches.each do |branch|
|
||||
system 'git', 'branch', '-D', branch.name unless [to_ref, head_branch].include? branch.name
|
||||
system 'git', 'branch', '-D', branch.name unless [to_ref, from_branch].include? branch.name
|
||||
end
|
||||
to_project.repo.tags.each do |tag|
|
||||
system 'git', 'tag', '-d', tag.name unless [to_ref, head_branch].include? tag.name
|
||||
system 'git', 'tag', '-d', tag.name unless [to_ref, from_branch].include? tag.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -208,4 +210,13 @@ class PullRequest < ActiveRecord::Base
|
|||
def clean_dir
|
||||
FileUtils.rm_rf path
|
||||
end
|
||||
|
||||
def update_inline_comments
|
||||
self.comments.each do |c|
|
||||
if c.data.present? # maybe need add new column 'actual'?
|
||||
c.actual_inline_comment? diff, true
|
||||
c.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,24 +27,17 @@ class CommentPresenter < ApplicationPresenter
|
|||
def caption?
|
||||
false
|
||||
end
|
||||
def buttons
|
||||
project = options[:project]
|
||||
commentable = options[:commentable]
|
||||
(ep, dp) = if Comment.issue_comment?(commentable.class)
|
||||
[edit_project_issue_comment_path(project, commentable, comment),
|
||||
project_issue_comment_path(project, commentable, comment)]
|
||||
elsif Comment.commit_comment?(commentable.class)
|
||||
[edit_project_commit_comment_path(project, commentable, comment),
|
||||
project_commit_comment_path(project, commentable, comment)]
|
||||
end
|
||||
|
||||
res = []
|
||||
def buttons
|
||||
project, commentable = options[:project], options[:commentable]
|
||||
path = helpers.project_commentable_comment_path(project, commentable, comment)
|
||||
|
||||
res = [link_to(t("layout.link"), "#{helpers.project_commentable_path(project, commentable)}##{comment_anchor}", :class => "#{@options[:in_discussion].present? ? 'in_discussion_' : ''}link_to_comment").html_safe]
|
||||
if controller.can? :update, @comment
|
||||
res << link_to(t('layout.comments.md_cheatsheet_header'), '#md_help', 'data-toggle' => 'modal')
|
||||
res << link_to(t("layout.edit"), ep, :id => "comment-#{comment.id}", :class => "edit_comment").html_safe
|
||||
res << link_to(t("layout.edit"), path, :id => "comment-#{comment.id}", :class => "edit_comment").html_safe
|
||||
end
|
||||
if controller.can? :delete, @comment
|
||||
res << link_to(t("layout.delete"), dp, :method => "delete",
|
||||
if controller.can? :destroy, @comment
|
||||
res << link_to(t("layout.delete"), path, :method => "delete",
|
||||
:confirm => t("layout.comments.confirm_delete")).html_safe
|
||||
end
|
||||
res
|
||||
|
@ -70,4 +63,15 @@ class CommentPresenter < ApplicationPresenter
|
|||
def comment_id
|
||||
@comment.id
|
||||
end
|
||||
|
||||
def comment_anchor
|
||||
# check for pull diff inline comment
|
||||
before = if @options[:add_anchor].present? && !@options[:in_discussion]
|
||||
'diff-'
|
||||
else
|
||||
''
|
||||
end
|
||||
"#{before}comment#{@comment.id}"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.text
|
||||
%span
|
||||
= raw t("notifications.bodies.new_comment_notification.title", :user_link => link_to(user_name, user_path(user_id)) )
|
||||
= raw t("notifications.bodies.new_comment_notification.commit_content", {:commit_link => link_to(commit_message, commit_path(project_owner, project_name, commit_id) + "#comment##{comment_id}")})
|
||||
= raw t("notifications.bodies.new_comment_notification.commit_content", {:commit_link => link_to(commit_message, commit_path(project_owner, project_name, commit_id) + "#comment#{comment_id}")})
|
||||
= raw t("notifications.bodies.project", :project_link => link_to("#{project_owner}/#{project_name}", project_path(project_owner, project_name)) )
|
||||
.both
|
||||
%span.date= activity_feed.created_at
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.text
|
||||
%span
|
||||
= raw t("notifications.bodies.new_comment_notification.title", {:user_link => link_to(user_name, user_path(user_id))})
|
||||
= raw t("notifications.bodies.new_comment_notification.content", {:issue_link => link_to(issue_title, project_issue_path(project_owner, project_name, issue_serial_id) + "#comment##{comment_id}")})
|
||||
= raw t("notifications.bodies.new_comment_notification.content", {:issue_link => link_to(issue_title, project_issue_path(project_owner, project_name, issue_serial_id) + "#comment#{comment_id}")})
|
||||
= raw t("notifications.bodies.project", :project_link => link_to("#{project_owner}/#{project_name}", project_path(project_owner, project_name)) )
|
||||
.both
|
||||
%span.date= activity_feed.created_at
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#open-comment.comment.view
|
||||
=link_to t('layout.comments.md_cheatsheet_header'), '#md_help', 'data-toggle' => 'modal', :style => 'float:right;'
|
||||
=render 'projects/comments/button_md_help'
|
||||
%h3.tmargin0= t("layout.comments.new_header")
|
||||
- if Comment.issue_comment?(commentable.class)
|
||||
- new_path = project_issue_comments_path(project, commentable)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
=link_to t('layout.comments.md_cheatsheet_header'), '#md_help', 'data-toggle' => 'modal', :style => 'float:right;'
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
- CommentPresenter.present(comment, :project => project, :commentable => commentable) do |presenter|
|
||||
- CommentPresenter.present(comment, data) do |presenter|
|
||||
= render 'shared/feed_message', :presenter => presenter
|
||||
#open-comment.comment.hidden{:class => "comment-#{comment.id}"}
|
||||
=render 'projects/comments/button_md_help'
|
||||
%h3.tmargin0= t("layout.comments.edit_header")
|
||||
= form_for comment, :url => project_commentable_comment_path(project, commentable, comment), :html => { :class => 'form edit_comment' } do |f|
|
||||
= render "projects/comments/form", :f => f, :id => "edit_#{comment.id}"
|
||||
= form_for comment, :url => project_commentable_comment_path(data[:project], data[:commentable], comment), :html => { :class => 'form edit_comment' } do |f|
|
||||
= render "projects/comments/form", :f => f, :id => "#{data[:add_id]}edit_#{comment.id}"
|
||||
.comment-left
|
||||
=link_to t('layout.cancel'), '#', :id => "comment-#{comment.id}", :class => 'cancel_edit_comment button'
|
||||
.both
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
.hr
|
||||
%h3#block-list= t("layout.comments.comments_header")
|
||||
- list.each do |comment|
|
||||
= render 'projects/comments/comment', :comment => comment, :project => project, :commentable => commentable
|
||||
= render 'projects/comments/comment', :comment => comment, :data => {:project => project, :commentable => commentable}
|
||||
= render "projects/comments/markdown_help"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#open-comment.comment.view.new_line_comment
|
||||
=render 'projects/comments/button_md_help'
|
||||
%h3.tmargin0= t("layout.comments.new_header")
|
||||
= form_for :comment, :url => @path, :method => :post, :html => { :class => :form } do |f|
|
||||
= render "projects/comments/form", :f => f, :id => 'new_line'
|
||||
.comment-left
|
||||
=link_to t('layout.cancel'), '#', :class => 'cancel_inline_comment button'
|
||||
=hidden_field_tag :path, params[:path]
|
||||
=hidden_field_tag :line, params[:line]
|
||||
=hidden_field_tag :in_reply, params[:in_reply] if params[:in_reply].present?
|
||||
.both
|
|
@ -6,5 +6,5 @@
|
|||
- if commit_diff.b_path.present?
|
||||
.r= link_to "view file @ #{short_hash_id(commit_id)}", blob_path(@project, commit_id, commit_diff.b_path)
|
||||
.clear
|
||||
|
||||
.diff_data= render_diff(commit_diff, commit_diff_counter) unless (@project.repo.tree(commit_id) / commit_diff.b_path).binary?
|
||||
-unless (@project.repo.tree(commit_id) / commit_diff.b_path).binary?
|
||||
.diff_data=render_diff(commit_diff, :diff_counter => commit_diff_counter, :comments => @comments)
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
|
||||
-begin
|
||||
= render_commit_stats(stats)
|
||||
= render :partial => 'commit_diff', :collection => @commit.diffs
|
||||
= render :partial => 'commit_diff', :collection => @diff
|
||||
- rescue Grit::Git::GitTimeout
|
||||
%p= t 'layout.git.repositories.commit_diff_too_big'
|
||||
|
|
|
@ -2,17 +2,15 @@
|
|||
= render 'submenu'
|
||||
= render 'about_block', :project => @project
|
||||
|
||||
|
||||
%h3= t("layout.projects.last_commit")
|
||||
- GitPresenters::CommitAsMessagePresenter.present(@commit, :branch => @branch, :project => @project) do |presenter|
|
||||
= render :partial => 'shared/feed_message', :locals => {:presenter => presenter, :item_no => 1}
|
||||
|
||||
.both
|
||||
|
||||
#repo-wrapper
|
||||
= render 'show'
|
||||
|
||||
= render "projects/comments/list", :list => Comment.for_commit(@commit), :project => @project, :commentable => @commit
|
||||
-comments = @comments.select {|c| c.data.blank? } # dont work @comments.where(:data => nil)
|
||||
= render "projects/comments/list", :list => comments, :project => @project, :commentable => @commit
|
||||
= render "projects/comments/add", :project => @project, :commentable => @commit if current_user
|
||||
|
||||
=hidden_field_tag :preview_url, project_md_preview_path(@project)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
%h3.tmargin0= t 'activerecord.attributes.issue.title'
|
||||
.wrapper= f.text_area :title, :cols => 80, :rows => 1
|
||||
#open-comment.comment.view
|
||||
=link_to t('layout.comments.md_cheatsheet_header'), '#md_help', 'data-toggle' => 'modal', :style => 'float:right;'
|
||||
=render 'projects/comments/button_md_help'
|
||||
%h3.tmargin0= t 'activerecord.attributes.issue.body'
|
||||
=render 'projects/comments/body', :f => f, :id => id
|
||||
.both
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
%a{ :name => "comments" }
|
||||
.hr
|
||||
%h3#block-list= t("layout.comments.comments_header")
|
||||
-commits_queue = []
|
||||
-merge_activity(@comments, @commits).each do |item| #
|
||||
-if item.is_a? Comment
|
||||
=render 'projects/git/commits/commits_small', :commits => commits_queue if commits_queue.present?
|
||||
-commits_queue.clear
|
||||
=render 'projects/comments/comment', :comment => item, :data => {:project => @project, :commentable => @commentable}
|
||||
-elsif item.is_a? Grit::Commit
|
||||
-commits_queue << item
|
||||
-elsif item.is_a? Array
|
||||
=render 'projects/git/commits/commits_small', :commits => commits_queue if commits_queue.present?
|
||||
-commits_queue.clear
|
||||
-unless item[1].first.data[:actual]
|
||||
-exp_id = "expand-comment#{item[1].first.id}"
|
||||
.activity
|
||||
=t '.show_outdated_diff'
|
||||
%span.data-expander.collapsed{:id => exp_id}
|
||||
.hidden{:id => "content-#{exp_id}"}
|
||||
=render 'projects/pull_requests/discussion_comments', :item => item, :add_id => nil
|
||||
-else
|
||||
=render 'projects/pull_requests/discussion_comments', :item => item, :add_id => nil
|
||||
=render 'projects/git/commits/commits_small', :commits => commits_queue if commits_queue.present?
|
||||
|
||||
- commits_queue = []
|
||||
- merge_activity(@issue.comments, @commits).each do |item| #
|
||||
- if item.is_a?(Comment)
|
||||
- if commits_queue.present?
|
||||
= render 'projects/git/commits/commits_small', :commits => commits_queue
|
||||
- commits_queue = []
|
||||
= render 'projects/comments/comment', :comment => item, :project => @project, :commentable => @issue
|
||||
- else
|
||||
- commits_queue << item
|
||||
- comments_for_commit = Comment.for_commit(item)
|
||||
- if comments_for_commit.present?
|
||||
= render 'projects/git/commits/commits_small', :commits => commits_queue
|
||||
- comments_for_commit.each do |comment|
|
||||
= render 'projects/comments/comment', :comment => comment, :project => @project, :commentable => item
|
||||
- commits_queue = []
|
||||
- if commits_queue.present?
|
||||
= render 'projects/git/commits/commits_small', :commits => commits_queue
|
||||
|
||||
= render "projects/comments/markdown_help"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
-comment = item[1].first
|
||||
.file
|
||||
.top
|
||||
.l=comment.data[:view_path]
|
||||
-if comment.actual_inline_comment? @diff
|
||||
.r=link_to t("layout.pull_requests.view_full_changes"),
|
||||
"#{project_commentable_path(@project, @commentable)}##{comment_anchor(comment)}",
|
||||
:class => 'link_to_full_changes'
|
||||
-else
|
||||
.r
|
||||
=t'projects.pull_requests.outdated_diff'
|
||||
=image_tag 'x.png'
|
||||
.clear
|
||||
.diff_data=render_diff(comment.inline_diff, :diff_counter => 0, :comments => item[1], :filepath => comment.data[:path])
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
- commit_id = pull_diff.deleted_file ? @base_commit.id : @head_commit.id
|
||||
- commit_id = pull_diff.deleted_file ? @pull.to_commit.id : @pull.from_commit.id
|
||||
.file
|
||||
%a{:name => "diff-#{pull_diff_counter}"}
|
||||
.top
|
||||
|
@ -6,5 +6,5 @@
|
|||
- if pull_diff.b_path.present?
|
||||
.r= link_to "view file @ #{short_hash_id(commit_id)}", blob_path(@project, commit_id, pull_diff.b_path)
|
||||
.clear
|
||||
-if pull_diff.diff.present? && !(Grit::Repo.new(@pull.path).tree(commit_id) / pull_diff.b_path).binary?
|
||||
.diff_data= render_diff(pull_diff, pull_diff_counter)
|
||||
-if pull_diff.diff.present? && !(@pull.repo.tree(commit_id) / pull_diff.b_path).binary?
|
||||
.diff_data=render_diff(pull_diff, :diff_counter => pull_diff_counter, :comments => @comments)
|
||||
|
|
|
@ -16,4 +16,4 @@
|
|||
=render 'status'
|
||||
=render 'diff_commits_tabs' unless @pull.already?
|
||||
=hidden_field_tag :preview_url, project_md_preview_path(@project)
|
||||
|
||||
= render "projects/comments/markdown_help"
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
.top
|
||||
.l= h((diff.deleted_file ? diff.a_path : diff.b_path).rtruncate 100)
|
||||
.clear
|
||||
.diff_data.highlight= render_diff(diff, diff_counter)
|
||||
.diff_data.highlight= render_diff(diff, :diff_counter => diff_counter, :in_wiki => true)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.activity{:id => presenter.comment_id? ? "comment##{presenter.comment_id}" : ''}
|
||||
.activity{:id => presenter.comment_id? ? presenter.comment_anchor : ''}
|
||||
.top
|
||||
- if presenter.buttons?
|
||||
%span.buttons= raw presenter.buttons.join(' | ').html_safe
|
||||
|
|
|
@ -48,6 +48,7 @@ en:
|
|||
invalid_content_type: incorrect type
|
||||
atom_link_tag_title: Private feed for %{nickname} | %{app_name}
|
||||
preview: Preview
|
||||
link: Link
|
||||
|
||||
settings:
|
||||
label: Settings
|
||||
|
|
|
@ -3,6 +3,7 @@ en:
|
|||
comments:
|
||||
confirm_delete: Are you sure you want to delete the comment?
|
||||
new_header: New comment
|
||||
new_inline: Add a line comment
|
||||
edit_header: Editing a comment
|
||||
has_commented: added a note
|
||||
notifications_are: Notifications for new comments are
|
||||
|
|
|
@ -3,6 +3,7 @@ ru:
|
|||
comments:
|
||||
confirm_delete: Вы уверены, что хотите удалить комментарий?
|
||||
new_header: Новый комментарий
|
||||
new_inline: Добавить комментарий к строке
|
||||
edit_header: Редактирование комментария
|
||||
has_commented: оставил комментарий
|
||||
notifications_are: Уведомления о последующих комментариях
|
||||
|
|
|
@ -28,7 +28,9 @@ en:
|
|||
ready: Ready
|
||||
merged: Merged
|
||||
closed: Closed
|
||||
|
||||
outdated_diff: Outdated diff
|
||||
activity:
|
||||
show_outdated_diff: Show outdated_diff
|
||||
pull_requests:
|
||||
tabs:
|
||||
discussion: Discussion
|
||||
|
@ -53,3 +55,4 @@ en:
|
|||
layout:
|
||||
pull_requests:
|
||||
search: Find pull request...
|
||||
view_full_changes: View full changes
|
||||
|
|
|
@ -2,13 +2,11 @@ ru:
|
|||
projects:
|
||||
pull_requests:
|
||||
new:
|
||||
header: 'Создать пул реквест'
|
||||
header: Создать пул реквест
|
||||
submit: Создать пул реквест
|
||||
update: Обновить коммиты
|
||||
show:
|
||||
pull: Пул реквест
|
||||
into: из
|
||||
from: в
|
||||
header: Пул реквест
|
||||
status:
|
||||
close: Закрыть пул реквест
|
||||
|
@ -23,14 +21,16 @@ ru:
|
|||
%{user} смержил <span class="label-bootstrap label-info font14">%{to_ref}</span>
|
||||
с <span class="label-bootstrap label-info font14">%{from_ref}</span> в %{time}'
|
||||
closed: '%{user} закрыл пул реквест в %{time}'
|
||||
is_big: Этот пул реквест слишком большой! Мы показываем только последние %{count} комитов.
|
||||
is_big: Этот пул реквест слишком большой! Мы показываем только последние %{count} коммитов.
|
||||
open: ''
|
||||
statuses:
|
||||
blocked: Заблокирован
|
||||
ready: Готов к мержу
|
||||
merged: Смержен
|
||||
closed: Закрыт
|
||||
|
||||
outdated_diff: Устаревшие изменения
|
||||
activity:
|
||||
show_outdated_diff: Отобразить устаревшие изменения
|
||||
pull_requests:
|
||||
tabs:
|
||||
discussion: Дискуссия
|
||||
|
@ -55,3 +55,4 @@ ru:
|
|||
layout:
|
||||
pull_requests:
|
||||
search: Найти пул реквест...
|
||||
view_full_changes: Посмотреть все изменения
|
||||
|
|
|
@ -48,6 +48,7 @@ ru:
|
|||
invalid_content_type: имеет неверный тип
|
||||
atom_link_tag_title: Приватная лента для %{nickname} | %{app_name}
|
||||
preview: Предосмотр
|
||||
link: Ссылка
|
||||
|
||||
settings:
|
||||
label: 'Настройки'
|
||||
|
|
|
@ -256,6 +256,7 @@ Rosa::Application.routes.draw do
|
|||
end
|
||||
post '/preview' => 'projects#preview', :as => 'md_preview'
|
||||
post 'refs_list' => 'projects#refs_list', :as => 'refs_list'
|
||||
get '/pull_requests/:issue_id/add_line_comments(.:format)' => "comments#new_line", :as => :new_line_pull_comment
|
||||
end
|
||||
|
||||
# Resource
|
||||
|
@ -281,6 +282,7 @@ Rosa::Application.routes.draw do
|
|||
get '/commit/:commit_id/comments/:id(.:format)' => "comments#edit", :as => :edit_project_commit_comment
|
||||
put '/commit/:commit_id/comments/:id(.:format)' => "comments#update", :as => :project_commit_comment
|
||||
delete '/commit/:commit_id/comments/:id(.:format)' => "comments#destroy"
|
||||
get '/commit/:commit_id/add_line_comments(.:format)' => "comments#new_line", :as => :new_line_commit_comment
|
||||
# Commit subscribes
|
||||
post '/commit/:commit_id/subscribe' => "commit_subscribes#create", :as => :subscribe_commit
|
||||
delete '/commit/:commit_id/unsubscribe' => "commit_subscribes#destroy", :as => :unsubscribe_commit
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddDataToComments < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :comments, :data, :text
|
||||
end
|
||||
end
|
115
db/schema.rb
115
db/schema.rb
|
@ -11,14 +11,14 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20121003154246) do
|
||||
ActiveRecord::Schema.define(:version => 20121005100158) do
|
||||
|
||||
create_table "activity_feeds", :force => true do |t|
|
||||
t.integer "user_id", :null => false
|
||||
t.string "kind"
|
||||
t.text "data"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "advisories", :force => true do |t|
|
||||
|
@ -53,8 +53,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
|
||||
create_table "arches", :force => true do |t|
|
||||
t.string "name", :null => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "arches", ["name"], :name => "index_arches_on_name", :unique => true
|
||||
|
@ -63,8 +63,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.integer "user_id"
|
||||
t.string "provider"
|
||||
t.string "uid"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "authentications", ["provider", "uid"], :name => "index_authentications_on_provider_and_uid", :unique => true
|
||||
|
@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.integer "level"
|
||||
t.integer "status"
|
||||
t.integer "build_list_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "version"
|
||||
end
|
||||
|
||||
|
@ -110,8 +110,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.integer "project_id"
|
||||
t.integer "arch_id"
|
||||
t.datetime "notified_at"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.boolean "is_circle", :default => false
|
||||
t.text "additional_repos"
|
||||
t.string "name"
|
||||
|
@ -142,10 +142,11 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "commentable_type"
|
||||
t.integer "user_id"
|
||||
t.text "body"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.decimal "commentable_id", :precision => 50, :scale => 0
|
||||
t.integer "project_id"
|
||||
t.text "data"
|
||||
end
|
||||
|
||||
create_table "event_logs", :force => true do |t|
|
||||
|
@ -160,8 +161,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "controller"
|
||||
t.string "action"
|
||||
t.text "message"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "flash_notifies", :force => true do |t|
|
||||
|
@ -175,8 +176,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
|
||||
create_table "groups", :force => true do |t|
|
||||
t.integer "owner_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "uname"
|
||||
t.integer "own_projects_count", :default => 0, :null => false
|
||||
t.text "description"
|
||||
|
@ -193,8 +194,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "title"
|
||||
t.text "body"
|
||||
t.string "status", :default => "open"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.integer "user_id"
|
||||
t.datetime "closed_at"
|
||||
t.integer "closed_by"
|
||||
|
@ -254,14 +255,14 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "description"
|
||||
t.string "name", :null => false
|
||||
t.integer "parent_platform_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.boolean "released", :default => false, :null => false
|
||||
t.integer "owner_id"
|
||||
t.string "owner_type"
|
||||
t.string "visibility", :default => "open", :null => false
|
||||
t.string "platform_type", :default => "main", :null => false
|
||||
t.string "distrib_type", :null => false
|
||||
t.string "distrib_type"
|
||||
end
|
||||
|
||||
add_index "platforms", ["name"], :name => "index_platforms_on_name", :unique => true, :case_sensitive => false
|
||||
|
@ -270,16 +271,16 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.integer "platform_id"
|
||||
t.string "login"
|
||||
t.string "password"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.integer "user_id"
|
||||
end
|
||||
|
||||
create_table "product_build_lists", :force => true do |t|
|
||||
t.integer "product_id"
|
||||
t.integer "status", :default => 2, :null => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "product_build_lists", ["product_id"], :name => "index_product_build_lists_on_product_id"
|
||||
|
@ -287,8 +288,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
create_table "products", :force => true do |t|
|
||||
t.string "name", :null => false
|
||||
t.integer "platform_id", :null => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.text "build_script"
|
||||
t.text "counter"
|
||||
t.text "ks"
|
||||
|
@ -307,8 +308,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "name"
|
||||
t.string "version"
|
||||
t.datetime "file_mtime"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.integer "platform_id"
|
||||
end
|
||||
|
||||
|
@ -317,25 +318,25 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
create_table "project_to_repositories", :force => true do |t|
|
||||
t.integer "project_id"
|
||||
t.integer "repository_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "projects", :force => true do |t|
|
||||
t.string "name"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.integer "owner_id"
|
||||
t.string "owner_type"
|
||||
t.string "visibility", :default => "open"
|
||||
t.text "description"
|
||||
t.string "ancestry"
|
||||
t.boolean "has_issues", :default => true
|
||||
t.boolean "has_wiki", :default => false
|
||||
t.string "srpm_file_name"
|
||||
t.string "srpm_content_type"
|
||||
t.integer "srpm_file_size"
|
||||
t.datetime "srpm_updated_at"
|
||||
t.string "srpm_content_type"
|
||||
t.boolean "has_wiki", :default => false
|
||||
t.string "default_branch", :default => "master"
|
||||
t.boolean "is_package", :default => true, :null => false
|
||||
t.integer "average_build_time", :default => 0, :null => false
|
||||
|
@ -363,8 +364,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "token"
|
||||
t.boolean "approved", :default => false
|
||||
t.boolean "rejected", :default => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "interest"
|
||||
t.text "more"
|
||||
t.string "language"
|
||||
|
@ -378,16 +379,16 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "actor_type"
|
||||
t.integer "target_id"
|
||||
t.string "target_type"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "role"
|
||||
end
|
||||
|
||||
create_table "repositories", :force => true do |t|
|
||||
t.string "description", :null => false
|
||||
t.integer "platform_id", :null => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "name", :null => false
|
||||
t.boolean "publish_without_qa", :default => true
|
||||
end
|
||||
|
@ -399,8 +400,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.boolean "new_comment_reply", :default => true
|
||||
t.boolean "new_issue", :default => true
|
||||
t.boolean "issue_assign", :default => true
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.boolean "new_comment_commit_owner", :default => true
|
||||
t.boolean "new_comment_commit_repo_owner", :default => true
|
||||
t.boolean "new_comment_commit_commentor", :default => true
|
||||
|
@ -411,8 +412,8 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
create_table "subscribes", :force => true do |t|
|
||||
t.string "subscribeable_type"
|
||||
t.integer "user_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.boolean "status", :default => true
|
||||
t.integer "project_id"
|
||||
t.decimal "subscribeable_id", :precision => 50, :scale => 0
|
||||
|
@ -420,18 +421,21 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "name"
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :limit => 128, :default => "", :null => false
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.text "ssh_key"
|
||||
t.string "uname"
|
||||
t.string "role"
|
||||
t.string "language", :default => "en"
|
||||
t.integer "own_projects_count", :default => 0, :null => false
|
||||
t.string "language", :default => "en"
|
||||
t.integer "own_projects_count", :default => 0, :null => false
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.text "professional_experience"
|
||||
t.string "site"
|
||||
t.string "company"
|
||||
|
@ -440,14 +444,11 @@ ActiveRecord::Schema.define(:version => 20121003154246) do
|
|||
t.string "avatar_content_type"
|
||||
t.integer "avatar_file_size"
|
||||
t.datetime "avatar_updated_at"
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.string "unlock_token"
|
||||
t.datetime "locked_at"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "authentication_token"
|
||||
t.integer "build_priority", :default => 50
|
||||
t.integer "build_priority", :default => 50
|
||||
end
|
||||
|
||||
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
module Git
|
||||
module Diff
|
||||
class InlineCallback < ::Diff::Renderer::Base
|
||||
def initialize diff_counter, path
|
||||
@diff_counter = diff_counter
|
||||
@path = path
|
||||
end
|
||||
|
||||
def before_headerblock(block)
|
||||
end
|
||||
|
||||
def after_headerblock(block)
|
||||
end
|
||||
|
||||
def headerline(line)
|
||||
"<tr class='header'>
|
||||
<td class='line_numbers'>...</td>
|
||||
<td class='line_numbers'>...</td>
|
||||
<td class='header'>#{line}</td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def addline(line)
|
||||
"<tr class='changes'>
|
||||
<td class='line_numbers'></td>
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code ins'><pre>#{render_line(line)}</pre></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def remline(line)
|
||||
"<tr class='changes'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
<td class='line_numbers'></td>
|
||||
<td class='code del'><pre>#{render_line(line)}</pre></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def modline(line)
|
||||
"<tr clas='chanes line'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code unchanged modline'><pre>#{render_line(line)}</pre></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def unmodline(line)
|
||||
"<tr class='changes unmodline'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code unchanged unmodline'><pre>#{render_line(line)}</pre></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def sepline(line)
|
||||
"<tr class='changes hunk-sep'>
|
||||
<td class='line_numbers line_num_cut'>…</td>
|
||||
<td class='line_numbers line_num_cut'>…</td>
|
||||
<td class='code cut-line'></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
def nonewlineline(line)
|
||||
"<tr class='changes'>
|
||||
#{td_line_link "diff-F#{@diff_counter}L#{line.old_number}", line.old_number}
|
||||
#{td_line_link "diff-F#{@diff_counter}R#{line.new_number}", line.new_number}
|
||||
<td class='code modline unmodline'><pre>#{render_line(line)}</pre></td>
|
||||
</tr>"
|
||||
end
|
||||
|
||||
protected
|
||||
def escape(str)
|
||||
str.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>').gsub('"', '"')
|
||||
end
|
||||
|
||||
def render_line(line)
|
||||
res = '<span class="diff-content">'
|
||||
if line.inline_changes?
|
||||
prefix, changed, postfix = line.segments.map{|segment| escape(segment) }
|
||||
res += "#{prefix}<span class='idiff'>#{changed}</span>#{postfix}"
|
||||
else
|
||||
res += escape(line)
|
||||
end
|
||||
res += '</span>'
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def td_line_link id, num
|
||||
"<td class='line_numbers' id='#{id}'><a href='#{@path}##{id}'>#{num}</a></td>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue