Merge pull request #2153 from koenpunt/commit-diff-views

Added swipe view for image diff
This commit is contained in:
Dmitriy Zaporozhets 2013-01-27 11:41:23 -08:00
commit e0b5e26035
23 changed files with 604 additions and 266 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,7 @@
class CommitFile
constructor: (file) ->
if $('.image', file).length
new ImageFile(file)
this.CommitFile = CommitFile

View file

@ -0,0 +1,128 @@
class ImageFile
# Width where images must fits in, for 2-up this gets divided by 2
@availWidth = 900
@viewModes = ['two-up', 'swipe']
constructor: (@file) ->
# Determine if old and new file has same dimensions, if not show 'two-up' view
this.requestImageInfo $('.two-up.view .frame.deleted img', @file), (deletedWidth, deletedHeight) =>
this.requestImageInfo $('.two-up.view .frame.added img', @file), (width, height) =>
if width == deletedWidth && height == deletedHeight
this.initViewModes()
else
this.initView('two-up')
initViewModes: ->
viewMode = ImageFile.viewModes[0]
$('.view-modes', @file).removeClass 'hide'
$('.view-modes-menu', @file).on 'click', 'li', (event) =>
unless $(event.currentTarget).hasClass('active')
this.activateViewMode(event.currentTarget.className)
this.activateViewMode(viewMode)
activateViewMode: (viewMode) ->
$('.view-modes-menu li', @file)
.removeClass('active')
.filter(".#{viewMode}").addClass 'active'
$(".view:visible:not(.#{viewMode})", @file).fadeOut 200, =>
$(".view.#{viewMode}", @file).fadeIn(200)
this.initView viewMode
initView: (viewMode) ->
this.views[viewMode].call(this)
prepareFrames = (view) ->
maxWidth = 0
maxHeight = 0
$('.frame', view).each (index, frame) =>
width = $(frame).width()
height = $(frame).height()
maxWidth = if width > maxWidth then width else maxWidth
maxHeight = if height > maxHeight then height else maxHeight
.css
width: maxWidth
height: maxHeight
[maxWidth, maxHeight]
views:
'two-up': ->
$('.two-up.view .wrap', @file).each (index, wrap) =>
$('img', wrap).each ->
currentWidth = $(this).width()
if currentWidth > ImageFile.availWidth / 2
$(this).width ImageFile.availWidth / 2
this.requestImageInfo $('img', wrap), (width, height) ->
$('.image-info .meta-width', wrap).text "#{width}px"
$('.image-info .meta-height', wrap).text "#{height}px"
$('.image-info', wrap).removeClass('hide')
'swipe': ->
maxWidth = 0
maxHeight = 0
$('.swipe.view', @file).each (index, view) =>
[maxWidth, maxHeight] = prepareFrames(view)
$('.swipe-frame', view).css
width: maxWidth + 16
height: maxHeight + 28
$('.swipe-wrap', view).css
width: maxWidth + 1
height: maxHeight + 2
$('.swipe-bar', view).css
left: 0
.draggable
axis: 'x'
containment: 'parent'
drag: (event) ->
$('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left
stop: (event) ->
$('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left
'onion-skin': ->
maxWidth = 0
maxHeight = 0
dragTrackWidth = $('.drag-track', @file).width() - $('.dragger', @file).width()
$('.onion-skin.view', @file).each (index, view) =>
[maxWidth, maxHeight] = prepareFrames(view)
$('.onion-skin-frame', view).css
width: maxWidth + 16
height: maxHeight + 28
$('.swipe-wrap', view).css
width: maxWidth + 1
height: maxHeight + 2
$('.dragger', view).css
left: dragTrackWidth
.draggable
axis: 'x'
containment: 'parent'
drag: (event) ->
$('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth)
stop: (event) ->
$('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth)
requestImageInfo: (img, callback) ->
domImg = img.get(0)
if domImg.complete
callback.call(this, domImg.naturalWidth, domImg.naturalHeight)
else
img.on 'load', =>
callback.call(this, domImg.naturalWidth, domImg.naturalHeight)
this.ImageFile = ImageFile

View file

@ -1,59 +0,0 @@
var CommitsList = {
ref:null,
limit:0,
offset:0,
disable:false,
init:
function(ref, limit) {
$(".day-commits-table li.commit").live('click', function(e){
if(e.target.nodeName != "A") {
location.href = $(this).attr("url");
e.stopPropagation();
return false;
}
});
this.ref=ref;
this.limit=limit;
this.offset=limit;
this.initLoadMore();
$('.loading').show();
},
getOld:
function() {
$('.loading').show();
$.ajax({
type: "GET",
url: location.href,
data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref,
complete: function(){ $('.loading').hide()},
dataType: "script"});
},
append:
function(count, html) {
$("#commits_list").append(html);
if(count > 0) {
this.offset += count;
} else {
this.disable = true;
}
},
initLoadMore:
function() {
$(document).endlessScroll({
bottomPixels: 400,
fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return CommitsList.disable;
},
callback: function(i) {
CommitsList.getOld();
}
});
}
}

View file

@ -0,0 +1,54 @@
class CommitsList
@data =
ref: null
limit: 0
offset: 0
@disable = false
@showProgress: ->
$('.loading').show()
@hideProgress: ->
$('.loading').hide()
@init: (ref, limit) ->
$(".day-commits-table li.commit").live 'click', (event) ->
if event.target.nodeName != "A"
location.href = $(this).attr("url")
e.stopPropagation()
return false
@data.ref = ref
@data.limit = limit
@data.offset = limit
this.initLoadMore()
this.showProgress();
@getOld: ->
this.showProgress()
$.ajax
type: "GET"
url: location.href
data: @data
complete: this.hideProgress
dataType: "script"
@append: (count, html) ->
$("#commits-list").append(html)
if count > 0
@data.offset += count
else
@disable = true
@initLoadMore: ->
$(document).endlessScroll
bottomPixels: 400
fireDelay: 1000
fireOnce: true
ceaseFire: =>
@disable
callback: =>
this.getOld()
this.CommitsList = CommitsList

View file

@ -338,7 +338,7 @@ li.note {
li { li {
border-bottom:none !important; border-bottom:none !important;
} }
.file { .attachment {
padding-left: 20px; padding-left: 20px;
background:url("icon-attachment.png") no-repeat left center; background:url("icon-attachment.png") no-repeat left center;
} }

View file

@ -135,7 +135,7 @@
pre { pre {
border: none; border: none;
border-radius: 0; border-radius: 0;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace_font;
font-size: 12px !important; font-size: 12px !important;
line-height: 16px !important; line-height: 16px !important;
margin: 0; margin: 0;

View file

@ -4,4 +4,4 @@
} }
/** Typo **/ /** Typo **/
$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace; $monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;

View file

@ -21,7 +21,7 @@ h6 {
/** CODE **/ /** CODE **/
pre { pre {
font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace_font;
&.dark { &.dark {
background: #333; background: #333;
@ -79,7 +79,7 @@ a:focus {
} }
.monospace { .monospace {
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace_font;
} }
/** /**

View file

@ -1,5 +1,13 @@
/** Colors **/ /**
* General Colors
*/
$primary_color: #2FA0BB; $primary_color: #2FA0BB;
$link_color: #3A89A3; $link_color: #3A89A3;
$style_color: #474D57; $style_color: #474D57;
$hover: #D9EDF7; $hover: #D9EDF7;
/**
* Commit Diff Colors
*/
$added: #63c363;
$deleted: #f77;

View file

@ -1,7 +1,5 @@
/** /**
* * Commit file
* COMMIT SHOw
*
*/ */
.commit-committer-link, .commit-committer-link,
.commit-author-link { .commit-author-link {
@ -12,11 +10,11 @@
} }
} }
.diff_file { .file {
border: 1px solid #CCC; border: 1px solid #CCC;
margin-bottom: 1em; margin-bottom: 1em;
.diff_file_header { .header {
@extend .clearfix; @extend .clearfix;
padding: 5px 5px 5px 10px; padding: 5px 5px 5px 10px;
color: #555; color: #555;
@ -28,32 +26,35 @@
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
a{
color: $style_color;
}
> span { > span {
font-family: $monospace; font-family: $monospace_font;
font-size: 14px; font-size: 14px;
line-height: 30px; line-height: 30px;
} }
a.view-commit{ a.view-file{
font-weight: bold; font-weight: bold;
} }
.commit-short-id{ .commit-short-id{
font-family: $monospace; font-family: $monospace_font;
font-size: smaller; font-size: smaller;
} }
.file-mode{ .file-mode{
font-family: $monospace; font-family: $monospace_font;
} }
} }
.diff_file_content { .content {
overflow: auto; overflow: auto;
overflow-y: hidden; overflow-y: hidden;
background: #fff; background: #FFF;
color: #333; color: #333;
font-size: 12px; font-size: 12px;
font-family: $monospace;
.old{ .old{
span.idiff{ span.idiff{
background-color: #FAA; background-color: #FAA;
@ -66,77 +67,28 @@
} }
table { table {
td { font-family: $monospace_font;
line-height: 18px;
}
}
}
.diff_file_content_image {
background: #eee;
text-align: center;
.image {
display: inline-block;
margin: 50px;
max-width: 400px;
img{
background: url('trans_bg.gif');
}
&.diff_removed {
img{
border: 1px solid #C00;
}
}
&.diff_added {
img{
border: 1px solid #0C0;
}
}
.image-info{
margin: 5px 0 0 0;
}
}
&.img_compared {
.image {
max-width: 300px;
}
}
}
}
.diff_file_content{
table {
border: none; border: none;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
tr {
td { td {
line-height: 18px;
font-size: 12px; font-size: 12px;
} }
} }
} .old_line, .new_line {
.new_line, margin: 0px;
.old_line, padding: 0px;
.notes_line { border: none;
margin:0px; background: #EEE;
padding:0px; color: #666;
border:none;
background:#EEE;
color:#666;
padding: 0px 5px; padding: 0px 5px;
border-right: 1px solid #ccc; border-right: 1px solid #ccc;
text-align: right; text-align: right;
min-width: 35px; min-width: 35px;
max-width: 35px; max-width: 35px;
width: 35px; width: 35px;
moz-user-select: none; @include user-select(none);
-khtml-user-select: none;
user-select: none;
a { a {
float: left; float: left;
width: 35px; width: 35px;
@ -164,16 +116,225 @@
background: #fafafa; background: #fafafa;
} }
} }
}
.image {
background: #ddd;
text-align: center;
padding: 30px;
.wrap{
display: inline-block;
}
.frame {
display: inline-block;
background-color: #fff;
line-height: 0;
img{
border: 1px solid #FFF;
background: url('trans_bg.gif');
}
&.deleted {
border: 1px solid $deleted;
}
&.added {
border: 1px solid $added;
}
}
.image-info{
font-size: 12px;
margin: 5px 0 0 0;
color: grey;
}
.view.swipe{
position: relative;
.swipe-frame{
display: block;
margin: auto;
position: relative;
}
.swipe-wrap{
overflow: hidden;
border-left: 1px solid #999;
position: absolute;
display: block;
top: 13px;
right: 7px;
}
.frame{
top: 0;
right: 0;
position: absolute;
&.deleted{
margin: 0;
display: block;
top: 13px;
right: 7px;
}
}
.swipe-bar{
display: block;
height: 100%;
width: 15px;
z-index: 100;
position: absolute;
cursor: pointer;
&:hover{
.top-handle{
background-position: -15px 3px;
}
.bottom-handle{
background-position: -15px -11px;
}
};
.top-handle{
display: block;
height: 14px;
width: 15px;
position: absolute;
top: 0px;
background: url('swipemode_sprites.gif') 0 3px no-repeat;
}
.bottom-handle{
display: block;
height: 14px;
width: 15px;
position: absolute;
bottom: 0px;
background: url('swipemode_sprites.gif') 0 -11px no-repeat;
}
}
} //.view.swipe
.view.onion-skin{
.onion-skin-frame{
display: block;
margin: auto;
position: relative;
}
.frame.added, .frame.deleted {
position: absolute;
display: block;
top: 0px;
left: 0px;
}
.controls{
display: block;
height: 14px;
width: 300px;
z-index: 100;
position: absolute;
bottom: 0px;
left: 50%;
margin-left: -150px;
.drag-track{
display: block;
position: absolute;
left: 12px;
height: 10px;
width: 276px;
background: url('onion_skin_sprites.gif') -4px -20px repeat-x;
}
.dragger {
display: block;
position: absolute;
left: 0px;
top: 0px;
height: 14px;
width: 14px;
background: url('onion_skin_sprites.gif') 0px -34px repeat-x;
cursor: pointer;
}
.transparent {
display: block;
position: absolute;
top: 2px;
right: 0px;
height: 10px;
width: 10px;
background: url('onion_skin_sprites.gif') -2px 0px no-repeat;
}
.opaque {
display: block;
position: absolute;
top: 2px;
left: 0px;
height: 10px;
width: 10px;
background: url('onion_skin_sprites.gif') -2px -10px no-repeat;
}
}
} //.view.onion-skin
}
.view-modes{
padding: 10px;
text-align: center;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
ul, li{
list-style: none;
margin: 0;
padding: 0;
display: inline-block;
}
li{
color: grey;
border-left: 1px solid #c1c1c1;
padding: 0 12px 0 16px;
cursor: pointer;
&:first-child{
border-left: none;
}
&:hover{
text-decoration: underline;
}
&.active{
&:hover{
text-decoration: none;
}
cursor: default;
color: #333;
}
&.disabled{
display: none;
}
}
}
} }
/** COMMIT BLOCK **/ /** COMMIT BLOCK **/
.commit-title{display: block;} .commit-title{
.commit-title{margin-bottom: 10px} display: block;
.commit-author, .commit-committer{display: block;color: #999; font-weight: normal; font-style: italic;} }
.commit-author strong, .commit-committer strong{font-weight: bold; font-style: normal;} .commit-title{
margin-bottom: 10px;
}
.commit-author, .commit-committer{
display: block;
color: #999;
font-weight: normal;
font-style: italic;
}
.commit-author strong, .commit-committer strong{
font-weight: bold;
font-style: normal;
}
/** COMMIT ROW **/ /**
* COMMIT ROW
*/
.commit { .commit {
.browse_code_link_holder { .browse_code_link_holder {
@extend .span2; @extend .span2;
@ -199,11 +360,10 @@
float: left; float: left;
@extend .lined; @extend .lined;
min-width: 65px; min-width: 65px;
font-family: $monospace; font-family: $monospace_font;
} }
} }
.diff_file_header a,
.file-stats a { .file-stats a {
color: $style_color; color: $style_color;
} }
@ -237,7 +397,7 @@
font-size: 13px; font-size: 13px;
background: #474D57; background: #474D57;
color: #fff; color: #fff;
font-family: $monospace; font-family: $monospace_font;
} }

View file

@ -77,7 +77,7 @@ li.merge_request {
font-size: 14px; font-size: 14px;
background: #474D57; background: #474D57;
color: #fff; color: #fff;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace_font;
} }
.mr_source_commit, .mr_source_commit,

View file

@ -40,13 +40,13 @@ ul.notes {
.discussion-body { .discussion-body {
margin-left: 50px; margin-left: 50px;
.diff_file, .file,
.discussion-hidden, .discussion-hidden,
.notes { .notes {
@extend .borders; @extend .borders;
background-color: #F9F9F9; background-color: #F9F9F9;
} }
.diff_file .notes { .file .notes {
/* reset */ /* reset */
background: inherit; background: inherit;
border: none; border: none;
@ -109,7 +109,7 @@ ul.notes {
} }
} }
.diff_file .notes_holder { .file .notes_holder {
font-family: $sansFontFamily; font-family: $sansFontFamily;
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
@ -134,8 +134,6 @@ ul.notes {
} }
} }
/** /**
* Actions for Discussions/Notes * Actions for Discussions/Notes
*/ */
@ -171,7 +169,7 @@ ul.notes {
} }
} }
} }
.diff_file .note .note-actions { .file .note .note-actions {
right: 0; right: 0;
top: 0; top: 0;
} }
@ -182,7 +180,7 @@ ul.notes {
* Line note button on the side of diffs * Line note button on the side of diffs
*/ */
.diff_file tr.line_holder { .file tr.line_holder {
.add-diff-note { .add-diff-note {
background: url("diff_note_add.png") no-repeat left 0; background: url("diff_note_add.png") no-repeat left 0;
height: 22px; height: 22px;
@ -212,8 +210,6 @@ ul.notes {
} }
} }
/** /**
* Note Form * Note Form
*/ */
@ -222,7 +218,12 @@ ul.notes {
.reply-btn { .reply-btn {
@extend .save-btn; @extend .save-btn;
} }
.diff_file, .file .content tr.line_holder:hover > td { background: $hover !important; }
.file .content tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
filter: alpha(opacity=100);
}
.file,
.discussion { .discussion {
.new_note { .new_note {
margin: 8px 5px 8px 0; margin: 8px 5px 8px 0;

View file

@ -59,9 +59,9 @@ module CommitsHelper
def image_diff_class(diff) def image_diff_class(diff)
if diff.deleted_file if diff.deleted_file
"diff_removed" "deleted"
elsif diff.new_file elsif diff.new_file
"diff_added" "added"
else else
nil nil
end end

View file

@ -11,19 +11,7 @@
:javascript :javascript
$(function(){ $(function(){
var w, h; $('.files .file').each(function(){
$('.diff_file').each(function(){ new CommitFile(this);
$('.image.diff_removed img', this).on('load', $.proxy(function(event){
var w = event.currentTarget.naturalWidth
, h = event.currentTarget.naturalHeight;
$('.image.diff_removed .image-info', this).append(' | <b>W:</b> ' + w + 'px | <b>H:</b> ' + h + 'px');
}, this));
$('.image.diff_added img', this).on('load', $.proxy(function(event){
var w = event.currentTarget.naturalWidth
, h = event.currentTarget.naturalHeight;
$('.image.diff_added .image-info', this).append(' | <b>W:</b> ' + w + 'px | <b>H:</b> ' + h + 'px');
}, this));
}); });
}); });

View file

@ -12,19 +12,20 @@
.file-stats .file-stats
= render "commits/diff_head", diffs: diffs = render "commits/diff_head", diffs: diffs
- unless @suppress_diff .files
- unless @suppress_diff
- diffs.each_with_index do |diff, i| - diffs.each_with_index do |diff, i|
- next if diff.diff.empty? - next if diff.diff.empty?
- file = (@commit.tree / diff.new_path) - file = (@commit.tree / diff.new_path)
- file = (@commit.prev_commit.tree / diff.old_path) unless file - file = (@commit.prev_commit.tree / diff.old_path) unless file
- next unless file - next unless file
.diff_file{id: "diff-#{i}"} .file{id: "diff-#{i}"}
.diff_file_header .header
- if diff.deleted_file - if diff.deleted_file
%span= diff.old_path %span= diff.old_path
- if @commit.prev_commit - if @commit.prev_commit
= link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-commit'} do = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-file'} do
View file @ View file @
%span.commit-short-id= @commit.short_id(6) %span.commit-short-id= @commit.short_id(6)
- else - else
@ -32,30 +33,17 @@
- if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
%span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
= link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn very_small right view-commit'} do = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn very_small right view-file'} do
View file @ View file @
%span.commit-short-id= @commit.short_id(6) %span.commit-short-id= @commit.short_id(6)
%br/ .content
.diff_file_content -# Skipp all non non-supported blobs
-# Skip all non-supported blobs
- next unless file.respond_to?('text?') - next unless file.respond_to?('text?')
- if file.text? - if file.text?
= render "commits/text_diff", diff: diff, index: i = render "commits/text_file", diff: diff, index: i
- elsif file.image? - elsif file.image?
- old_file = (@commit.prev_commit.tree / diff.old_path) if !@commit.prev_commit.nil? - old_file = (@commit.prev_commit.tree / diff.old_path) if !@commit.prev_commit.nil?
- if diff.renamed_file || diff.new_file || diff.deleted_file = render "commits/image", diff: diff, old_file: old_file, file: file, index: i
.diff_file_content_image
.image{class: image_diff_class(diff)}
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
%div.image-info= "#{number_to_human_size file.size}"
- else
.diff_file_content_image.img_compared
.image.diff_removed
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
%div.image-info= "#{number_to_human_size file.size}"
.image.diff_added
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
%div.image-info= "#{number_to_human_size file.size}"
- else - else
%p.nothing_here_message No preview for this file type %p.nothing_here_message No preview for this file type

View file

@ -0,0 +1,63 @@
- if diff.renamed_file || diff.new_file || diff.deleted_file
.image
%span.wrap
.frame{class: image_diff_class(diff)}
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
%p.image-info= "#{number_to_human_size file.size}"
- else
.image
%div.two-up.view
%span.wrap
.frame.deleted
%a{href: project_tree_path(@project, tree_join(@commit.id, diff.old_path))}
%img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
%p.image-info.hide
%span.meta-filesize= "#{number_to_human_size old_file.size}"
|
%b W:
%span.meta-width
|
%b H:
%span.meta-height
%span.wrap
.frame.added
%a{href: project_tree_path(@project, tree_join(@commit.id, diff.new_path))}
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
%p.image-info.hide
%span.meta-filesize= "#{number_to_human_size file.size}"
|
%b W:
%span.meta-width
|
%b H:
%span.meta-height
%div.swipe.view.hide
.swipe-frame
.frame.deleted
%img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
.swipe-wrap
.frame.added
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
%span.swipe-bar
%span.top-handle
%span.bottom-handle
%div.onion-skin.view.hide
.onion-skin-frame
.frame.deleted
%img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
.frame.added
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
.controls
.transparent
.drag-track
.dragger{:style => "left: 0px;"}
.opaque
.view-modes.hide
%ul.view-modes-menu
%li.two-up{data: {mode: 'two-up'}} 2-up
%li.swipe{data: {mode: 'swipe'}} Swipe
%li.onion-skin{data: {mode: 'onion-skin'}} Onion skin

View file

@ -2,7 +2,7 @@
- if too_big - if too_big
%a.supp_diff_link Diff suppressed. Click to show %a.supp_diff_link Diff suppressed. Click to show
%table{class: "#{'hide' if too_big}"} %table.text-file{class: "#{'hide' if too_big}"}
- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old| - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old|
%tr.line_holder{ id: line_code } %tr.line_holder{ id: line_code }
- if type == "match" - if type == "match"

View file

@ -5,7 +5,7 @@
= breadcrumbs = breadcrumbs
%div{id: dom_id(@project)} %div{id: dom_id(@project)}
#commits_list= render "commits" #commits-list= render "commits"
.clear .clear
.loading{ style: "display:none;"} .loading{ style: "display:none;"}

View file

@ -38,7 +38,7 @@
- if note.for_diff_line? - if note.for_diff_line?
- if note.diff - if note.diff
.content .content
.diff_file= render "notes/discussion_diff", discussion_notes: discussion_notes, note: note .file= render "notes/discussion_diff", discussion_notes: discussion_notes, note: note
- else - else
= link_to 'show outdated discussion', '#', class: 'js-show-outdated-discussion' = link_to 'show outdated discussion', '#', class: 'js-show-outdated-discussion'
%div.hide.outdated-discussion %div.hide.outdated-discussion

View file

@ -1,5 +1,5 @@
- diff = note.diff - diff = note.diff
.diff_file_header .header
- if diff.deleted_file - if diff.deleted_file
%span= diff.old_path %span= diff.old_path
- else - else
@ -7,7 +7,7 @@
- if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
%span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
%br/ %br/
.diff_file_content .content
%table %table
- each_diff_line(diff, note.diff_file_index) do |line, type, line_code, line_new, line_old| - each_diff_line(diff, note.diff_file_index) do |line, type, line_code, line_new, line_old|
%tr.line_holder{ id: line_code } %tr.line_holder{ id: line_code }

View file

@ -2,27 +2,27 @@ module SharedDiffNote
include Spinach::DSL include Spinach::DSL
Given 'I cancel the diff comment' do Given 'I cancel the diff comment' do
within(".diff_file") do within(".file") do
find(".js-close-discussion-note-form").trigger("click") find(".js-close-discussion-note-form").trigger("click")
end end
end end
Given 'I delete a diff comment' do Given 'I delete a diff comment' do
sleep 1 sleep 1
within(".diff_file") do within(".file") do
first(".js-note-delete").trigger("click") first(".js-note-delete").trigger("click")
end end
end end
Given 'I haven\'t written any diff comment text' do Given 'I haven\'t written any diff comment text' do
within(".diff_file") do within(".file") do
fill_in "note[note]", with: "" fill_in "note[note]", with: ""
end end
end end
Given 'I leave a diff comment like "Typo, please fix"' do Given 'I leave a diff comment like "Typo, please fix"' do
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click") find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
within(".diff_file") do within(".file") do
fill_in "note[note]", with: "Typo, please fix" fill_in "note[note]", with: "Typo, please fix"
#click_button("Add Comment") #click_button("Add Comment")
find(".js-comment-button").trigger("click") find(".js-comment-button").trigger("click")
@ -32,7 +32,7 @@ module SharedDiffNote
Given 'I preview a diff comment text like "Should fix it :smile:"' do Given 'I preview a diff comment text like "Should fix it :smile:"' do
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click") find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
within(".diff_file") do within(".file") do
fill_in "note[note]", with: "Should fix it :smile:" fill_in "note[note]", with: "Should fix it :smile:"
find(".js-note-preview-button").trigger("click") find(".js-note-preview-button").trigger("click")
end end
@ -40,7 +40,7 @@ module SharedDiffNote
Given 'I preview another diff comment text like "DRY this up"' do Given 'I preview another diff comment text like "DRY this up"' do
find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click") find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
within(".diff_file") do within(".file") do
fill_in "note[note]", with: "DRY this up" fill_in "note[note]", with: "DRY this up"
find(".js-note-preview-button").trigger("click") find(".js-note-preview-button").trigger("click")
end end
@ -55,13 +55,13 @@ module SharedDiffNote
end end
Given 'I write a diff comment like ":-1: I don\'t like this"' do Given 'I write a diff comment like ":-1: I don\'t like this"' do
within(".diff_file") do within(".file") do
fill_in "note[note]", with: ":-1: I don\'t like this" fill_in "note[note]", with: ":-1: I don\'t like this"
end end
end end
Given 'I submit the diff comment' do Given 'I submit the diff comment' do
within(".diff_file") do within(".file") do
click_button("Add Comment") click_button("Add Comment")
end end
end end
@ -69,49 +69,49 @@ module SharedDiffNote
Then 'I should not see the diff comment form' do Then 'I should not see the diff comment form' do
within(".diff_file") do within(".file") do
page.should_not have_css("form.new_note") page.should_not have_css("form.new_note")
end end
end end
Then 'I should not see the diff comment preview button' do Then 'I should not see the diff comment preview button' do
within(".diff_file") do within(".file") do
page.should have_css(".js-note-preview-button", visible: false) page.should have_css(".js-note-preview-button", visible: false)
end end
end end
Then 'I should not see the diff comment text field' do Then 'I should not see the diff comment text field' do
within(".diff_file") do within(".file") do
page.should have_css(".js-note-text", visible: false) page.should have_css(".js-note-text", visible: false)
end end
end end
Then 'I should only see one diff form' do Then 'I should only see one diff form' do
within(".diff_file") do within(".file") do
page.should have_css("form.new_note", count: 1) page.should have_css("form.new_note", count: 1)
end end
end end
Then 'I should see a diff comment form with ":-1: I don\'t like this"' do Then 'I should see a diff comment form with ":-1: I don\'t like this"' do
within(".diff_file") do within(".file") do
page.should have_field("note[note]", with: ":-1: I don\'t like this") page.should have_field("note[note]", with: ":-1: I don\'t like this")
end end
end end
Then 'I should see a diff comment saying "Typo, please fix"' do Then 'I should see a diff comment saying "Typo, please fix"' do
within(".diff_file .note") do within(".file .note") do
page.should have_content("Typo, please fix") page.should have_content("Typo, please fix")
end end
end end
Then 'I should see a discussion reply button' do Then 'I should see a discussion reply button' do
within(".diff_file") do within(".file") do
page.should have_link("Reply") page.should have_link("Reply")
end end
end end
Then 'I should see a temporary diff comment form' do Then 'I should see a temporary diff comment form' do
within(".diff_file") do within(".file") do
page.should have_css(".js-temp-notes-holder form.new_note") page.should have_css(".js-temp-notes-holder form.new_note")
end end
end end
@ -121,37 +121,37 @@ module SharedDiffNote
end end
Then 'I should see an empty diff comment form' do Then 'I should see an empty diff comment form' do
within(".diff_file") do within(".file") do
page.should have_field("note[note]", with: "") page.should have_field("note[note]", with: "")
end end
end end
Then 'I should see the cancel comment button' do Then 'I should see the cancel comment button' do
within(".diff_file form") do within(".file form") do
page.should have_css(".js-close-discussion-note-form", text: "Cancel") page.should have_css(".js-close-discussion-note-form", text: "Cancel")
end end
end end
Then 'I should see the diff comment preview' do Then 'I should see the diff comment preview' do
within(".diff_file form") do within(".file form") do
page.should have_css(".js-note-preview", visible: false) page.should have_css(".js-note-preview", visible: false)
end end
end end
Then 'I should see the diff comment edit button' do Then 'I should see the diff comment edit button' do
within(".diff_file") do within(".file") do
page.should have_css(".js-note-edit-button", visible: true) page.should have_css(".js-note-edit-button", visible: true)
end end
end end
Then 'I should see the diff comment preview button' do Then 'I should see the diff comment preview button' do
within(".diff_file") do within(".file") do
page.should have_css(".js-note-preview-button", visible: true) page.should have_css(".js-note-preview-button", visible: true)
end end
end end
Then 'I should see two separate previews' do Then 'I should see two separate previews' do
within(".diff_file") do within(".file") do
page.should have_css(".js-note-preview", visible: true, count: 2) page.should have_css(".js-note-preview", visible: true, count: 2)
page.should have_content("Should fix it") page.should have_content("Should fix it")
page.should have_content("DRY this up") page.should have_content("DRY this up")