diff unfold
This commit is contained in:
parent
fdd8e45075
commit
4e40800166
17 changed files with 164 additions and 15 deletions
1
Gemfile
1
Gemfile
|
@ -178,6 +178,7 @@ gem "gitlab_emoji", "~> 0.0.1.1"
|
|||
gem "gon", '~> 5.0.0'
|
||||
gem 'nprogress-rails'
|
||||
gem 'request_store'
|
||||
gem "virtus"
|
||||
|
||||
group :development do
|
||||
gem "annotate", "~> 2.6.0.beta2"
|
||||
|
|
|
@ -692,5 +692,6 @@ DEPENDENCIES
|
|||
unicorn (~> 4.6.3)
|
||||
unicorn-worker-killer
|
||||
version_sorter
|
||||
virtus
|
||||
webmock
|
||||
wikicloth (= 0.8.1)
|
||||
|
|
46
app/assets/javascripts/diff.js.coffee
Normal file
46
app/assets/javascripts/diff.js.coffee
Normal file
|
@ -0,0 +1,46 @@
|
|||
class Diff
|
||||
UNFOLD_COUNT = 20
|
||||
constructor: ->
|
||||
$(document).on('click', '.js-unfold', (event) =>
|
||||
target = $(event.target)
|
||||
unfoldBottom = target.hasClass('js-unfold-bottom')
|
||||
unfold = true
|
||||
|
||||
[old_line, line_number] = @lineNumbers(target.parent())
|
||||
offset = line_number - old_line
|
||||
|
||||
if unfoldBottom
|
||||
line_number += 1
|
||||
since = line_number
|
||||
to = line_number + UNFOLD_COUNT
|
||||
else
|
||||
[prev_old_line, prev_new_line] = @lineNumbers(target.parent().prev())
|
||||
line_number -= 1
|
||||
to = line_number
|
||||
if line_number - UNFOLD_COUNT > prev_new_line + 1
|
||||
since = line_number - UNFOLD_COUNT
|
||||
else
|
||||
since = prev_new_line + 1
|
||||
unfold = false
|
||||
|
||||
link = target.parents('.diff-file').attr('data-blob-diff-path')
|
||||
params =
|
||||
since: since
|
||||
to: to
|
||||
bottom: unfoldBottom
|
||||
offset: offset
|
||||
unfold: unfold
|
||||
|
||||
$.get(link, params, (response) =>
|
||||
target.parent().replaceWith(response)
|
||||
)
|
||||
)
|
||||
|
||||
lineNumbers: (line) ->
|
||||
return ([0, 0]) unless line.children().length
|
||||
lines = line.children().slice(0, 2)
|
||||
line_numbers = ($(l).attr('data-linenumber') for l in lines)
|
||||
(parseInt(line_number) for line_number in line_numbers)
|
||||
|
||||
|
||||
@Diff = Diff
|
|
@ -23,13 +23,21 @@ class Dispatcher
|
|||
new Issue()
|
||||
when 'projects:milestones:show'
|
||||
new Milestone()
|
||||
when 'projects:issues:new', 'projects:merge_requests:new'
|
||||
when 'projects:issues:new'
|
||||
GitLab.GfmAutoComplete.setup()
|
||||
when 'projects:merge_requests:new'
|
||||
GitLab.GfmAutoComplete.setup()
|
||||
new Diff()
|
||||
when 'projects:merge_requests:show'
|
||||
new Diff()
|
||||
when "projects:merge_requests:diffs"
|
||||
new Diff()
|
||||
when 'dashboard:show'
|
||||
new Dashboard()
|
||||
new Activities()
|
||||
when 'projects:commit:show'
|
||||
new Commit()
|
||||
new Diff()
|
||||
when 'groups:show', 'projects:show'
|
||||
new Activities()
|
||||
when 'projects:new', 'projects:edit'
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
background-color: #8F8;
|
||||
}
|
||||
}
|
||||
.unfold {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-mode-changed {
|
||||
padding: 10px;
|
||||
|
|
|
@ -25,6 +25,21 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def diff
|
||||
@form = UnfoldForm.new(params)
|
||||
@lines = @blob.data.lines[@form.since - 1..@form.to - 1]
|
||||
|
||||
if @form.bottom?
|
||||
@match_line = ''
|
||||
else
|
||||
lines_length = @lines.length - 1
|
||||
line = [@form.since, lines_length].join(',')
|
||||
@match_line = "@@ -#{line}+#{line} @@"
|
||||
end
|
||||
|
||||
render layout: false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def blob
|
||||
|
|
|
@ -232,4 +232,16 @@ module CommitsHelper
|
|||
def diff_file_mode_changed?(diff)
|
||||
diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
|
||||
end
|
||||
|
||||
def unfold_bottom_class(bottom)
|
||||
(bottom) ? 'js-unfold-bottom' : ''
|
||||
end
|
||||
|
||||
def view_file_btn(commit_sha, diff, project)
|
||||
link_to project_blob_path(project, tree_join(commit_sha, diff.new_path)),
|
||||
class: 'btn btn-small view-file js-view-file' do
|
||||
raw('View file @') + content_tag(:span, commit_sha[0..6],
|
||||
class: 'commit-short-id')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
19
app/views/projects/blob/diff.html.haml
Normal file
19
app/views/projects/blob/diff.html.haml
Normal file
|
@ -0,0 +1,19 @@
|
|||
- if @lines.present?
|
||||
- if @form.unfold? && @form.since != 1 && !@form.bottom?
|
||||
%tr.line_holder{ id: @form.since }
|
||||
= render "projects/commits/diffs/match_line", {line: @match_line,
|
||||
line_old: @form.since, line_new: @form.since, bottom: false}
|
||||
|
||||
- @lines.each_with_index do |line, index|
|
||||
- line_new = index + @form.since
|
||||
- line_old = line_new - @form.offset
|
||||
%tr.line_holder
|
||||
%td.old_line.diff-line-num{data: {linenumber: line_old}}
|
||||
= link_to raw(line_old), "#"
|
||||
%td.new_line= link_to raw(line_new) , "#"
|
||||
%td.line_content.noteable_line= line
|
||||
|
||||
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc
|
||||
%tr.line_holder{ id: @form.to }
|
||||
= render "projects/commits/diffs/match_line", {line: @match_line,
|
||||
line_old: @form.to, line_new: @form.to, bottom: true}
|
|
@ -1,15 +1,15 @@
|
|||
- file = project.repository.blob_for_diff(@commit, diff)
|
||||
- return unless file
|
||||
.diff-file{id: "diff-#{i}"}
|
||||
- blob_diff_path = diff_project_blob_path(project,
|
||||
tree_join(@commit.id, diff.new_path))
|
||||
.diff-file{id: "diff-#{i}", data: {blob_diff_path: blob_diff_path }}
|
||||
.diff-header{id: "file-path-#{hexdigest(diff.new_path || diff.old_path)}"}
|
||||
- if diff.deleted_file
|
||||
%span= diff.old_path
|
||||
|
||||
.diff-btn-group
|
||||
- if @commit.parent_ids.present?
|
||||
= link_to project_blob_path(project, tree_join(@commit.parent_id, diff.new_path)), { class: 'btn btn-small view-file' } do
|
||||
View file @
|
||||
%span.commit-short-id= @commit.short_id(6)
|
||||
= view_file_btn(@commit.parent_id, diff, project)
|
||||
- else
|
||||
%span= diff.new_path
|
||||
- if diff_file_mode_changed?(diff)
|
||||
|
@ -26,10 +26,7 @@
|
|||
Edit
|
||||
|
||||
|
||||
= link_to project_blob_path(project, tree_join(@commit.id, diff.new_path)), { class: 'btn btn-small view-file' } do
|
||||
View file @
|
||||
%span.commit-short-id= @commit.short_id(6)
|
||||
|
||||
= view_file_btn(@commit.id, diff, project)
|
||||
|
||||
.diff-content
|
||||
-# Skipp all non non-supported blobs
|
||||
|
|
|
@ -3,18 +3,20 @@
|
|||
%a.supp_diff_link Changes suppressed. Click to show
|
||||
|
||||
%table.text-file{class: "#{'hide' if too_big}"}
|
||||
- last_line = 0
|
||||
- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
|
||||
- last_line = line_new
|
||||
%tr.line_holder{ id: line_code, class: "#{type}" }
|
||||
- if type == "match"
|
||||
%td.old_line= "..."
|
||||
%td.new_line= "..."
|
||||
%td.line_content.matched= line
|
||||
= render "projects/commits/diffs/match_line", {line: line,
|
||||
line_old: line_old, line_new: line_new, bottom: false}
|
||||
- else
|
||||
%td.old_line
|
||||
= link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code
|
||||
- if @comments_allowed
|
||||
= link_to_new_diff_note(line_code)
|
||||
%td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code
|
||||
%td.new_line{data: {linenumber: line_new}}
|
||||
= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code
|
||||
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
|
||||
|
||||
- if @reply_allowed
|
||||
|
@ -22,6 +24,10 @@
|
|||
- unless comments.empty?
|
||||
= render "projects/notes/diff_notes_with_reply", notes: comments, line: line
|
||||
|
||||
- if last_line > 0
|
||||
= render "projects/commits/diffs/match_line", {line: "",
|
||||
line_old: last_line, line_new: last_line, bottom: true}
|
||||
|
||||
- if diff.diff.blank? && diff_file_mode_changed?(diff)
|
||||
.file-mode-changed
|
||||
File mode changed
|
||||
|
|
7
app/views/projects/commits/diffs/_match_line.html.haml
Normal file
7
app/views/projects/commits/diffs/_match_line.html.haml
Normal file
|
@ -0,0 +1,7 @@
|
|||
%td.old_line.diff-line-num.unfold.js-unfold{data: {linenumber: line_old},
|
||||
class: unfold_bottom_class(bottom)}
|
||||
\...
|
||||
%td.new_line.diff-line-num.unfold.js-unfold{data: {linenumber: line_new},
|
||||
class: unfold_bottom_class(bottom)}
|
||||
\...
|
||||
%td.line_content.matched= line
|
|
@ -193,7 +193,9 @@ Gitlab::Application.routes.draw do
|
|||
end
|
||||
|
||||
scope module: :projects do
|
||||
resources :blob, only: [:show, :destroy], constraints: {id: /.+/}
|
||||
resources :blob, only: [:show, :destroy], constraints: { id: /.+/ } do
|
||||
get :diff, on: :member
|
||||
end
|
||||
resources :raw, only: [:show], constraints: {id: /.+/}
|
||||
resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
|
||||
resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do
|
||||
|
|
|
@ -139,3 +139,11 @@ Feature: Project Merge Requests
|
|||
And I click link "Show inline discussion" of the second file
|
||||
Then I should see a comment like "Line is wrong" in the second file
|
||||
And I should still see a comment like "Line is correct" in the first file
|
||||
|
||||
@javascript
|
||||
Scenario: I unfold diff
|
||||
Given project "Shop" have "Bug NS-05" open merge request with diffs inside
|
||||
And I visit merge request page "Bug NS-05"
|
||||
And I switch to the diff tab
|
||||
And I unfold diff
|
||||
Then I should see additional file lines
|
||||
|
|
|
@ -242,6 +242,14 @@ class ProjectMergeRequests < Spinach::FeatureSteps
|
|||
end
|
||||
end
|
||||
|
||||
step 'I unfold diff' do
|
||||
first('.js-unfold').click
|
||||
end
|
||||
|
||||
step 'I should see additional file lines' do
|
||||
expect(first('.text-file')).to have_content('.bundle')
|
||||
end
|
||||
|
||||
def project
|
||||
@project ||= Project.find_by!(name: "Shop")
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ module Gitlab
|
|||
line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
|
||||
|
||||
next if line_old == 1 && line_new == 1 #top of file
|
||||
yield(full_line, type, nil, nil, nil)
|
||||
yield(full_line, type, nil, line_new, line_old)
|
||||
next
|
||||
else
|
||||
type = identification_type(line)
|
||||
|
|
5
lib/gt_one_coercion.rb
Normal file
5
lib/gt_one_coercion.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class GtOneCoercion < Virtus::Attribute
|
||||
def coerce(value)
|
||||
[1, value.to_i].max
|
||||
end
|
||||
end
|
11
lib/unfold_form.rb
Normal file
11
lib/unfold_form.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require_relative 'gt_one_coercion'
|
||||
|
||||
class UnfoldForm
|
||||
include Virtus.model
|
||||
|
||||
attribute :since, GtOneCoercion
|
||||
attribute :to, GtOneCoercion
|
||||
attribute :bottom, Boolean
|
||||
attribute :unfold, Boolean, default: true
|
||||
attribute :offset, Integer
|
||||
end
|
Loading…
Reference in a new issue