Commit d859d080942175082c1a0cf34d89c0eefd1a3c39
1 parent
cd623218
Exists in
spb-stable
and in
2 other branches
Editing preview
Showing
15 changed files
with
148 additions
and
19 deletions
Show diff stats
Gemfile
Gemfile.lock
... | ... | @@ -101,6 +101,7 @@ GEM |
101 | 101 | devise-async (0.8.0) |
102 | 102 | devise (>= 2.2, < 3.2) |
103 | 103 | diff-lcs (1.2.5) |
104 | + diffy (3.0.3) | |
104 | 105 | docile (1.1.1) |
105 | 106 | dotenv (0.9.0) |
106 | 107 | email_spec (1.5.0) |
... | ... | @@ -574,6 +575,7 @@ DEPENDENCIES |
574 | 575 | default_value_for (~> 3.0.0) |
575 | 576 | devise (= 3.0.4) |
576 | 577 | devise-async (= 0.8.0) |
578 | + diffy (~> 3.0.3) | |
577 | 579 | email_spec |
578 | 580 | email_validator (~> 1.4.0) |
579 | 581 | enumerize |
... | ... | @@ -644,7 +646,7 @@ DEPENDENCIES |
644 | 646 | simplecov |
645 | 647 | sinatra |
646 | 648 | six |
647 | - slack-notifier (~> 0.2.0) | |
649 | + slack-notifier (~> 0.3.2) | |
648 | 650 | slim |
649 | 651 | spinach-rails |
650 | 652 | spring (= 1.1.1) |
... | ... | @@ -662,4 +664,4 @@ DEPENDENCIES |
662 | 664 | unicorn (~> 4.6.3) |
663 | 665 | unicorn-worker-killer |
664 | 666 | version_sorter |
665 | - webmock | |
666 | 667 | \ No newline at end of file |
668 | + webmock | ... | ... |
app/assets/stylesheets/generic/files.scss
app/controllers/projects/edit_tree_controller.rb
... | ... | @@ -26,6 +26,18 @@ class Projects::EditTreeController < Projects::BaseTreeController |
26 | 26 | end |
27 | 27 | end |
28 | 28 | |
29 | + def preview | |
30 | + @content = params[:content] | |
31 | + #FIXME workaround https://github.com/gitlabhq/gitlabhq/issues/5936 | |
32 | + @content += "\n" if @blob.data.end_with?("\n") | |
33 | + | |
34 | + diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', | |
35 | + include_diff_info: true) | |
36 | + @diff = Gitlab::DiffParser.new(diffy.diff.scan(/.*\n/)) | |
37 | + | |
38 | + render layout: false | |
39 | + end | |
40 | + | |
29 | 41 | private |
30 | 42 | |
31 | 43 | def blob | ... | ... |
app/helpers/commits_helper.rb
... | ... | @@ -16,9 +16,10 @@ module CommitsHelper |
16 | 16 | end |
17 | 17 | |
18 | 18 | def each_diff_line(diff, index) |
19 | - Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old| | |
20 | - yield(full_line, type, line_code, line_new, line_old) | |
21 | - end | |
19 | + Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path) | |
20 | + .each do |full_line, type, line_code, line_new, line_old| | |
21 | + yield(full_line, type, line_code, line_new, line_old) | |
22 | + end | |
22 | 23 | end |
23 | 24 | |
24 | 25 | def each_diff_line_near(diff, index, expected_line_code) | ... | ... |
app/helpers/tree_helper.rb
... | ... | @@ -91,4 +91,12 @@ module TreeHelper |
91 | 91 | def leave_edit_message |
92 | 92 | "Leave edit mode?\nAll unsaved changes will be lost." |
93 | 93 | end |
94 | + | |
95 | + def editing_preview_title(filename) | |
96 | + if gitlab_markdown?(filename) || markup?(filename) | |
97 | + 'Preview' | |
98 | + else | |
99 | + 'Diff' | |
100 | + end | |
101 | + end | |
94 | 102 | end | ... | ... |
app/models/note.rb
... | ... | @@ -184,9 +184,10 @@ class Note < ActiveRecord::Base |
184 | 184 | return @diff_line if @diff_line |
185 | 185 | |
186 | 186 | if diff |
187 | - Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old| | |
188 | - @diff_line = full_line if line_code == self.line_code | |
189 | - end | |
187 | + Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path) | |
188 | + .each do |full_line, type, line_code, line_new, line_old| | |
189 | + @diff_line = full_line if line_code == self.line_code | |
190 | + end | |
190 | 191 | end |
191 | 192 | |
192 | 193 | @diff_line | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +%table.text-file | |
2 | + - each_diff_line(diff, 1) do |line, type, line_code, line_new, line_old, raw_line| | |
3 | + %tr.line_holder{ id: line_code, class: "#{type}" } | |
4 | + - if type == "match" | |
5 | + %td.old_line= "..." | |
6 | + %td.new_line= "..." | |
7 | + %td.line_content.matched= line | |
8 | + - else | |
9 | + %td.old_line | |
10 | + = link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code | |
11 | + %td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code | |
12 | + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line) | |
13 | + | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +.diff-file | |
2 | + .diff-content | |
3 | + - if gitlab_markdown?(@blob.name) | |
4 | + .file-content.wiki | |
5 | + = preserve do | |
6 | + = markdown(@content) | |
7 | + - elsif markup?(@blob.name) | |
8 | + .file-content.wiki | |
9 | + = raw GitHub::Markup.render(@blob.name, @content) | |
10 | + - else | |
11 | + .file-content.code | |
12 | + - unless @diff.empty? | |
13 | + %table.text-file | |
14 | + - @diff.each do |line, type, line_code, line_new, line_old, raw_line| | |
15 | + %tr.line_holder{ id: line_code, class: "#{type}" } | |
16 | + - if type == "match" | |
17 | + %td.old_line= "..." | |
18 | + %td.new_line= "..." | |
19 | + %td.line_content.matched= line | |
20 | + - else | |
21 | + %td.old_line | |
22 | + = link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code | |
23 | + %td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code | |
24 | + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line) | |
25 | + - else | |
26 | + %p.nothing_here_message No changes. | ... | ... |
app/views/projects/edit_tree/show.html.haml
1 | 1 | %h3.page-title Edit mode |
2 | 2 | .file-editor |
3 | 3 | = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do |
4 | - .file-holder | |
4 | + .file-holder.file | |
5 | 5 | .file-title |
6 | + .btn-group.js-edit-mode.left-options | |
7 | + = link_to 'Edit', '#editor', class: 'active hover btn btn-tiny' | |
8 | + = link_to editing_preview_title(@blob.name), '#preview', class: 'btn btn-tiny', 'data-preview-url' => preview_project_edit_tree_path(@project, @id) | |
6 | 9 | %i.icon-file |
7 | 10 | %span.file_name |
8 | 11 | = @path |
... | ... | @@ -13,7 +16,8 @@ |
13 | 16 | .btn-group.tree-btn-group |
14 | 17 | = link_to "Cancel", @after_edit_path, class: "btn btn-tiny btn-cancel", data: { confirm: leave_edit_message } |
15 | 18 | .file-content.code |
16 | - %pre#editor= @blob.data | |
19 | + %pre.js-edit-mode-pane#editor= @blob.data | |
20 | + .js-edit-mode-pane#preview.hide | |
17 | 21 | |
18 | 22 | .form-group.commit_message-group |
19 | 23 | = label_tag 'commit_message', class: "control-label" do |
... | ... | @@ -45,3 +49,28 @@ |
45 | 49 | $("#file-content").val(editor.getValue()); |
46 | 50 | $(".file-editor form").submit(); |
47 | 51 | }); |
52 | + | |
53 | + var editModePanes = $('.js-edit-mode-pane'), | |
54 | + editModeLinks = $('.js-edit-mode a'); | |
55 | + | |
56 | + editModeLinks.click(function(event) { | |
57 | + event.preventDefault(); | |
58 | + | |
59 | + var currentLink = $(this), | |
60 | + paneId = currentLink.attr('href'), | |
61 | + currentPane = editModePanes.filter(paneId); | |
62 | + | |
63 | + editModeLinks.removeClass('active hover'); | |
64 | + currentLink.addClass('active hover'); | |
65 | + editModePanes.hide(); | |
66 | + | |
67 | + if (paneId == '#preview') { | |
68 | + $.post(currentLink.data('preview-url'), { content: editor.getValue() }, function(response) { | |
69 | + currentPane.empty().append(response); | |
70 | + currentPane.fadeIn(200); | |
71 | + }) | |
72 | + } else { | |
73 | + currentPane.fadeIn(200); | |
74 | + editor.focus() | |
75 | + } | |
76 | + }) | ... | ... |
config/routes.rb
... | ... | @@ -187,7 +187,9 @@ Gitlab::Application.routes.draw do |
187 | 187 | resources :blob, only: [:show, :destroy], constraints: {id: /.+/} |
188 | 188 | resources :raw, only: [:show], constraints: {id: /.+/} |
189 | 189 | resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ } |
190 | - resources :edit_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'edit' | |
190 | + resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do | |
191 | + post :preview, on: :member | |
192 | + end | |
191 | 193 | resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new' |
192 | 194 | resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/} |
193 | 195 | resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} | ... | ... |
db/schema.rb
... | ... | @@ -319,7 +319,6 @@ ActiveRecord::Schema.define(version: 20140414131055) do |
319 | 319 | t.integer "notification_level", default: 1, null: false |
320 | 320 | t.datetime "password_expires_at" |
321 | 321 | t.integer "created_by_id" |
322 | - t.datetime "last_credential_check_at" | |
323 | 322 | t.string "avatar" |
324 | 323 | t.string "confirmation_token" |
325 | 324 | t.datetime "confirmed_at" |
... | ... | @@ -327,6 +326,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do |
327 | 326 | t.string "unconfirmed_email" |
328 | 327 | t.boolean "hide_no_ssh_key", default: false |
329 | 328 | t.string "website_url", default: "", null: false |
329 | + t.datetime "last_credential_check_at" | |
330 | 330 | end |
331 | 331 | |
332 | 332 | add_index "users", ["admin"], name: "index_users_on_admin", using: :btree | ... | ... |
features/project/source/browse_files.feature
... | ... | @@ -29,3 +29,13 @@ Feature: Project Browse files |
29 | 29 | Given I click on "Gemfile.lock" file in repo |
30 | 30 | And I click button "edit" |
31 | 31 | Then I can edit code |
32 | + | |
33 | + @javascript | |
34 | + Scenario: I can see editing preview | |
35 | + Given I click on "Gemfile.lock" file in repo | |
36 | + And I click button "edit" | |
37 | + And I edit code | |
38 | + And I click link "Diff" | |
39 | + Then I see diff | |
40 | + | |
41 | + | ... | ... |
features/steps/project/browse_files.rb
... | ... | @@ -41,6 +41,18 @@ class ProjectBrowseFiles < Spinach::FeatureSteps |
41 | 41 | page.evaluate_script('editor.getValue()').should == "GitlabFileEditor" |
42 | 42 | end |
43 | 43 | |
44 | + step 'I edit code' do | |
45 | + page.execute_script('editor.setValue("GitlabFileEditor")') | |
46 | + end | |
47 | + | |
48 | + step 'I click link "Diff"' do | |
49 | + click_link 'Diff' | |
50 | + end | |
51 | + | |
52 | + step 'I see diff' do | |
53 | + page.should have_css '.line_holder.new' | |
54 | + end | |
55 | + | |
44 | 56 | step 'I click on "new file" link in repo' do |
45 | 57 | click_link 'new-file-link' |
46 | 58 | end | ... | ... |
lib/gitlab/diff_parser.rb
... | ... | @@ -4,9 +4,9 @@ module Gitlab |
4 | 4 | |
5 | 5 | attr_reader :lines, :new_path |
6 | 6 | |
7 | - def initialize(diff) | |
8 | - @lines = diff.diff.lines.to_a | |
9 | - @new_path = diff.new_path | |
7 | + def initialize(lines, new_path = '') | |
8 | + @lines = lines | |
9 | + @new_path = new_path | |
10 | 10 | end |
11 | 11 | |
12 | 12 | def each |
... | ... | @@ -18,10 +18,7 @@ module Gitlab |
18 | 18 | lines_arr.each do |line| |
19 | 19 | raw_line = line.dup |
20 | 20 | |
21 | - next if line.match(/^\-\-\- \/dev\/null/) | |
22 | - next if line.match(/^\+\+\+ \/dev\/null/) | |
23 | - next if line.match(/^\-\-\- a/) | |
24 | - next if line.match(/^\+\+\+ b/) | |
21 | + next if filename?(line) | |
25 | 22 | |
26 | 23 | full_line = html_escape(line.gsub(/\n/, '')) |
27 | 24 | full_line = ::Gitlab::InlineDiff.replace_markers full_line |
... | ... | @@ -53,8 +50,17 @@ module Gitlab |
53 | 50 | end |
54 | 51 | end |
55 | 52 | |
53 | + def empty? | |
54 | + @lines.empty? | |
55 | + end | |
56 | + | |
56 | 57 | private |
57 | 58 | |
59 | + def filename?(line) | |
60 | + line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b', | |
61 | + '--- /tmp/diffy', '+++ /tmp/diffy') | |
62 | + end | |
63 | + | |
58 | 64 | def identification_type(line) |
59 | 65 | if line[0] == "+" |
60 | 66 | "new" | ... | ... |