Commit e33debc2147966525246bad999d0cacc4e676585

Authored by Koen Punt
1 parent 6ab6c55d

Updated commit diff view with some minor visual modifications

Prepared diff view for multiple view modes

Converted commits.js to coffeescript
image info in separate coffeescript file

Added swipe view mode

Added onion skin viewMode
app/assets/images/onion_skin_sprites.gif 0 → 100644

1.55 KB

app/assets/images/swipemode_sprites.gif 0 → 100644

1.5 KB

app/assets/javascripts/commit/file.js.coffee 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +class CommitFile
  2 +
  3 + constructor: (file) ->
  4 + if $('.image', file).length
  5 + new ImageFile(file)
  6 +
  7 +this.CommitFile = CommitFile
0 8 \ No newline at end of file
... ...
app/assets/javascripts/commit/image-file.js.coffee 0 → 100644
... ... @@ -0,0 +1,128 @@
  1 +class ImageFile
  2 +
  3 + # Width where images must fits in, for 2-up this gets divided by 2
  4 + @availWidth = 900
  5 + @viewModes = ['two-up', 'swipe']
  6 +
  7 + constructor: (@file) ->
  8 + # Determine if old and new file has same dimensions, if not show 'two-up' view
  9 + this.requestImageInfo $('.two-up.view .frame.deleted img', @file), (deletedWidth, deletedHeight) =>
  10 + this.requestImageInfo $('.two-up.view .frame.added img', @file), (width, height) =>
  11 + if width == deletedWidth && height == deletedHeight
  12 + this.initViewModes()
  13 + else
  14 + this.initView('two-up')
  15 +
  16 + initViewModes: ->
  17 + viewMode = ImageFile.viewModes[0]
  18 +
  19 + $('.view-modes', @file).removeClass 'hide'
  20 + $('.view-modes-menu', @file).on 'click', 'li', (event) =>
  21 + unless $(event.currentTarget).hasClass('active')
  22 + this.activateViewMode(event.currentTarget.className)
  23 +
  24 + this.activateViewMode(viewMode)
  25 +
  26 + activateViewMode: (viewMode) ->
  27 + $('.view-modes-menu li', @file)
  28 + .removeClass('active')
  29 + .filter(".#{viewMode}").addClass 'active'
  30 + $(".view:visible:not(.#{viewMode})", @file).fadeOut 200, =>
  31 + $(".view.#{viewMode}", @file).fadeIn(200)
  32 + this.initView viewMode
  33 +
  34 + initView: (viewMode) ->
  35 + this.views[viewMode].call(this)
  36 +
  37 + prepareFrames = (view) ->
  38 + maxWidth = 0
  39 + maxHeight = 0
  40 + $('.frame', view).each (index, frame) =>
  41 + width = $(frame).width()
  42 + height = $(frame).height()
  43 + maxWidth = if width > maxWidth then width else maxWidth
  44 + maxHeight = if height > maxHeight then height else maxHeight
  45 + .css
  46 + width: maxWidth
  47 + height: maxHeight
  48 +
  49 + [maxWidth, maxHeight]
  50 +
  51 + views:
  52 + 'two-up': ->
  53 + $('.two-up.view .wrap', @file).each (index, wrap) =>
  54 + $('img', wrap).each ->
  55 + currentWidth = $(this).width()
  56 + if currentWidth > ImageFile.availWidth / 2
  57 + $(this).width ImageFile.availWidth / 2
  58 +
  59 + this.requestImageInfo $('img', wrap), (width, height) ->
  60 + $('.image-info .meta-width', wrap).text "#{width}px"
  61 + $('.image-info .meta-height', wrap).text "#{height}px"
  62 + $('.image-info', wrap).removeClass('hide')
  63 +
  64 + 'swipe': ->
  65 + maxWidth = 0
  66 + maxHeight = 0
  67 +
  68 + $('.swipe.view', @file).each (index, view) =>
  69 +
  70 + [maxWidth, maxHeight] = prepareFrames(view)
  71 +
  72 + $('.swipe-frame', view).css
  73 + width: maxWidth + 16
  74 + height: maxHeight + 28
  75 +
  76 + $('.swipe-wrap', view).css
  77 + width: maxWidth + 1
  78 + height: maxHeight + 2
  79 +
  80 + $('.swipe-bar', view).css
  81 + left: 0
  82 + .draggable
  83 + axis: 'x'
  84 + containment: 'parent'
  85 + drag: (event) ->
  86 + $('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left
  87 + stop: (event) ->
  88 + $('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left
  89 +
  90 + 'onion-skin': ->
  91 + maxWidth = 0
  92 + maxHeight = 0
  93 +
  94 + dragTrackWidth = $('.drag-track', @file).width() - $('.dragger', @file).width()
  95 +
  96 + $('.onion-skin.view', @file).each (index, view) =>
  97 +
  98 + [maxWidth, maxHeight] = prepareFrames(view)
  99 +
  100 + $('.onion-skin-frame', view).css
  101 + width: maxWidth + 16
  102 + height: maxHeight + 28
  103 +
  104 + $('.swipe-wrap', view).css
  105 + width: maxWidth + 1
  106 + height: maxHeight + 2
  107 +
  108 + $('.dragger', view).css
  109 + left: dragTrackWidth
  110 + .draggable
  111 + axis: 'x'
  112 + containment: 'parent'
  113 + drag: (event) ->
  114 + $('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth)
  115 + stop: (event) ->
  116 + $('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth)
  117 +
  118 +
  119 +
  120 + requestImageInfo: (img, callback) ->
  121 + domImg = img.get(0)
  122 + if domImg.complete
  123 + callback.call(this, domImg.naturalWidth, domImg.naturalHeight)
  124 + else
  125 + img.on 'load', =>
  126 + callback.call(this, domImg.naturalWidth, domImg.naturalHeight)
  127 +
  128 +this.ImageFile = ImageFile
0 129 \ No newline at end of file
... ...
app/assets/javascripts/commits.js
... ... @@ -1,59 +0,0 @@
1   -var CommitsList = {
2   - ref:null,
3   - limit:0,
4   - offset:0,
5   - disable:false,
6   -
7   - init:
8   - function(ref, limit) {
9   - $(".day-commits-table li.commit").live('click', function(e){
10   - if(e.target.nodeName != "A") {
11   - location.href = $(this).attr("url");
12   - e.stopPropagation();
13   - return false;
14   - }
15   - });
16   -
17   - this.ref=ref;
18   - this.limit=limit;
19   - this.offset=limit;
20   - this.initLoadMore();
21   - $('.loading').show();
22   - },
23   -
24   - getOld:
25   - function() {
26   - $('.loading').show();
27   - $.ajax({
28   - type: "GET",
29   - url: location.href,
30   - data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref,
31   - complete: function(){ $('.loading').hide()},
32   - dataType: "script"});
33   - },
34   -
35   - append:
36   - function(count, html) {
37   - $("#commits_list").append(html);
38   - if(count > 0) {
39   - this.offset += count;
40   - } else {
41   - this.disable = true;
42   - }
43   - },
44   -
45   - initLoadMore:
46   - function() {
47   - $(document).endlessScroll({
48   - bottomPixels: 400,
49   - fireDelay: 1000,
50   - fireOnce:true,
51   - ceaseFire: function() {
52   - return CommitsList.disable;
53   - },
54   - callback: function(i) {
55   - CommitsList.getOld();
56   - }
57   - });
58   - }
59   -}
app/assets/javascripts/commits.js.coffee 0 → 100644
... ... @@ -0,0 +1,54 @@
  1 +class CommitsList
  2 + @data =
  3 + ref: null
  4 + limit: 0
  5 + offset: 0
  6 + @disable = false
  7 +
  8 + @showProgress: ->
  9 + $('.loading').show()
  10 +
  11 + @hideProgress: ->
  12 + $('.loading').hide()
  13 +
  14 + @init: (ref, limit) ->
  15 + $(".day-commits-table li.commit").live 'click', (event) ->
  16 + if event.target.nodeName != "A"
  17 + location.href = $(this).attr("url")
  18 + e.stopPropagation()
  19 + return false
  20 +
  21 + @data.ref = ref
  22 + @data.limit = limit
  23 + @data.offset = limit
  24 +
  25 + this.initLoadMore()
  26 + this.showProgress();
  27 +
  28 + @getOld: ->
  29 + this.showProgress()
  30 + $.ajax
  31 + type: "GET"
  32 + url: location.href
  33 + data: @data
  34 + complete: this.hideProgress
  35 + dataType: "script"
  36 +
  37 + @append: (count, html) ->
  38 + $("#commits-list").append(html)
  39 + if count > 0
  40 + @data.offset += count
  41 + else
  42 + @disable = true
  43 +
  44 + @initLoadMore: ->
  45 + $(document).endlessScroll
  46 + bottomPixels: 400
  47 + fireDelay: 1000
  48 + fireOnce: true
  49 + ceaseFire: =>
  50 + @disable
  51 + callback: =>
  52 + this.getOld()
  53 +
  54 +this.CommitsList = CommitsList
0 55 \ No newline at end of file
... ...
app/assets/stylesheets/common.scss
... ... @@ -338,7 +338,7 @@ li.note {
338 338 li {
339 339 border-bottom:none !important;
340 340 }
341   - .file {
  341 + .attachment {
342 342 padding-left: 20px;
343 343 background:url("icon-attachment.png") no-repeat left center;
344 344 }
... ...
app/assets/stylesheets/gitlab_bootstrap/files.scss
... ... @@ -135,7 +135,7 @@
135 135 pre {
136 136 border: none;
137 137 border-radius: 0;
138   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  138 + font-family: $monospace_font;
139 139 font-size: 12px !important;
140 140 line-height: 16px !important;
141 141 margin: 0;
... ...
app/assets/stylesheets/gitlab_bootstrap/fonts.scss
... ... @@ -4,4 +4,4 @@
4 4 }
5 5  
6 6 /** Typo **/
7   -$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
  7 +$monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
... ...
app/assets/stylesheets/gitlab_bootstrap/typography.scss
... ... @@ -21,7 +21,7 @@ h6 {
21 21  
22 22 /** CODE **/
23 23 pre {
24   - font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  24 + font-family: $monospace_font;
25 25  
26 26 &.dark {
27 27 background: #333;
... ... @@ -79,7 +79,7 @@ a:focus {
79 79 }
80 80  
81 81 .monospace {
82   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  82 + font-family: $monospace_font;
83 83 }
84 84  
85 85 /**
... ...
app/assets/stylesheets/gitlab_bootstrap/variables.scss
1   -/** Colors **/
  1 +/**
  2 + * General Colors
  3 + */
2 4 $primary_color: #2FA0BB;
3 5 $link_color: #3A89A3;
4 6 $style_color: #474D57;
5 7 $hover: #D9EDF7;
  8 +
  9 +/**
  10 + * Commit Diff Colors
  11 + */
  12 +$added: #63c363;
  13 +$deleted: #f77;
... ...
app/assets/stylesheets/sections/commits.scss
1 1 /**
2   - *
3   - * COMMIT SHOw
4   - *
  2 + * Commit file
5 3 */
6 4 .commit-committer-link,
7 5 .commit-author-link {
... ... @@ -12,11 +10,11 @@
12 10 }
13 11 }
14 12  
15   -.diff_file {
  13 +.file {
16 14 border: 1px solid #CCC;
17 15 margin-bottom: 1em;
18 16  
19   - .diff_file_header {
  17 + .header {
20 18 @extend .clearfix;
21 19 padding: 5px 5px 5px 10px;
22 20 color: #555;
... ... @@ -28,32 +26,35 @@
28 26 background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
29 27 background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
30 28  
  29 + a{
  30 + color: $style_color;
  31 + }
  32 +
31 33 > span {
32   - font-family: $monospace;
  34 + font-family: $monospace_font;
33 35 font-size: 14px;
34 36 line-height: 30px;
35 37 }
36 38  
37   - a.view-commit{
  39 + a.view-file{
38 40 font-weight: bold;
39 41 }
40 42  
41 43 .commit-short-id{
42   - font-family: $monospace;
  44 + font-family: $monospace_font;
43 45 font-size: smaller;
44 46 }
45 47  
46 48 .file-mode{
47   - font-family: $monospace;
  49 + font-family: $monospace_font;
48 50 }
49 51 }
50   - .diff_file_content {
  52 + .content {
51 53 overflow: auto;
52 54 overflow-y: hidden;
53   - background: #fff;
  55 + background: #FFF;
54 56 color: #333;
55 57 font-size: 12px;
56   - font-family: $monospace;
57 58 .old{
58 59 span.idiff{
59 60 background-color: #FAA;
... ... @@ -66,114 +67,274 @@
66 67 }
67 68  
68 69 table {
  70 + font-family: $monospace_font;
  71 + border: none;
  72 + margin: 0px;
  73 + padding: 0px;
69 74 td {
70 75 line-height: 18px;
  76 + font-size: 12px;
  77 + }
  78 + }
  79 + .old_line, .new_line {
  80 + margin: 0px;
  81 + padding: 0px;
  82 + border: none;
  83 + background: #EEE;
  84 + color: #666;
  85 + padding: 0px 5px;
  86 + border-right: 1px solid #ccc;
  87 + text-align: right;
  88 + min-width: 35px;
  89 + max-width: 35px;
  90 + width: 35px;
  91 + @include user-select(none);
  92 + a {
  93 + float: left;
  94 + width: 35px;
  95 + font-weight: normal;
  96 + color: #666;
  97 + &:hover {
  98 + text-decoration: underline;
  99 + }
  100 + }
  101 + }
  102 + .line_content {
  103 + white-space: pre;
  104 + height: 14px;
  105 + margin: 0px;
  106 + padding: 0px;
  107 + border: none;
  108 + &.new {
  109 + background: #CFD;
  110 + }
  111 + &.old {
  112 + background: #FDD;
  113 + }
  114 + &.matched {
  115 + color: #ccc;
  116 + background: #fafafa;
71 117 }
72 118 }
73 119 }
74   - .diff_file_content_image {
75   - background: #eee;
  120 + .image {
  121 + background: #ddd;
76 122 text-align: center;
77   - .image {
  123 + padding: 30px;
  124 + .wrap{
78 125 display: inline-block;
79   - margin: 50px;
80   - max-width: 400px;
81   -
  126 + }
  127 +
  128 + .frame {
  129 + display: inline-block;
  130 + background-color: #fff;
  131 + line-height: 0;
82 132 img{
  133 + border: 1px solid #FFF;
83 134 background: url('trans_bg.gif');
84 135 }
  136 + &.deleted {
  137 + border: 1px solid $deleted;
  138 + }
85 139  
86   - &.diff_removed {
87   - img{
88   - border: 1px solid #C00;
89   - }
  140 + &.added {
  141 + border: 1px solid $added;
90 142 }
  143 + }
  144 + .image-info{
  145 + font-size: 12px;
  146 + margin: 5px 0 0 0;
  147 + color: grey;
  148 + }
91 149  
92   - &.diff_added {
93   - img{
94   - border: 1px solid #0C0;
  150 + .view.swipe{
  151 + position: relative;
  152 +
  153 + .swipe-frame{
  154 + display: block;
  155 + margin: auto;
  156 + position: relative;
  157 + }
  158 + .swipe-wrap{
  159 + overflow: hidden;
  160 + border-left: 1px solid #999;
  161 + position: absolute;
  162 + display: block;
  163 + top: 13px;
  164 + right: 7px;
  165 + }
  166 + .frame{
  167 + top: 0;
  168 + right: 0;
  169 + position: absolute;
  170 + &.deleted{
  171 + margin: 0;
  172 + display: block;
  173 + top: 13px;
  174 + right: 7px;
95 175 }
96 176 }
97   -
98   - .image-info{
99   - margin: 5px 0 0 0;
  177 + .swipe-bar{
  178 + display: block;
  179 + height: 100%;
  180 + width: 15px;
  181 + z-index: 100;
  182 + position: absolute;
  183 + cursor: pointer;
  184 + &:hover{
  185 + .top-handle{
  186 + background-position: -15px 3px;
  187 + }
  188 + .bottom-handle{
  189 + background-position: -15px -11px;
  190 + }
  191 + };
  192 + .top-handle{
  193 + display: block;
  194 + height: 14px;
  195 + width: 15px;
  196 + position: absolute;
  197 + top: 0px;
  198 + background: url('swipemode_sprites.gif') 0 3px no-repeat;
  199 + }
  200 + .bottom-handle{
  201 + display: block;
  202 + height: 14px;
  203 + width: 15px;
  204 + position: absolute;
  205 + bottom: 0px;
  206 + background: url('swipemode_sprites.gif') 0 -11px no-repeat;
  207 + }
100 208 }
101   - }
102   -
103   - &.img_compared {
104   - .image {
105   - max-width: 300px;
  209 + } //.view.swipe
  210 + .view.onion-skin{
  211 + .onion-skin-frame{
  212 + display: block;
  213 + margin: auto;
  214 + position: relative;
106 215 }
107   - }
  216 + .frame.added, .frame.deleted {
  217 + position: absolute;
  218 + display: block;
  219 + top: 0px;
  220 + left: 0px;
  221 + }
  222 + .controls{
  223 + display: block;
  224 + height: 14px;
  225 + width: 300px;
  226 + z-index: 100;
  227 + position: absolute;
  228 + bottom: 0px;
  229 + left: 50%;
  230 + margin-left: -150px;
  231 +
  232 + .drag-track{
  233 + display: block;
  234 + position: absolute;
  235 + left: 12px;
  236 + height: 10px;
  237 + width: 276px;
  238 + background: url('onion_skin_sprites.gif') -4px -20px repeat-x;
  239 + }
  240 +
  241 + .dragger {
  242 + display: block;
  243 + position: absolute;
  244 + left: 0px;
  245 + top: 0px;
  246 + height: 14px;
  247 + width: 14px;
  248 + background: url('onion_skin_sprites.gif') 0px -34px repeat-x;
  249 + cursor: pointer;
  250 + }
  251 +
  252 + .transparent {
  253 + display: block;
  254 + position: absolute;
  255 + top: 2px;
  256 + right: 0px;
  257 + height: 10px;
  258 + width: 10px;
  259 + background: url('onion_skin_sprites.gif') -2px 0px no-repeat;
  260 + }
  261 +
  262 + .opaque {
  263 + display: block;
  264 + position: absolute;
  265 + top: 2px;
  266 + left: 0px;
  267 + height: 10px;
  268 + width: 10px;
  269 + background: url('onion_skin_sprites.gif') -2px -10px no-repeat;
  270 + }
  271 + }
  272 + } //.view.onion-skin
108 273 }
109   -}
  274 + .view-modes{
110 275  
111   -.diff_file_content{
112   - table {
113   - border: none;
114   - margin: 0px;
115   - padding: 0px;
116   - tr {
117   - td {
118   - font-size: 12px;
119   - }
  276 + padding: 10px;
  277 + text-align: center;
  278 +
  279 + background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
  280 + background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
  281 + background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
  282 + background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
  283 +
  284 + ul, li{
  285 + list-style: none;
  286 + margin: 0;
  287 + padding: 0;
  288 + display: inline-block;
120 289 }
121   - }
122   - .new_line,
123   - .old_line,
124   - .notes_line {
125   - margin:0px;
126   - padding:0px;
127   - border:none;
128   - background:#EEE;
129   - color:#666;
130   - padding: 0px 5px;
131   - border-right: 1px solid #ccc;
132   - text-align: right;
133   - min-width: 35px;
134   - max-width: 35px;
135   - width: 35px;
136   - moz-user-select: none;
137   - -khtml-user-select: none;
138   - user-select: none;
139   -
140   - a {
141   - float: left;
142   - width: 35px;
143   - font-weight: normal;
144   - color: #666;
145   - &:hover {
  290 +
  291 + li{
  292 + color: grey;
  293 + border-left: 1px solid #c1c1c1;
  294 + padding: 0 12px 0 16px;
  295 + cursor: pointer;
  296 + &:first-child{
  297 + border-left: none;
  298 + }
  299 + &:hover{
146 300 text-decoration: underline;
147 301 }
148   - }
149   - }
150   - .line_content {
151   - white-space: pre;
152   - height: 14px;
153   - margin: 0px;
154   - padding: 0px;
155   - border: none;
156   - &.new {
157   - background: #CFD;
158   - }
159   - &.old {
160   - background: #FDD;
161   - }
162   - &.matched {
163   - color: #ccc;
164   - background: #fafafa;
  302 + &.active{
  303 + &:hover{
  304 + text-decoration: none;
  305 + }
  306 + cursor: default;
  307 + color: #333;
  308 + }
  309 + &.disabled{
  310 + display: none;
  311 + }
165 312 }
166 313 }
167 314 }
168 315  
169 316 /** COMMIT BLOCK **/
170   -.commit-title{display: block;}
171   -.commit-title{margin-bottom: 10px}
172   -.commit-author, .commit-committer{display: block;color: #999; font-weight: normal; font-style: italic;}
173   -.commit-author strong, .commit-committer strong{font-weight: bold; font-style: normal;}
  317 +.commit-title{
  318 + display: block;
  319 +}
  320 +.commit-title{
  321 + margin-bottom: 10px;
  322 +}
  323 +.commit-author, .commit-committer{
  324 + display: block;
  325 + color: #999;
  326 + font-weight: normal;
  327 + font-style: italic;
  328 +}
  329 +.commit-author strong, .commit-committer strong{
  330 + font-weight: bold;
  331 + font-style: normal;
  332 +}
174 333  
175 334  
176   -/** COMMIT ROW **/
  335 +/**
  336 + * COMMIT ROW
  337 + */
177 338 .commit {
178 339 .browse_code_link_holder {
179 340 @extend .span2;
... ... @@ -199,11 +360,10 @@
199 360 float: left;
200 361 @extend .lined;
201 362 min-width: 65px;
202   - font-family: $monospace;
  363 + font-family: $monospace_font;
203 364 }
204 365 }
205 366  
206   -.diff_file_header a,
207 367 .file-stats a {
208 368 color: $style_color;
209 369 }
... ... @@ -237,7 +397,7 @@
237 397 font-size: 13px;
238 398 background: #474D57;
239 399 color: #fff;
240   - font-family: $monospace;
  400 + font-family: $monospace_font;
241 401 }
242 402  
243 403  
... ...
app/assets/stylesheets/sections/merge_requests.scss
... ... @@ -77,7 +77,7 @@ li.merge_request {
77 77 font-size: 14px;
78 78 background: #474D57;
79 79 color: #fff;
80   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  80 + font-family: $monospace_font;
81 81 }
82 82  
83 83 .mr_source_commit,
... ...
app/assets/stylesheets/sections/notes.scss
... ... @@ -40,13 +40,13 @@ ul.notes {
40 40 .discussion-body {
41 41 margin-left: 50px;
42 42  
43   - .diff_file,
  43 + .file,
44 44 .discussion-hidden,
45 45 .notes {
46 46 @extend .borders;
47 47 background-color: #F9F9F9;
48 48 }
49   - .diff_file .notes {
  49 + .file .notes {
50 50 /* reset */
51 51 background: inherit;
52 52 border: none;
... ... @@ -109,7 +109,7 @@ ul.notes {
109 109 }
110 110 }
111 111  
112   -.diff_file .notes_holder {
  112 +.file .notes_holder {
113 113 font-family: $sansFontFamily;
114 114 font-size: 13px;
115 115 line-height: 18px;
... ... @@ -134,8 +134,6 @@ ul.notes {
134 134 }
135 135 }
136 136  
137   -
138   -
139 137 /**
140 138 * Actions for Discussions/Notes
141 139 */
... ... @@ -171,7 +169,7 @@ ul.notes {
171 169 }
172 170 }
173 171 }
174   -.diff_file .note .note-actions {
  172 +.file .note .note-actions {
175 173 right: 0;
176 174 top: 0;
177 175 }
... ... @@ -182,7 +180,7 @@ ul.notes {
182 180 * Line note button on the side of diffs
183 181 */
184 182  
185   -.diff_file tr.line_holder {
  183 +.file tr.line_holder {
186 184 .add-diff-note {
187 185 background: url("diff_note_add.png") no-repeat left 0;
188 186 height: 22px;
... ... @@ -212,8 +210,6 @@ ul.notes {
212 210 }
213 211 }
214 212  
215   -
216   -
217 213 /**
218 214 * Note Form
219 215 */
... ... @@ -222,7 +218,12 @@ ul.notes {
222 218 .reply-btn {
223 219 @extend .save-btn;
224 220 }
225   -.diff_file,
  221 +.file .content tr.line_holder:hover > td { background: $hover !important; }
  222 +.file .content tr.line_holder:hover > td .line_note_link {
  223 + opacity: 1.0;
  224 + filter: alpha(opacity=100);
  225 +}
  226 +.file,
226 227 .discussion {
227 228 .new_note {
228 229 margin: 8px 5px 8px 0;
... ...
app/helpers/commits_helper.rb
... ... @@ -59,9 +59,9 @@ module CommitsHelper
59 59  
60 60 def image_diff_class(diff)
61 61 if diff.deleted_file
62   - "diff_removed"
  62 + "deleted"
63 63 elsif diff.new_file
64   - "diff_added"
  64 + "added"
65 65 else
66 66 nil
67 67 end
... ...
app/views/commit/show.html.haml
... ... @@ -11,19 +11,7 @@
11 11  
12 12 :javascript
13 13 $(function(){
14   - var w, h;
15   - $('.diff_file').each(function(){
16   - $('.image.diff_removed img', this).on('load', $.proxy(function(event){
17   - var w = event.currentTarget.naturalWidth
18   - , h = event.currentTarget.naturalHeight;
19   - $('.image.diff_removed .image-info', this).append(' | <b>W:</b> ' + w + 'px | <b>H:</b> ' + h + 'px');
20   - }, this));
21   - $('.image.diff_added img', this).on('load', $.proxy(function(event){
22   - var w = event.currentTarget.naturalWidth
23   - , h = event.currentTarget.naturalHeight;
24   - $('.image.diff_added .image-info', this).append(' | <b>W:</b> ' + w + 'px | <b>H:</b> ' + h + 'px');
25   - }, this));
26   -
  14 + $('.files .file').each(function(){
  15 + new CommitFile(this);
27 16 });
28   -
29 17 });
... ...
app/views/commits/_diffs.html.haml
... ... @@ -12,50 +12,38 @@
12 12 .file-stats
13 13 = render "commits/diff_head", diffs: diffs
14 14  
15   -- unless @suppress_diff
16   - - diffs.each_with_index do |diff, i|
17   - - next if diff.diff.empty?
18   - - file = (@commit.tree / diff.new_path)
19   - - file = (@commit.prev_commit.tree / diff.old_path) unless file
20   - - next unless file
21   - .diff_file{id: "diff-#{i}"}
22   - .diff_file_header
23   - - if diff.deleted_file
24   - %span= diff.old_path
  15 +.files
  16 + - unless @suppress_diff
  17 + - diffs.each_with_index do |diff, i|
  18 + - next if diff.diff.empty?
  19 + - file = (@commit.tree / diff.new_path)
  20 + - file = (@commit.prev_commit.tree / diff.old_path) unless file
  21 + - next unless file
  22 + .file{id: "diff-#{i}"}
  23 + .header
  24 + - if diff.deleted_file
  25 + %span= diff.old_path
25 26  
26   - - if @commit.prev_commit
27   - = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-commit'} do
  27 + - if @commit.prev_commit
  28 + = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-file'} do
  29 + View file @
  30 + %span.commit-short-id= @commit.short_id(6)
  31 + - else
  32 + %span= diff.new_path
  33 + - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
  34 + %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
  35 +
  36 + = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn very_small right view-file'} do
28 37 View file @
29 38 %span.commit-short-id= @commit.short_id(6)
30   - - else
31   - %span= diff.new_path
32   - - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
33   - %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
34   -
35   - = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn very_small right view-commit'} do
36   - View file @
37   - %span.commit-short-id= @commit.short_id(6)
38 39  
39   - %br/
40   - .diff_file_content
41   - -# Skip all non-supported blobs
42   - - next unless file.respond_to?('text?')
43   - - if file.text?
44   - = render "commits/text_diff", diff: diff, index: i
45   - - elsif file.image?
46   - - old_file = (@commit.prev_commit.tree / diff.old_path) if !@commit.prev_commit.nil?
47   - - if diff.renamed_file || diff.new_file || diff.deleted_file
48   - .diff_file_content_image
49   - .image{class: image_diff_class(diff)}
50   - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
51   - %div.image-info= "#{number_to_human_size file.size}"
  40 + .content
  41 + -# Skipp all non non-supported blobs
  42 + - next unless file.respond_to?('text?')
  43 + - if file.text?
  44 + = render "commits/text_file", diff: diff, index: i
  45 + - elsif file.image?
  46 + - old_file = (@commit.prev_commit.tree / diff.old_path) if !@commit.prev_commit.nil?
  47 + = render "commits/image", diff: diff, old_file: old_file, file: file, index: i
52 48 - else
53   - .diff_file_content_image.img_compared
54   - .image.diff_removed
55   - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
56   - %div.image-info= "#{number_to_human_size file.size}"
57   - .image.diff_added
58   - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
59   - %div.image-info= "#{number_to_human_size file.size}"
60   - - else
61   - %p.nothing_here_message No preview for this file type
  49 + %p.nothing_here_message No preview for this file type
... ...
app/views/commits/_image.html.haml 0 → 100644
... ... @@ -0,0 +1,63 @@
  1 +- if diff.renamed_file || diff.new_file || diff.deleted_file
  2 + .image
  3 + %span.wrap
  4 + .frame{class: image_diff_class(diff)}
  5 + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
  6 + %p.image-info= "#{number_to_human_size file.size}"
  7 +- else
  8 + .image
  9 + %div.two-up.view
  10 + %span.wrap
  11 + .frame.deleted
  12 + %a{href: project_tree_path(@project, tree_join(@commit.id, diff.old_path))}
  13 + %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
  14 + %p.image-info.hide
  15 + %span.meta-filesize= "#{number_to_human_size old_file.size}"
  16 + |
  17 + %b W:
  18 + %span.meta-width
  19 + |
  20 + %b H:
  21 + %span.meta-height
  22 + %span.wrap
  23 + .frame.added
  24 + %a{href: project_tree_path(@project, tree_join(@commit.id, diff.new_path))}
  25 + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
  26 + %p.image-info.hide
  27 + %span.meta-filesize= "#{number_to_human_size file.size}"
  28 + |
  29 + %b W:
  30 + %span.meta-width
  31 + |
  32 + %b H:
  33 + %span.meta-height
  34 +
  35 + %div.swipe.view.hide
  36 + .swipe-frame
  37 + .frame.deleted
  38 + %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
  39 + .swipe-wrap
  40 + .frame.added
  41 + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
  42 + %span.swipe-bar
  43 + %span.top-handle
  44 + %span.bottom-handle
  45 +
  46 + %div.onion-skin.view.hide
  47 + .onion-skin-frame
  48 + .frame.deleted
  49 + %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
  50 + .frame.added
  51 + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
  52 + .controls
  53 + .transparent
  54 + .drag-track
  55 + .dragger{:style => "left: 0px;"}
  56 + .opaque
  57 +
  58 +
  59 + .view-modes.hide
  60 + %ul.view-modes-menu
  61 + %li.two-up{data: {mode: 'two-up'}} 2-up
  62 + %li.swipe{data: {mode: 'swipe'}} Swipe
  63 + %li.onion-skin{data: {mode: 'onion-skin'}} Onion skin
0 64 \ No newline at end of file
... ...
app/views/commits/_text_diff.html.haml
... ... @@ -1,23 +0,0 @@
1   -- too_big = diff.diff.lines.count > 1000
2   -- if too_big
3   - %a.supp_diff_link Diff suppressed. Click to show
4   -
5   -%table{class: "#{'hide' if too_big}"}
6   - - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old|
7   - %tr.line_holder{ id: line_code }
8   - - if type == "match"
9   - %td.old_line= "..."
10   - %td.new_line= "..."
11   - %td.line_content.matched= line
12   - - else
13   - %td.old_line
14   - = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
15   - - if @comments_allowed
16   - = render "notes/diff_note_link", line_code: line_code
17   - %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
18   - %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
19   -
20   - - if @reply_allowed
21   - - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at)
22   - - unless comments.empty?
23   - = render "notes/diff_notes_with_reply", notes: comments
app/views/commits/_text_file.html.haml 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +- too_big = diff.diff.lines.count > 1000
  2 +- if too_big
  3 + %a.supp_diff_link Diff suppressed. Click to show
  4 +
  5 +%table.text-file{class: "#{'hide' if too_big}"}
  6 + - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old|
  7 + %tr.line_holder{ id: line_code }
  8 + - if type == "match"
  9 + %td.old_line= "..."
  10 + %td.new_line= "..."
  11 + %td.line_content.matched= line
  12 + - else
  13 + %td.old_line
  14 + = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
  15 + - if @comments_allowed
  16 + = render "notes/diff_note_link", line_code: line_code
  17 + %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
  18 + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
  19 +
  20 + - if @reply_allowed
  21 + - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at)
  22 + - unless comments.empty?
  23 + = render "notes/diff_notes_with_reply", notes: comments
... ...
app/views/commits/show.html.haml
... ... @@ -5,7 +5,7 @@
5 5 = breadcrumbs
6 6  
7 7 %div{id: dom_id(@project)}
8   - #commits_list= render "commits"
  8 + #commits-list= render "commits"
9 9 .clear
10 10 .loading{ style: "display:none;"}
11 11  
... ...
app/views/notes/_discussion.html.haml
... ... @@ -38,7 +38,7 @@
38 38 - if note.for_diff_line?
39 39 - if note.diff
40 40 .content
41   - .diff_file= render "notes/discussion_diff", discussion_notes: discussion_notes, note: note
  41 + .file= render "notes/discussion_diff", discussion_notes: discussion_notes, note: note
42 42 - else
43 43 = link_to 'show outdated discussion', '#', class: 'js-show-outdated-discussion'
44 44 %div.hide.outdated-discussion
... ...
app/views/notes/_discussion_diff.html.haml
1 1 - diff = note.diff
2   -.diff_file_header
  2 +.header
3 3 - if diff.deleted_file
4 4 %span= diff.old_path
5 5 - else
... ... @@ -7,7 +7,7 @@
7 7 - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
8 8 %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
9 9 %br/
10   -.diff_file_content
  10 +.content
11 11 %table
12 12 - each_diff_line(diff, note.diff_file_index) do |line, type, line_code, line_new, line_old|
13 13 %tr.line_holder{ id: line_code }
... ...
features/steps/shared/diff_note.rb
... ... @@ -2,27 +2,27 @@ module SharedDiffNote
2 2 include Spinach::DSL
3 3  
4 4 Given 'I cancel the diff comment' do
5   - within(".diff_file") do
  5 + within(".file") do
6 6 find(".js-close-discussion-note-form").trigger("click")
7 7 end
8 8 end
9 9  
10 10 Given 'I delete a diff comment' do
11 11 sleep 1
12   - within(".diff_file") do
  12 + within(".file") do
13 13 first(".js-note-delete").trigger("click")
14 14 end
15 15 end
16 16  
17 17 Given 'I haven\'t written any diff comment text' do
18   - within(".diff_file") do
  18 + within(".file") do
19 19 fill_in "note[note]", with: ""
20 20 end
21 21 end
22 22  
23 23 Given 'I leave a diff comment like "Typo, please fix"' do
24 24 find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
25   - within(".diff_file") do
  25 + within(".file") do
26 26 fill_in "note[note]", with: "Typo, please fix"
27 27 #click_button("Add Comment")
28 28 find(".js-comment-button").trigger("click")
... ... @@ -32,7 +32,7 @@ module SharedDiffNote
32 32  
33 33 Given 'I preview a diff comment text like "Should fix it :smile:"' do
34 34 find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
35   - within(".diff_file") do
  35 + within(".file") do
36 36 fill_in "note[note]", with: "Should fix it :smile:"
37 37 find(".js-note-preview-button").trigger("click")
38 38 end
... ... @@ -40,7 +40,7 @@ module SharedDiffNote
40 40  
41 41 Given 'I preview another diff comment text like "DRY this up"' do
42 42 find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
43   - within(".diff_file") do
  43 + within(".file") do
44 44 fill_in "note[note]", with: "DRY this up"
45 45 find(".js-note-preview-button").trigger("click")
46 46 end
... ... @@ -55,13 +55,13 @@ module SharedDiffNote
55 55 end
56 56  
57 57 Given 'I write a diff comment like ":-1: I don\'t like this"' do
58   - within(".diff_file") do
  58 + within(".file") do
59 59 fill_in "note[note]", with: ":-1: I don\'t like this"
60 60 end
61 61 end
62 62  
63 63 Given 'I submit the diff comment' do
64   - within(".diff_file") do
  64 + within(".file") do
65 65 click_button("Add Comment")
66 66 end
67 67 end
... ... @@ -69,49 +69,49 @@ module SharedDiffNote
69 69  
70 70  
71 71 Then 'I should not see the diff comment form' do
72   - within(".diff_file") do
  72 + within(".file") do
73 73 page.should_not have_css("form.new_note")
74 74 end
75 75 end
76 76  
77 77 Then 'I should not see the diff comment preview button' do
78   - within(".diff_file") do
  78 + within(".file") do
79 79 page.should have_css(".js-note-preview-button", visible: false)
80 80 end
81 81 end
82 82  
83 83 Then 'I should not see the diff comment text field' do
84   - within(".diff_file") do
  84 + within(".file") do
85 85 page.should have_css(".js-note-text", visible: false)
86 86 end
87 87 end
88 88  
89 89 Then 'I should only see one diff form' do
90   - within(".diff_file") do
  90 + within(".file") do
91 91 page.should have_css("form.new_note", count: 1)
92 92 end
93 93 end
94 94  
95 95 Then 'I should see a diff comment form with ":-1: I don\'t like this"' do
96   - within(".diff_file") do
  96 + within(".file") do
97 97 page.should have_field("note[note]", with: ":-1: I don\'t like this")
98 98 end
99 99 end
100 100  
101 101 Then 'I should see a diff comment saying "Typo, please fix"' do
102   - within(".diff_file .note") do
  102 + within(".file .note") do
103 103 page.should have_content("Typo, please fix")
104 104 end
105 105 end
106 106  
107 107 Then 'I should see a discussion reply button' do
108   - within(".diff_file") do
  108 + within(".file") do
109 109 page.should have_link("Reply")
110 110 end
111 111 end
112 112  
113 113 Then 'I should see a temporary diff comment form' do
114   - within(".diff_file") do
  114 + within(".file") do
115 115 page.should have_css(".js-temp-notes-holder form.new_note")
116 116 end
117 117 end
... ... @@ -121,37 +121,37 @@ module SharedDiffNote
121 121 end
122 122  
123 123 Then 'I should see an empty diff comment form' do
124   - within(".diff_file") do
  124 + within(".file") do
125 125 page.should have_field("note[note]", with: "")
126 126 end
127 127 end
128 128  
129 129 Then 'I should see the cancel comment button' do
130   - within(".diff_file form") do
  130 + within(".file form") do
131 131 page.should have_css(".js-close-discussion-note-form", text: "Cancel")
132 132 end
133 133 end
134 134  
135 135 Then 'I should see the diff comment preview' do
136   - within(".diff_file form") do
  136 + within(".file form") do
137 137 page.should have_css(".js-note-preview", visible: false)
138 138 end
139 139 end
140 140  
141 141 Then 'I should see the diff comment edit button' do
142   - within(".diff_file") do
  142 + within(".file") do
143 143 page.should have_css(".js-note-edit-button", visible: true)
144 144 end
145 145 end
146 146  
147 147 Then 'I should see the diff comment preview button' do
148   - within(".diff_file") do
  148 + within(".file") do
149 149 page.should have_css(".js-note-preview-button", visible: true)
150 150 end
151 151 end
152 152  
153 153 Then 'I should see two separate previews' do
154   - within(".diff_file") do
  154 + within(".file") do
155 155 page.should have_css(".js-note-preview", visible: true, count: 2)
156 156 page.should have_content("Should fix it")
157 157 page.should have_content("DRY this up")
... ...