summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskv-headless <skv-headless@yandex.ru>2014-04-15 19:02:02 +0400
committerskv-headless <skv-headless@yandex.ru>2014-04-15 19:02:02 +0400
commitd859d080942175082c1a0cf34d89c0eefd1a3c39 (patch)
tree50dc1d374da6a1563a8b4958225d937e182401c5
parentcd6232187b707b0a278bd91986ec85dcfe66046f (diff)
downloadgitlab-ce-d859d080942175082c1a0cf34d89c0eefd1a3c39.tar.gz
Editing preview
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/stylesheets/generic/files.scss4
-rw-r--r--app/controllers/projects/edit_tree_controller.rb12
-rw-r--r--app/helpers/commits_helper.rb7
-rw-r--r--app/helpers/tree_helper.rb8
-rw-r--r--app/models/note.rb7
-rw-r--r--app/views/projects/edit_tree/_diff.html.haml13
-rw-r--r--app/views/projects/edit_tree/preview.html.haml26
-rw-r--r--app/views/projects/edit_tree/show.html.haml33
-rw-r--r--config/routes.rb4
-rw-r--r--db/schema.rb2
-rw-r--r--features/project/source/browse_files.feature10
-rw-r--r--features/steps/project/browse_files.rb12
-rw-r--r--lib/gitlab/diff_parser.rb20
15 files changed, 148 insertions, 19 deletions
diff --git a/Gemfile b/Gemfile
index 4ab1ab50eb9..2f1347879cd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -82,6 +82,9 @@ gem "seed-fu"
gem "redcarpet", "~> 2.2.2"
gem "github-markup"
+# Diffs
+gem 'diffy', '~> 3.0.3'
+
# Asciidoc to HTML
gem "asciidoctor"
diff --git a/Gemfile.lock b/Gemfile.lock
index 7682540eba0..60329b40a62 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -101,6 +101,7 @@ GEM
devise-async (0.8.0)
devise (>= 2.2, < 3.2)
diff-lcs (1.2.5)
+ diffy (3.0.3)
docile (1.1.1)
dotenv (0.9.0)
email_spec (1.5.0)
@@ -574,6 +575,7 @@ DEPENDENCIES
default_value_for (~> 3.0.0)
devise (= 3.0.4)
devise-async (= 0.8.0)
+ diffy (~> 3.0.3)
email_spec
email_validator (~> 1.4.0)
enumerize
@@ -644,7 +646,7 @@ DEPENDENCIES
simplecov
sinatra
six
- slack-notifier (~> 0.2.0)
+ slack-notifier (~> 0.3.2)
slim
spinach-rails
spring (= 1.1.1)
@@ -662,4 +664,4 @@ DEPENDENCIES
unicorn (~> 4.6.3)
unicorn-worker-killer
version_sorter
- webmock \ No newline at end of file
+ webmock
diff --git a/app/assets/stylesheets/generic/files.scss b/app/assets/stylesheets/generic/files.scss
index 12559f76051..6418f24d97f 100644
--- a/app/assets/stylesheets/generic/files.scss
+++ b/app/assets/stylesheets/generic/files.scss
@@ -26,6 +26,10 @@
margin-top: -5px;
}
+ .left-options {
+ margin-top: -3px;
+ }
+
.file_name {
color: $style_color;
font-size: 14px;
diff --git a/app/controllers/projects/edit_tree_controller.rb b/app/controllers/projects/edit_tree_controller.rb
index ff5206b6fa1..be611892bb0 100644
--- a/app/controllers/projects/edit_tree_controller.rb
+++ b/app/controllers/projects/edit_tree_controller.rb
@@ -26,6 +26,18 @@ class Projects::EditTreeController < Projects::BaseTreeController
end
end
+ def preview
+ @content = params[:content]
+ #FIXME workaround https://github.com/gitlabhq/gitlabhq/issues/5936
+ @content += "\n" if @blob.data.end_with?("\n")
+
+ diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
+ include_diff_info: true)
+ @diff = Gitlab::DiffParser.new(diffy.diff.scan(/.*\n/))
+
+ render layout: false
+ end
+
private
def blob
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index c6e4f574b67..de081acc2ba 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -16,9 +16,10 @@ module CommitsHelper
end
def each_diff_line(diff, index)
- Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
- yield(full_line, type, line_code, line_new, line_old)
- end
+ Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
+ .each do |full_line, type, line_code, line_new, line_old|
+ yield(full_line, type, line_code, line_new, line_old)
+ end
end
def each_diff_line_near(diff, index, expected_line_code)
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 50501dffefb..f39d0081dce 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -91,4 +91,12 @@ module TreeHelper
def leave_edit_message
"Leave edit mode?\nAll unsaved changes will be lost."
end
+
+ def editing_preview_title(filename)
+ if gitlab_markdown?(filename) || markup?(filename)
+ 'Preview'
+ else
+ 'Diff'
+ end
+ end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 6f7afcd1f9f..cee10ec90d2 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -184,9 +184,10 @@ class Note < ActiveRecord::Base
return @diff_line if @diff_line
if diff
- Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
- @diff_line = full_line if line_code == self.line_code
- end
+ Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
+ .each do |full_line, type, line_code, line_new, line_old|
+ @diff_line = full_line if line_code == self.line_code
+ end
end
@diff_line
diff --git a/app/views/projects/edit_tree/_diff.html.haml b/app/views/projects/edit_tree/_diff.html.haml
new file mode 100644
index 00000000000..cf044feb9a4
--- /dev/null
+++ b/app/views/projects/edit_tree/_diff.html.haml
@@ -0,0 +1,13 @@
+%table.text-file
+ - each_diff_line(diff, 1) do |line, type, line_code, line_new, line_old, raw_line|
+ %tr.line_holder{ id: line_code, class: "#{type}" }
+ - if type == "match"
+ %td.old_line= "..."
+ %td.new_line= "..."
+ %td.line_content.matched= line
+ - else
+ %td.old_line
+ = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
+ %td.new_line= link_to raw(type == "old" ? "&nbsp;" : 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)
+
diff --git a/app/views/projects/edit_tree/preview.html.haml b/app/views/projects/edit_tree/preview.html.haml
new file mode 100644
index 00000000000..fc6d3bfbc24
--- /dev/null
+++ b/app/views/projects/edit_tree/preview.html.haml
@@ -0,0 +1,26 @@
+.diff-file
+ .diff-content
+ - if gitlab_markdown?(@blob.name)
+ .file-content.wiki
+ = preserve do
+ = markdown(@content)
+ - elsif markup?(@blob.name)
+ .file-content.wiki
+ = raw GitHub::Markup.render(@blob.name, @content)
+ - else
+ .file-content.code
+ - unless @diff.empty?
+ %table.text-file
+ - @diff.each do |line, type, line_code, line_new, line_old, raw_line|
+ %tr.line_holder{ id: line_code, class: "#{type}" }
+ - if type == "match"
+ %td.old_line= "..."
+ %td.new_line= "..."
+ %td.line_content.matched= line
+ - else
+ %td.old_line
+ = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
+ %td.new_line= link_to raw(type == "old" ? "&nbsp;" : 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)
+ - else
+ %p.nothing_here_message No changes.
diff --git a/app/views/projects/edit_tree/show.html.haml b/app/views/projects/edit_tree/show.html.haml
index 3f2e98f3a7f..48babb43aaf 100644
--- a/app/views/projects/edit_tree/show.html.haml
+++ b/app/views/projects/edit_tree/show.html.haml
@@ -1,8 +1,11 @@
%h3.page-title Edit mode
.file-editor
= form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do
- .file-holder
+ .file-holder.file
.file-title
+ .btn-group.js-edit-mode.left-options
+ = link_to 'Edit', '#editor', class: 'active hover btn btn-tiny'
+ = link_to editing_preview_title(@blob.name), '#preview', class: 'btn btn-tiny', 'data-preview-url' => preview_project_edit_tree_path(@project, @id)
%i.icon-file
%span.file_name
= @path
@@ -13,7 +16,8 @@
.btn-group.tree-btn-group
= link_to "Cancel", @after_edit_path, class: "btn btn-tiny btn-cancel", data: { confirm: leave_edit_message }
.file-content.code
- %pre#editor= @blob.data
+ %pre.js-edit-mode-pane#editor= @blob.data
+ .js-edit-mode-pane#preview.hide
.form-group.commit_message-group
= label_tag 'commit_message', class: "control-label" do
@@ -45,3 +49,28 @@
$("#file-content").val(editor.getValue());
$(".file-editor form").submit();
});
+
+ var editModePanes = $('.js-edit-mode-pane'),
+ editModeLinks = $('.js-edit-mode a');
+
+ editModeLinks.click(function(event) {
+ event.preventDefault();
+
+ var currentLink = $(this),
+ paneId = currentLink.attr('href'),
+ currentPane = editModePanes.filter(paneId);
+
+ editModeLinks.removeClass('active hover');
+ currentLink.addClass('active hover');
+ editModePanes.hide();
+
+ if (paneId == '#preview') {
+ $.post(currentLink.data('preview-url'), { content: editor.getValue() }, function(response) {
+ currentPane.empty().append(response);
+ currentPane.fadeIn(200);
+ })
+ } else {
+ currentPane.fadeIn(200);
+ editor.focus()
+ }
+ })
diff --git a/config/routes.rb b/config/routes.rb
index f23542cc893..910c9ec2393 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -187,7 +187,9 @@ Gitlab::Application.routes.draw do
resources :blob, only: [:show, :destroy], constraints: {id: /.+/}
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'
+ resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do
+ post :preview, on: :member
+ end
resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new'
resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
diff --git a/db/schema.rb b/db/schema.rb
index 265d556bd27..dbd489335db 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -319,7 +319,6 @@ ActiveRecord::Schema.define(version: 20140414131055) do
t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at"
t.integer "created_by_id"
- t.datetime "last_credential_check_at"
t.string "avatar"
t.string "confirmation_token"
t.datetime "confirmed_at"
@@ -327,6 +326,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do
t.string "unconfirmed_email"
t.boolean "hide_no_ssh_key", default: false
t.string "website_url", default: "", null: false
+ t.datetime "last_credential_check_at"
end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature
index fd9a2f01a28..a204c3e10c7 100644
--- a/features/project/source/browse_files.feature
+++ b/features/project/source/browse_files.feature
@@ -29,3 +29,13 @@ Feature: Project Browse files
Given I click on "Gemfile.lock" file in repo
And I click button "edit"
Then I can edit code
+
+ @javascript
+ Scenario: I can see editing preview
+ Given I click on "Gemfile.lock" file in repo
+ And I click button "edit"
+ And I edit code
+ And I click link "Diff"
+ Then I see diff
+
+
diff --git a/features/steps/project/browse_files.rb b/features/steps/project/browse_files.rb
index 069086d5eac..7cdd1101ac5 100644
--- a/features/steps/project/browse_files.rb
+++ b/features/steps/project/browse_files.rb
@@ -41,6 +41,18 @@ class ProjectBrowseFiles < Spinach::FeatureSteps
page.evaluate_script('editor.getValue()').should == "GitlabFileEditor"
end
+ step 'I edit code' do
+ page.execute_script('editor.setValue("GitlabFileEditor")')
+ end
+
+ step 'I click link "Diff"' do
+ click_link 'Diff'
+ end
+
+ step 'I see diff' do
+ page.should have_css '.line_holder.new'
+ end
+
step 'I click on "new file" link in repo' do
click_link 'new-file-link'
end
diff --git a/lib/gitlab/diff_parser.rb b/lib/gitlab/diff_parser.rb
index fb27280c4a4..14bbb328637 100644
--- a/lib/gitlab/diff_parser.rb
+++ b/lib/gitlab/diff_parser.rb
@@ -4,9 +4,9 @@ module Gitlab
attr_reader :lines, :new_path
- def initialize(diff)
- @lines = diff.diff.lines.to_a
- @new_path = diff.new_path
+ def initialize(lines, new_path = '')
+ @lines = lines
+ @new_path = new_path
end
def each
@@ -18,10 +18,7 @@ module Gitlab
lines_arr.each do |line|
raw_line = line.dup
- next if line.match(/^\-\-\- \/dev\/null/)
- next if line.match(/^\+\+\+ \/dev\/null/)
- next if line.match(/^\-\-\- a/)
- next if line.match(/^\+\+\+ b/)
+ next if filename?(line)
full_line = html_escape(line.gsub(/\n/, ''))
full_line = ::Gitlab::InlineDiff.replace_markers full_line
@@ -53,8 +50,17 @@ module Gitlab
end
end
+ def empty?
+ @lines.empty?
+ end
+
private
+ def filename?(line)
+ line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
+ '--- /tmp/diffy', '+++ /tmp/diffy')
+ end
+
def identification_type(line)
if line[0] == "+"
"new"