##// END OF EJS Templates
comments: make add arrow slightly smaller, and not hide the line numbers when hover.
marcink -
r1160:a4d6d4c7 default
parent child Browse files
Show More
@@ -1,1174 +1,1176 b''
1 // Default styles
1 // Default styles
2
2
3 .diff-collapse {
3 .diff-collapse {
4 margin: @padding 0;
4 margin: @padding 0;
5 text-align: right;
5 text-align: right;
6 }
6 }
7
7
8 .diff-container {
8 .diff-container {
9 margin-bottom: @space;
9 margin-bottom: @space;
10
10
11 .diffblock {
11 .diffblock {
12 margin-bottom: @space;
12 margin-bottom: @space;
13 }
13 }
14
14
15 &.hidden {
15 &.hidden {
16 display: none;
16 display: none;
17 overflow: hidden;
17 overflow: hidden;
18 }
18 }
19 }
19 }
20
20
21 .compare_view_files {
21 .compare_view_files {
22
22
23 .diff-container {
23 .diff-container {
24
24
25 .diffblock {
25 .diffblock {
26 margin-bottom: 0;
26 margin-bottom: 0;
27 }
27 }
28 }
28 }
29 }
29 }
30
30
31 div.diffblock .sidebyside {
31 div.diffblock .sidebyside {
32 background: #ffffff;
32 background: #ffffff;
33 }
33 }
34
34
35 div.diffblock {
35 div.diffblock {
36 overflow-x: auto;
36 overflow-x: auto;
37 overflow-y: hidden;
37 overflow-y: hidden;
38 clear: both;
38 clear: both;
39 padding: 0px;
39 padding: 0px;
40 background: @grey6;
40 background: @grey6;
41 border: @border-thickness solid @grey5;
41 border: @border-thickness solid @grey5;
42 -webkit-border-radius: @border-radius @border-radius 0px 0px;
42 -webkit-border-radius: @border-radius @border-radius 0px 0px;
43 border-radius: @border-radius @border-radius 0px 0px;
43 border-radius: @border-radius @border-radius 0px 0px;
44
44
45
45
46 .comments-number {
46 .comments-number {
47 float: right;
47 float: right;
48 }
48 }
49
49
50 // BEGIN CODE-HEADER STYLES
50 // BEGIN CODE-HEADER STYLES
51
51
52 .code-header {
52 .code-header {
53 background: @grey6;
53 background: @grey6;
54 padding: 10px 0 10px 0;
54 padding: 10px 0 10px 0;
55 height: auto;
55 height: auto;
56 width: 100%;
56 width: 100%;
57
57
58 .hash {
58 .hash {
59 float: left;
59 float: left;
60 padding: 2px 0 0 2px;
60 padding: 2px 0 0 2px;
61 }
61 }
62
62
63 .date {
63 .date {
64 float: left;
64 float: left;
65 text-transform: uppercase;
65 text-transform: uppercase;
66 padding: 4px 0px 0px 2px;
66 padding: 4px 0px 0px 2px;
67 }
67 }
68
68
69 div {
69 div {
70 margin-left: 4px;
70 margin-left: 4px;
71 }
71 }
72
72
73 div.compare_header {
73 div.compare_header {
74 min-height: 40px;
74 min-height: 40px;
75 margin: 0;
75 margin: 0;
76 padding: 0 @padding;
76 padding: 0 @padding;
77
77
78 .drop-menu {
78 .drop-menu {
79 float:left;
79 float:left;
80 display: block;
80 display: block;
81 margin:0 0 @padding 0;
81 margin:0 0 @padding 0;
82 }
82 }
83
83
84 .compare-label {
84 .compare-label {
85 float: left;
85 float: left;
86 clear: both;
86 clear: both;
87 display: inline-block;
87 display: inline-block;
88 min-width: 5em;
88 min-width: 5em;
89 margin: 0;
89 margin: 0;
90 padding: @button-padding @button-padding @button-padding 0;
90 padding: @button-padding @button-padding @button-padding 0;
91 font-family: @text-semibold;
91 font-family: @text-semibold;
92 }
92 }
93
93
94 .compare-buttons {
94 .compare-buttons {
95 float: left;
95 float: left;
96 margin: 0;
96 margin: 0;
97 padding: 0 0 @padding;
97 padding: 0 0 @padding;
98
98
99 .btn {
99 .btn {
100 margin: 0 @padding 0 0;
100 margin: 0 @padding 0 0;
101 }
101 }
102 }
102 }
103 }
103 }
104
104
105 }
105 }
106
106
107 .parents {
107 .parents {
108 float: left;
108 float: left;
109 width: 100px;
109 width: 100px;
110 font-weight: 400;
110 font-weight: 400;
111 vertical-align: middle;
111 vertical-align: middle;
112 padding: 0px 2px 0px 2px;
112 padding: 0px 2px 0px 2px;
113 background-color: @grey6;
113 background-color: @grey6;
114
114
115 #parent_link {
115 #parent_link {
116 margin: 00px 2px;
116 margin: 00px 2px;
117
117
118 &.double {
118 &.double {
119 margin: 0px 2px;
119 margin: 0px 2px;
120 }
120 }
121
121
122 &.disabled{
122 &.disabled{
123 margin-right: @padding;
123 margin-right: @padding;
124 }
124 }
125 }
125 }
126 }
126 }
127
127
128 .children {
128 .children {
129 float: right;
129 float: right;
130 width: 100px;
130 width: 100px;
131 font-weight: 400;
131 font-weight: 400;
132 vertical-align: middle;
132 vertical-align: middle;
133 text-align: right;
133 text-align: right;
134 padding: 0px 2px 0px 2px;
134 padding: 0px 2px 0px 2px;
135 background-color: @grey6;
135 background-color: @grey6;
136
136
137 #child_link {
137 #child_link {
138 margin: 0px 2px;
138 margin: 0px 2px;
139
139
140 &.double {
140 &.double {
141 margin: 0px 2px;
141 margin: 0px 2px;
142 }
142 }
143
143
144 &.disabled{
144 &.disabled{
145 margin-right: @padding;
145 margin-right: @padding;
146 }
146 }
147 }
147 }
148 }
148 }
149
149
150 .changeset_header {
150 .changeset_header {
151 height: 16px;
151 height: 16px;
152
152
153 & > div{
153 & > div{
154 margin-right: @padding;
154 margin-right: @padding;
155 }
155 }
156 }
156 }
157
157
158 .changeset_file {
158 .changeset_file {
159 text-align: left;
159 text-align: left;
160 float: left;
160 float: left;
161 padding: 0;
161 padding: 0;
162
162
163 a{
163 a{
164 display: inline-block;
164 display: inline-block;
165 margin-right: 0.5em;
165 margin-right: 0.5em;
166 }
166 }
167
167
168 #selected_mode{
168 #selected_mode{
169 margin-left: 0;
169 margin-left: 0;
170 }
170 }
171 }
171 }
172
172
173 .diff-menu-wrapper {
173 .diff-menu-wrapper {
174 float: left;
174 float: left;
175 }
175 }
176
176
177 .diff-menu {
177 .diff-menu {
178 position: absolute;
178 position: absolute;
179 background: none repeat scroll 0 0 #FFFFFF;
179 background: none repeat scroll 0 0 #FFFFFF;
180 border-color: #003367 @grey3 @grey3;
180 border-color: #003367 @grey3 @grey3;
181 border-right: 1px solid @grey3;
181 border-right: 1px solid @grey3;
182 border-style: solid solid solid;
182 border-style: solid solid solid;
183 border-width: @border-thickness;
183 border-width: @border-thickness;
184 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
184 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
185 margin-top: 5px;
185 margin-top: 5px;
186 margin-left: 1px;
186 margin-left: 1px;
187 }
187 }
188
188
189 .diff-actions, .editor-actions {
189 .diff-actions, .editor-actions {
190 float: left;
190 float: left;
191
191
192 input{
192 input{
193 margin: 0 0.5em 0 0;
193 margin: 0 0.5em 0 0;
194 }
194 }
195 }
195 }
196
196
197 // END CODE-HEADER STYLES
197 // END CODE-HEADER STYLES
198
198
199 // BEGIN CODE-BODY STYLES
199 // BEGIN CODE-BODY STYLES
200
200
201 .code-body {
201 .code-body {
202 background: white;
202 background: white;
203 padding: 0;
203 padding: 0;
204 background-color: #ffffff;
204 background-color: #ffffff;
205 position: relative;
205 position: relative;
206 max-width: none;
206 max-width: none;
207 box-sizing: border-box;
207 box-sizing: border-box;
208 // TODO: johbo: Parent has overflow: auto, this forces the child here
208 // TODO: johbo: Parent has overflow: auto, this forces the child here
209 // to have the intended size and to scroll. Should be simplified.
209 // to have the intended size and to scroll. Should be simplified.
210 width: 100%;
210 width: 100%;
211 overflow-x: auto;
211 overflow-x: auto;
212 }
212 }
213
213
214 pre.raw {
214 pre.raw {
215 background: white;
215 background: white;
216 color: @grey1;
216 color: @grey1;
217 }
217 }
218 // END CODE-BODY STYLES
218 // END CODE-BODY STYLES
219
219
220 }
220 }
221
221
222
222
223 table.code-difftable {
223 table.code-difftable {
224 border-collapse: collapse;
224 border-collapse: collapse;
225 width: 99%;
225 width: 99%;
226 border-radius: 0px !important;
226 border-radius: 0px !important;
227
227
228 td {
228 td {
229 padding: 0 !important;
229 padding: 0 !important;
230 background: none !important;
230 background: none !important;
231 border: 0 !important;
231 border: 0 !important;
232 }
232 }
233
233
234 .context {
234 .context {
235 background: none repeat scroll 0 0 #DDE7EF;
235 background: none repeat scroll 0 0 #DDE7EF;
236 }
236 }
237
237
238 .add {
238 .add {
239 background: none repeat scroll 0 0 #DDFFDD;
239 background: none repeat scroll 0 0 #DDFFDD;
240
240
241 ins {
241 ins {
242 background: none repeat scroll 0 0 #AAFFAA;
242 background: none repeat scroll 0 0 #AAFFAA;
243 text-decoration: none;
243 text-decoration: none;
244 }
244 }
245 }
245 }
246
246
247 .del {
247 .del {
248 background: none repeat scroll 0 0 #FFDDDD;
248 background: none repeat scroll 0 0 #FFDDDD;
249
249
250 del {
250 del {
251 background: none repeat scroll 0 0 #FFAAAA;
251 background: none repeat scroll 0 0 #FFAAAA;
252 text-decoration: none;
252 text-decoration: none;
253 }
253 }
254 }
254 }
255
255
256 /** LINE NUMBERS **/
256 /** LINE NUMBERS **/
257 .lineno {
257 .lineno {
258 padding-left: 2px !important;
258 padding-left: 2px !important;
259 padding-right: 2px;
259 padding-right: 2px;
260 text-align: right;
260 text-align: right;
261 width: 32px;
261 width: 32px;
262 -moz-user-select: none;
262 -moz-user-select: none;
263 -webkit-user-select: none;
263 -webkit-user-select: none;
264 border-right: @border-thickness solid @grey5 !important;
264 border-right: @border-thickness solid @grey5 !important;
265 border-left: 0px solid #CCC !important;
265 border-left: 0px solid #CCC !important;
266 border-top: 0px solid #CCC !important;
266 border-top: 0px solid #CCC !important;
267 border-bottom: none !important;
267 border-bottom: none !important;
268
268
269 a {
269 a {
270 &:extend(pre);
270 &:extend(pre);
271 text-align: right;
271 text-align: right;
272 padding-right: 2px;
272 padding-right: 2px;
273 cursor: pointer;
273 cursor: pointer;
274 display: block;
274 display: block;
275 width: 32px;
275 width: 32px;
276 }
276 }
277 }
277 }
278
278
279 .context {
279 .context {
280 cursor: auto;
280 cursor: auto;
281 &:extend(pre);
281 &:extend(pre);
282 }
282 }
283
283
284 .lineno-inline {
284 .lineno-inline {
285 background: none repeat scroll 0 0 #FFF !important;
285 background: none repeat scroll 0 0 #FFF !important;
286 padding-left: 2px;
286 padding-left: 2px;
287 padding-right: 2px;
287 padding-right: 2px;
288 text-align: right;
288 text-align: right;
289 width: 30px;
289 width: 30px;
290 -moz-user-select: none;
290 -moz-user-select: none;
291 -webkit-user-select: none;
291 -webkit-user-select: none;
292 }
292 }
293
293
294 /** CODE **/
294 /** CODE **/
295 .code {
295 .code {
296 display: block;
296 display: block;
297 width: 100%;
297 width: 100%;
298
298
299 td {
299 td {
300 margin: 0;
300 margin: 0;
301 padding: 0;
301 padding: 0;
302 }
302 }
303
303
304 pre {
304 pre {
305 margin: 0;
305 margin: 0;
306 padding: 0;
306 padding: 0;
307 margin-left: .5em;
307 margin-left: .5em;
308 }
308 }
309 }
309 }
310 }
310 }
311
311
312
312
313 // Comments
313 // Comments
314
314
315 div.comment:target {
315 div.comment:target {
316 border-left: 6px solid @comment-highlight-color;
316 border-left: 6px solid @comment-highlight-color;
317 padding-left: 3px;
317 padding-left: 3px;
318 margin-left: -9px;
318 margin-left: -9px;
319 }
319 }
320
320
321 //TODO: anderson: can't get an absolute number out of anything, so had to put the
321 //TODO: anderson: can't get an absolute number out of anything, so had to put the
322 //current values that might change. But to make it clear I put as a calculation
322 //current values that might change. But to make it clear I put as a calculation
323 @comment-max-width: 1065px;
323 @comment-max-width: 1065px;
324 @pr-extra-margin: 34px;
324 @pr-extra-margin: 34px;
325 @pr-border-spacing: 4px;
325 @pr-border-spacing: 4px;
326 @pr-comment-width: @comment-max-width - @pr-extra-margin - @pr-border-spacing;
326 @pr-comment-width: @comment-max-width - @pr-extra-margin - @pr-border-spacing;
327
327
328 // Pull Request
328 // Pull Request
329 .cs_files .code-difftable {
329 .cs_files .code-difftable {
330 border: @border-thickness solid @grey5; //borders only on PRs
330 border: @border-thickness solid @grey5; //borders only on PRs
331
331
332 .comment-inline-form,
332 .comment-inline-form,
333 div.comment {
333 div.comment {
334 width: @pr-comment-width;
334 width: @pr-comment-width;
335 }
335 }
336 }
336 }
337
337
338 // Changeset
338 // Changeset
339 .code-difftable {
339 .code-difftable {
340 .comment-inline-form,
340 .comment-inline-form,
341 div.comment {
341 div.comment {
342 width: @comment-max-width;
342 width: @comment-max-width;
343 }
343 }
344 }
344 }
345
345
346 //Style page
346 //Style page
347 @style-extra-margin: @sidebar-width + (@sidebarpadding * 3) + @padding;
347 @style-extra-margin: @sidebar-width + (@sidebarpadding * 3) + @padding;
348 #style-page .code-difftable{
348 #style-page .code-difftable{
349 .comment-inline-form,
349 .comment-inline-form,
350 div.comment {
350 div.comment {
351 width: @comment-max-width - @style-extra-margin;
351 width: @comment-max-width - @style-extra-margin;
352 }
352 }
353 }
353 }
354
354
355 #context-bar > h2 {
355 #context-bar > h2 {
356 font-size: 20px;
356 font-size: 20px;
357 }
357 }
358
358
359 #context-bar > h2> a {
359 #context-bar > h2> a {
360 font-size: 20px;
360 font-size: 20px;
361 }
361 }
362 // end of defaults
362 // end of defaults
363
363
364 .file_diff_buttons {
364 .file_diff_buttons {
365 padding: 0 0 @padding;
365 padding: 0 0 @padding;
366
366
367 .drop-menu {
367 .drop-menu {
368 float: left;
368 float: left;
369 margin: 0 @padding 0 0;
369 margin: 0 @padding 0 0;
370 }
370 }
371 .btn {
371 .btn {
372 margin: 0 @padding 0 0;
372 margin: 0 @padding 0 0;
373 }
373 }
374 }
374 }
375
375
376 .code-body.textarea.editor {
376 .code-body.textarea.editor {
377 max-width: none;
377 max-width: none;
378 padding: 15px;
378 padding: 15px;
379 }
379 }
380
380
381 td.injected_diff{
381 td.injected_diff{
382 max-width: 1178px;
382 max-width: 1178px;
383 overflow-x: auto;
383 overflow-x: auto;
384 overflow-y: hidden;
384 overflow-y: hidden;
385
385
386 div.diff-container,
386 div.diff-container,
387 div.diffblock{
387 div.diffblock{
388 max-width: 100%;
388 max-width: 100%;
389 }
389 }
390
390
391 div.code-body {
391 div.code-body {
392 max-width: 1124px;
392 max-width: 1124px;
393 overflow-x: auto;
393 overflow-x: auto;
394 overflow-y: hidden;
394 overflow-y: hidden;
395 padding: 0;
395 padding: 0;
396 }
396 }
397 div.diffblock {
397 div.diffblock {
398 border: none;
398 border: none;
399 }
399 }
400
400
401 &.inline-form {
401 &.inline-form {
402 width: 99%
402 width: 99%
403 }
403 }
404 }
404 }
405
405
406
406
407 table.code-difftable {
407 table.code-difftable {
408 width: 100%;
408 width: 100%;
409 }
409 }
410
410
411 /** PYGMENTS COLORING **/
411 /** PYGMENTS COLORING **/
412 div.codeblock {
412 div.codeblock {
413
413
414 // TODO: johbo: Added interim to get rid of the margin around
414 // TODO: johbo: Added interim to get rid of the margin around
415 // Select2 widgets. This needs further cleanup.
415 // Select2 widgets. This needs further cleanup.
416 margin-top: @padding;
416 margin-top: @padding;
417
417
418 overflow: auto;
418 overflow: auto;
419 padding: 0px;
419 padding: 0px;
420 border: @border-thickness solid @grey5;
420 border: @border-thickness solid @grey5;
421 background: @grey6;
421 background: @grey6;
422 .border-radius(@border-radius);
422 .border-radius(@border-radius);
423
423
424 #remove_gist {
424 #remove_gist {
425 float: right;
425 float: right;
426 }
426 }
427
427
428 .author {
428 .author {
429 clear: both;
429 clear: both;
430 vertical-align: middle;
430 vertical-align: middle;
431 font-family: @text-bold;
431 font-family: @text-bold;
432 }
432 }
433
433
434 .btn-mini {
434 .btn-mini {
435 float: left;
435 float: left;
436 margin: 0 5px 0 0;
436 margin: 0 5px 0 0;
437 }
437 }
438
438
439 .code-header {
439 .code-header {
440 padding: @padding;
440 padding: @padding;
441 border-bottom: @border-thickness solid @grey5;
441 border-bottom: @border-thickness solid @grey5;
442
442
443 .rc-user {
443 .rc-user {
444 min-width: 0;
444 min-width: 0;
445 margin-right: .5em;
445 margin-right: .5em;
446 }
446 }
447
447
448 .stats {
448 .stats {
449 clear: both;
449 clear: both;
450 margin: 0 0 @padding 0;
450 margin: 0 0 @padding 0;
451 padding: 0;
451 padding: 0;
452 .left {
452 .left {
453 float: left;
453 float: left;
454 clear: left;
454 clear: left;
455 max-width: 75%;
455 max-width: 75%;
456 margin: 0 0 @padding 0;
456 margin: 0 0 @padding 0;
457
457
458 &.item {
458 &.item {
459 margin-right: @padding;
459 margin-right: @padding;
460 &.last { border-right: none; }
460 &.last { border-right: none; }
461 }
461 }
462 }
462 }
463 .buttons { float: right; }
463 .buttons { float: right; }
464 .author {
464 .author {
465 height: 25px; margin-left: 15px; font-weight: bold;
465 height: 25px; margin-left: 15px; font-weight: bold;
466 }
466 }
467 }
467 }
468
468
469 .commit {
469 .commit {
470 margin: 5px 0 0 26px;
470 margin: 5px 0 0 26px;
471 font-weight: normal;
471 font-weight: normal;
472 white-space: pre-wrap;
472 white-space: pre-wrap;
473 }
473 }
474 }
474 }
475
475
476 .message {
476 .message {
477 position: relative;
477 position: relative;
478 margin: @padding;
478 margin: @padding;
479
479
480 .codeblock-label {
480 .codeblock-label {
481 margin: 0 0 1em 0;
481 margin: 0 0 1em 0;
482 }
482 }
483 }
483 }
484
484
485 .code-body {
485 .code-body {
486 padding: @padding;
486 padding: @padding;
487 background-color: #ffffff;
487 background-color: #ffffff;
488 min-width: 100%;
488 min-width: 100%;
489 box-sizing: border-box;
489 box-sizing: border-box;
490 // TODO: johbo: Parent has overflow: auto, this forces the child here
490 // TODO: johbo: Parent has overflow: auto, this forces the child here
491 // to have the intended size and to scroll. Should be simplified.
491 // to have the intended size and to scroll. Should be simplified.
492 width: 100%;
492 width: 100%;
493 overflow-x: auto;
493 overflow-x: auto;
494 }
494 }
495 }
495 }
496
496
497 .code-highlighttable,
497 .code-highlighttable,
498 div.codeblock {
498 div.codeblock {
499
499
500 &.readme {
500 &.readme {
501 background-color: white;
501 background-color: white;
502 }
502 }
503
503
504 .markdown-block table {
504 .markdown-block table {
505 border-collapse: collapse;
505 border-collapse: collapse;
506
506
507 th,
507 th,
508 td {
508 td {
509 padding: .5em;
509 padding: .5em;
510 border: @border-thickness solid @border-default-color;
510 border: @border-thickness solid @border-default-color;
511 }
511 }
512 }
512 }
513
513
514 table {
514 table {
515 border: 0px;
515 border: 0px;
516 margin: 0;
516 margin: 0;
517 letter-spacing: normal;
517 letter-spacing: normal;
518
518
519
519
520 td {
520 td {
521 border: 0px;
521 border: 0px;
522 vertical-align: top;
522 vertical-align: top;
523 }
523 }
524 }
524 }
525 }
525 }
526
526
527 div.codeblock .code-header .search-path { padding: 0 0 0 10px; }
527 div.codeblock .code-header .search-path { padding: 0 0 0 10px; }
528 div.search-code-body {
528 div.search-code-body {
529 background-color: #ffffff; padding: 5px 0 5px 10px;
529 background-color: #ffffff; padding: 5px 0 5px 10px;
530 pre {
530 pre {
531 .match { background-color: #faffa6;}
531 .match { background-color: #faffa6;}
532 .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; }
532 .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; }
533 }
533 }
534 .code-highlighttable {
534 .code-highlighttable {
535 border-collapse: collapse;
535 border-collapse: collapse;
536
536
537 tr:hover {
537 tr:hover {
538 background: #fafafa;
538 background: #fafafa;
539 }
539 }
540 td.code {
540 td.code {
541 padding-left: 10px;
541 padding-left: 10px;
542 }
542 }
543 td.line {
543 td.line {
544 border-right: 1px solid #ccc !important;
544 border-right: 1px solid #ccc !important;
545 padding-right: 10px;
545 padding-right: 10px;
546 text-align: right;
546 text-align: right;
547 font-family: "Lucida Console",Monaco,monospace;
547 font-family: "Lucida Console",Monaco,monospace;
548 span {
548 span {
549 white-space: pre-wrap;
549 white-space: pre-wrap;
550 color: #666666;
550 color: #666666;
551 }
551 }
552 }
552 }
553 }
553 }
554 }
554 }
555
555
556 div.annotatediv { margin-left: 2px; margin-right: 4px; }
556 div.annotatediv { margin-left: 2px; margin-right: 4px; }
557 .code-highlight {
557 .code-highlight {
558 margin: 0; padding: 0; border-left: @border-thickness solid @grey5;
558 margin: 0; padding: 0; border-left: @border-thickness solid @grey5;
559 pre, .linenodiv pre { padding: 0 5px; margin: 0; }
559 pre, .linenodiv pre { padding: 0 5px; margin: 0; }
560 pre div:target {background-color: @comment-highlight-color !important;}
560 pre div:target {background-color: @comment-highlight-color !important;}
561 }
561 }
562
562
563 .linenos a { text-decoration: none; }
563 .linenos a { text-decoration: none; }
564
564
565 .CodeMirror-selected { background: @rchighlightblue; }
565 .CodeMirror-selected { background: @rchighlightblue; }
566 .CodeMirror-focused .CodeMirror-selected { background: @rchighlightblue; }
566 .CodeMirror-focused .CodeMirror-selected { background: @rchighlightblue; }
567 .CodeMirror ::selection { background: @rchighlightblue; }
567 .CodeMirror ::selection { background: @rchighlightblue; }
568 .CodeMirror ::-moz-selection { background: @rchighlightblue; }
568 .CodeMirror ::-moz-selection { background: @rchighlightblue; }
569
569
570 .code { display: block; border:0px !important; }
570 .code { display: block; border:0px !important; }
571 .code-highlight, /* TODO: dan: merge codehilite into code-highlight */
571 .code-highlight, /* TODO: dan: merge codehilite into code-highlight */
572 .codehilite {
572 .codehilite {
573 .hll { background-color: #ffffcc }
573 .hll { background-color: #ffffcc }
574 .c { color: #408080; font-style: italic } /* Comment */
574 .c { color: #408080; font-style: italic } /* Comment */
575 .err, .codehilite .err { border: @border-thickness solid #FF0000 } /* Error */
575 .err, .codehilite .err { border: @border-thickness solid #FF0000 } /* Error */
576 .k { color: #008000; font-weight: bold } /* Keyword */
576 .k { color: #008000; font-weight: bold } /* Keyword */
577 .o { color: #666666 } /* Operator */
577 .o { color: #666666 } /* Operator */
578 .cm { color: #408080; font-style: italic } /* Comment.Multiline */
578 .cm { color: #408080; font-style: italic } /* Comment.Multiline */
579 .cp { color: #BC7A00 } /* Comment.Preproc */
579 .cp { color: #BC7A00 } /* Comment.Preproc */
580 .c1 { color: #408080; font-style: italic } /* Comment.Single */
580 .c1 { color: #408080; font-style: italic } /* Comment.Single */
581 .cs { color: #408080; font-style: italic } /* Comment.Special */
581 .cs { color: #408080; font-style: italic } /* Comment.Special */
582 .gd { color: #A00000 } /* Generic.Deleted */
582 .gd { color: #A00000 } /* Generic.Deleted */
583 .ge { font-style: italic } /* Generic.Emph */
583 .ge { font-style: italic } /* Generic.Emph */
584 .gr { color: #FF0000 } /* Generic.Error */
584 .gr { color: #FF0000 } /* Generic.Error */
585 .gh { color: #000080; font-weight: bold } /* Generic.Heading */
585 .gh { color: #000080; font-weight: bold } /* Generic.Heading */
586 .gi { color: #00A000 } /* Generic.Inserted */
586 .gi { color: #00A000 } /* Generic.Inserted */
587 .go { color: #808080 } /* Generic.Output */
587 .go { color: #808080 } /* Generic.Output */
588 .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
588 .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
589 .gs { font-weight: bold } /* Generic.Strong */
589 .gs { font-weight: bold } /* Generic.Strong */
590 .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
590 .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
591 .gt { color: #0040D0 } /* Generic.Traceback */
591 .gt { color: #0040D0 } /* Generic.Traceback */
592 .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
592 .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
593 .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
593 .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
594 .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
594 .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
595 .kp { color: #008000 } /* Keyword.Pseudo */
595 .kp { color: #008000 } /* Keyword.Pseudo */
596 .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
596 .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
597 .kt { color: #B00040 } /* Keyword.Type */
597 .kt { color: #B00040 } /* Keyword.Type */
598 .m { color: #666666 } /* Literal.Number */
598 .m { color: #666666 } /* Literal.Number */
599 .s { color: #BA2121 } /* Literal.String */
599 .s { color: #BA2121 } /* Literal.String */
600 .na { color: #7D9029 } /* Name.Attribute */
600 .na { color: #7D9029 } /* Name.Attribute */
601 .nb { color: #008000 } /* Name.Builtin */
601 .nb { color: #008000 } /* Name.Builtin */
602 .nc { color: #0000FF; font-weight: bold } /* Name.Class */
602 .nc { color: #0000FF; font-weight: bold } /* Name.Class */
603 .no { color: #880000 } /* Name.Constant */
603 .no { color: #880000 } /* Name.Constant */
604 .nd { color: #AA22FF } /* Name.Decorator */
604 .nd { color: #AA22FF } /* Name.Decorator */
605 .ni { color: #999999; font-weight: bold } /* Name.Entity */
605 .ni { color: #999999; font-weight: bold } /* Name.Entity */
606 .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
606 .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
607 .nf { color: #0000FF } /* Name.Function */
607 .nf { color: #0000FF } /* Name.Function */
608 .nl { color: #A0A000 } /* Name.Label */
608 .nl { color: #A0A000 } /* Name.Label */
609 .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
609 .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
610 .nt { color: #008000; font-weight: bold } /* Name.Tag */
610 .nt { color: #008000; font-weight: bold } /* Name.Tag */
611 .nv { color: #19177C } /* Name.Variable */
611 .nv { color: #19177C } /* Name.Variable */
612 .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
612 .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
613 .w { color: #bbbbbb } /* Text.Whitespace */
613 .w { color: #bbbbbb } /* Text.Whitespace */
614 .mf { color: #666666 } /* Literal.Number.Float */
614 .mf { color: #666666 } /* Literal.Number.Float */
615 .mh { color: #666666 } /* Literal.Number.Hex */
615 .mh { color: #666666 } /* Literal.Number.Hex */
616 .mi { color: #666666 } /* Literal.Number.Integer */
616 .mi { color: #666666 } /* Literal.Number.Integer */
617 .mo { color: #666666 } /* Literal.Number.Oct */
617 .mo { color: #666666 } /* Literal.Number.Oct */
618 .sb { color: #BA2121 } /* Literal.String.Backtick */
618 .sb { color: #BA2121 } /* Literal.String.Backtick */
619 .sc { color: #BA2121 } /* Literal.String.Char */
619 .sc { color: #BA2121 } /* Literal.String.Char */
620 .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
620 .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
621 .s2 { color: #BA2121 } /* Literal.String.Double */
621 .s2 { color: #BA2121 } /* Literal.String.Double */
622 .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
622 .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
623 .sh { color: #BA2121 } /* Literal.String.Heredoc */
623 .sh { color: #BA2121 } /* Literal.String.Heredoc */
624 .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
624 .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
625 .sx { color: #008000 } /* Literal.String.Other */
625 .sx { color: #008000 } /* Literal.String.Other */
626 .sr { color: #BB6688 } /* Literal.String.Regex */
626 .sr { color: #BB6688 } /* Literal.String.Regex */
627 .s1 { color: #BA2121 } /* Literal.String.Single */
627 .s1 { color: #BA2121 } /* Literal.String.Single */
628 .ss { color: #19177C } /* Literal.String.Symbol */
628 .ss { color: #19177C } /* Literal.String.Symbol */
629 .bp { color: #008000 } /* Name.Builtin.Pseudo */
629 .bp { color: #008000 } /* Name.Builtin.Pseudo */
630 .vc { color: #19177C } /* Name.Variable.Class */
630 .vc { color: #19177C } /* Name.Variable.Class */
631 .vg { color: #19177C } /* Name.Variable.Global */
631 .vg { color: #19177C } /* Name.Variable.Global */
632 .vi { color: #19177C } /* Name.Variable.Instance */
632 .vi { color: #19177C } /* Name.Variable.Instance */
633 .il { color: #666666 } /* Literal.Number.Integer.Long */
633 .il { color: #666666 } /* Literal.Number.Integer.Long */
634 }
634 }
635
635
636 /* customized pre blocks for markdown/rst */
636 /* customized pre blocks for markdown/rst */
637 pre.literal-block, .codehilite pre{
637 pre.literal-block, .codehilite pre{
638 padding: @padding;
638 padding: @padding;
639 border: 1px solid @grey6;
639 border: 1px solid @grey6;
640 .border-radius(@border-radius);
640 .border-radius(@border-radius);
641 background-color: @grey7;
641 background-color: @grey7;
642 }
642 }
643
643
644
644
645 /* START NEW CODE BLOCK CSS */
645 /* START NEW CODE BLOCK CSS */
646
646
647 @cb-line-height: 18px;
647 @cb-line-height: 18px;
648 @cb-line-code-padding: 10px;
648 @cb-line-code-padding: 10px;
649 @cb-text-padding: 5px;
649 @cb-text-padding: 5px;
650
650
651 @pill-padding: 2px 7px;
651 @pill-padding: 2px 7px;
652
652
653 input.filediff-collapse-state {
653 input.filediff-collapse-state {
654 display: none;
654 display: none;
655
655
656 &:checked + .filediff { /* file diff is collapsed */
656 &:checked + .filediff { /* file diff is collapsed */
657 .cb {
657 .cb {
658 display: none
658 display: none
659 }
659 }
660 .filediff-collapse-indicator {
660 .filediff-collapse-indicator {
661 border-width: 9px 0 9px 15.6px;
661 border-width: 9px 0 9px 15.6px;
662 border-color: transparent transparent transparent #ccc;
662 border-color: transparent transparent transparent #ccc;
663 }
663 }
664 .filediff-menu {
664 .filediff-menu {
665 display: none;
665 display: none;
666 }
666 }
667 margin: -1px 0 0 0;
667 margin: -1px 0 0 0;
668 }
668 }
669
669
670 &+ .filediff { /* file diff is expanded */
670 &+ .filediff { /* file diff is expanded */
671 .filediff-collapse-indicator {
671 .filediff-collapse-indicator {
672 border-width: 15.6px 9px 0 9px;
672 border-width: 15.6px 9px 0 9px;
673 border-color: #ccc transparent transparent transparent;
673 border-color: #ccc transparent transparent transparent;
674 }
674 }
675 .filediff-menu {
675 .filediff-menu {
676 display: block;
676 display: block;
677 }
677 }
678 margin: 20px 0;
678 margin: 20px 0;
679 &:nth-child(2) {
679 &:nth-child(2) {
680 margin: 0;
680 margin: 0;
681 }
681 }
682 }
682 }
683 }
683 }
684 .cs_files {
684 .cs_files {
685 clear: both;
685 clear: both;
686 }
686 }
687
687
688 .diffset-menu {
688 .diffset-menu {
689 margin-bottom: 20px;
689 margin-bottom: 20px;
690 }
690 }
691 .diffset {
691 .diffset {
692 margin: 20px auto;
692 margin: 20px auto;
693 .diffset-heading {
693 .diffset-heading {
694 border: 1px solid @grey5;
694 border: 1px solid @grey5;
695 margin-bottom: -1px;
695 margin-bottom: -1px;
696 // margin-top: 20px;
696 // margin-top: 20px;
697 h2 {
697 h2 {
698 margin: 0;
698 margin: 0;
699 line-height: 38px;
699 line-height: 38px;
700 padding-left: 10px;
700 padding-left: 10px;
701 }
701 }
702 .btn {
702 .btn {
703 margin: 0;
703 margin: 0;
704 }
704 }
705 background: @grey6;
705 background: @grey6;
706 display: block;
706 display: block;
707 padding: 5px;
707 padding: 5px;
708 }
708 }
709 .diffset-heading-warning {
709 .diffset-heading-warning {
710 background: @alert3-inner;
710 background: @alert3-inner;
711 border: 1px solid @alert3;
711 border: 1px solid @alert3;
712 }
712 }
713 &.diffset-comments-disabled {
713 &.diffset-comments-disabled {
714 .cb-comment-box-opener, .comment-inline-form, .cb-comment-add-button {
714 .cb-comment-box-opener, .comment-inline-form, .cb-comment-add-button {
715 display: none !important;
715 display: none !important;
716 }
716 }
717 }
717 }
718 }
718 }
719
719
720 .pill {
720 .pill {
721 display: block;
721 display: block;
722 float: left;
722 float: left;
723 padding: @pill-padding;
723 padding: @pill-padding;
724 }
724 }
725 .pill-group {
725 .pill-group {
726 .pill {
726 .pill {
727 opacity: .8;
727 opacity: .8;
728 &:first-child {
728 &:first-child {
729 border-radius: @border-radius 0 0 @border-radius;
729 border-radius: @border-radius 0 0 @border-radius;
730 }
730 }
731 &:last-child {
731 &:last-child {
732 border-radius: 0 @border-radius @border-radius 0;
732 border-radius: 0 @border-radius @border-radius 0;
733 }
733 }
734 &:only-child {
734 &:only-child {
735 border-radius: @border-radius;
735 border-radius: @border-radius;
736 }
736 }
737 }
737 }
738 }
738 }
739
739
740 .filediff {
740 .filediff {
741 border: 1px solid @grey5;
741 border: 1px solid @grey5;
742
742
743 /* START OVERRIDES */
743 /* START OVERRIDES */
744 .code-highlight {
744 .code-highlight {
745 border: none; // TODO: remove this border from the global
745 border: none; // TODO: remove this border from the global
746 // .code-highlight, it doesn't belong there
746 // .code-highlight, it doesn't belong there
747 }
747 }
748 label {
748 label {
749 margin: 0; // TODO: remove this margin definition from global label
749 margin: 0; // TODO: remove this margin definition from global label
750 // it doesn't belong there - if margin on labels
750 // it doesn't belong there - if margin on labels
751 // are needed for a form they should be defined
751 // are needed for a form they should be defined
752 // in the form's class
752 // in the form's class
753 }
753 }
754 /* END OVERRIDES */
754 /* END OVERRIDES */
755
755
756 * {
756 * {
757 box-sizing: border-box;
757 box-sizing: border-box;
758 }
758 }
759 .filediff-anchor {
759 .filediff-anchor {
760 visibility: hidden;
760 visibility: hidden;
761 }
761 }
762 &:hover {
762 &:hover {
763 .filediff-anchor {
763 .filediff-anchor {
764 visibility: visible;
764 visibility: visible;
765 }
765 }
766 }
766 }
767
767
768 .filediff-collapse-indicator {
768 .filediff-collapse-indicator {
769 width: 0;
769 width: 0;
770 height: 0;
770 height: 0;
771 border-style: solid;
771 border-style: solid;
772 float: left;
772 float: left;
773 margin: 2px 2px 0 0;
773 margin: 2px 2px 0 0;
774 cursor: pointer;
774 cursor: pointer;
775 }
775 }
776
776
777 .filediff-heading {
777 .filediff-heading {
778 background: @grey7;
778 background: @grey7;
779 cursor: pointer;
779 cursor: pointer;
780 display: block;
780 display: block;
781 padding: 5px 10px;
781 padding: 5px 10px;
782 }
782 }
783 .filediff-heading:after {
783 .filediff-heading:after {
784 content: "";
784 content: "";
785 display: table;
785 display: table;
786 clear: both;
786 clear: both;
787 }
787 }
788 .filediff-heading:hover {
788 .filediff-heading:hover {
789 background: #e1e9f4 !important;
789 background: #e1e9f4 !important;
790 }
790 }
791
791
792 .filediff-menu {
792 .filediff-menu {
793 float: right;
793 float: right;
794
794
795 &> a, &> span {
795 &> a, &> span {
796 padding: 5px;
796 padding: 5px;
797 display: block;
797 display: block;
798 float: left
798 float: left
799 }
799 }
800 }
800 }
801
801
802 .pill {
802 .pill {
803 &[op="name"] {
803 &[op="name"] {
804 background: none;
804 background: none;
805 color: @grey2;
805 color: @grey2;
806 opacity: 1;
806 opacity: 1;
807 color: white;
807 color: white;
808 }
808 }
809 &[op="limited"] {
809 &[op="limited"] {
810 background: @grey2;
810 background: @grey2;
811 color: white;
811 color: white;
812 }
812 }
813 &[op="binary"] {
813 &[op="binary"] {
814 background: @color7;
814 background: @color7;
815 color: white;
815 color: white;
816 }
816 }
817 &[op="modified"] {
817 &[op="modified"] {
818 background: @alert1;
818 background: @alert1;
819 color: white;
819 color: white;
820 }
820 }
821 &[op="renamed"] {
821 &[op="renamed"] {
822 background: @color4;
822 background: @color4;
823 color: white;
823 color: white;
824 }
824 }
825 &[op="mode"] {
825 &[op="mode"] {
826 background: @grey3;
826 background: @grey3;
827 color: white;
827 color: white;
828 }
828 }
829 &[op="symlink"] {
829 &[op="symlink"] {
830 background: @color8;
830 background: @color8;
831 color: white;
831 color: white;
832 }
832 }
833
833
834 &[op="added"] { /* added lines */
834 &[op="added"] { /* added lines */
835 background: @alert1;
835 background: @alert1;
836 color: white;
836 color: white;
837 }
837 }
838 &[op="deleted"] { /* deleted lines */
838 &[op="deleted"] { /* deleted lines */
839 background: @alert2;
839 background: @alert2;
840 color: white;
840 color: white;
841 }
841 }
842
842
843 &[op="created"] { /* created file */
843 &[op="created"] { /* created file */
844 background: @alert1;
844 background: @alert1;
845 color: white;
845 color: white;
846 }
846 }
847 &[op="removed"] { /* deleted file */
847 &[op="removed"] { /* deleted file */
848 background: @color5;
848 background: @color5;
849 color: white;
849 color: white;
850 }
850 }
851 }
851 }
852
852
853 .filediff-collapse-button, .filediff-expand-button {
853 .filediff-collapse-button, .filediff-expand-button {
854 cursor: pointer;
854 cursor: pointer;
855 }
855 }
856 .filediff-collapse-button {
856 .filediff-collapse-button {
857 display: inline;
857 display: inline;
858 }
858 }
859 .filediff-expand-button {
859 .filediff-expand-button {
860 display: none;
860 display: none;
861 }
861 }
862 .filediff-collapsed .filediff-collapse-button {
862 .filediff-collapsed .filediff-collapse-button {
863 display: none;
863 display: none;
864 }
864 }
865 .filediff-collapsed .filediff-expand-button {
865 .filediff-collapsed .filediff-expand-button {
866 display: inline;
866 display: inline;
867 }
867 }
868
868
869 @comment-padding: 5px;
869 @comment-padding: 5px;
870
870
871 /**** COMMENTS ****/
871 /**** COMMENTS ****/
872
872
873 .filediff-menu {
873 .filediff-menu {
874 .show-comment-button {
874 .show-comment-button {
875 display: none;
875 display: none;
876 }
876 }
877 }
877 }
878 &.hide-comments {
878 &.hide-comments {
879 .inline-comments {
879 .inline-comments {
880 display: none;
880 display: none;
881 }
881 }
882 .filediff-menu {
882 .filediff-menu {
883 .show-comment-button {
883 .show-comment-button {
884 display: inline;
884 display: inline;
885 }
885 }
886 .hide-comment-button {
886 .hide-comment-button {
887 display: none;
887 display: none;
888 }
888 }
889 }
889 }
890 }
890 }
891
891
892 .hide-line-comments {
892 .hide-line-comments {
893 .inline-comments {
893 .inline-comments {
894 display: none;
894 display: none;
895 }
895 }
896 }
896 }
897 .inline-comments {
897 .inline-comments {
898 border-radius: @border-radius;
898 border-radius: @border-radius;
899 background: @grey6;
899 background: @grey6;
900 .comment {
900 .comment {
901 margin: 0;
901 margin: 0;
902 border-radius: @border-radius;
902 border-radius: @border-radius;
903 }
903 }
904 .comment-outdated {
904 .comment-outdated {
905 opacity: 0.5;
905 opacity: 0.5;
906 }
906 }
907 .comment-inline {
907 .comment-inline {
908 background: white;
908 background: white;
909 padding: (@comment-padding + 3px) @comment-padding;
909 padding: (@comment-padding + 3px) @comment-padding;
910 border: @comment-padding solid @grey6;
910 border: @comment-padding solid @grey6;
911
911
912 .text {
912 .text {
913 border: none;
913 border: none;
914 }
914 }
915 .meta {
915 .meta {
916 border-bottom: 1px solid @grey6;
916 border-bottom: 1px solid @grey6;
917 padding-bottom: 10px;
917 padding-bottom: 10px;
918 }
918 }
919 }
919 }
920 .comment-selected {
920 .comment-selected {
921 border-left: 6px solid @comment-highlight-color;
921 border-left: 6px solid @comment-highlight-color;
922 }
922 }
923 .comment-inline-form {
923 .comment-inline-form {
924 padding: @comment-padding;
924 padding: @comment-padding;
925 display: none;
925 display: none;
926 }
926 }
927 .cb-comment-add-button {
927 .cb-comment-add-button {
928 margin: @comment-padding;
928 margin: @comment-padding;
929 }
929 }
930 /* hide add comment button when form is open */
930 /* hide add comment button when form is open */
931 .comment-inline-form-open + .cb-comment-add-button {
931 .comment-inline-form-open + .cb-comment-add-button {
932 display: none;
932 display: none;
933 }
933 }
934 .comment-inline-form-open {
934 .comment-inline-form-open {
935 display: block;
935 display: block;
936 }
936 }
937 /* hide add comment button when form but no comments */
937 /* hide add comment button when form but no comments */
938 .comment-inline-form:first-child + .cb-comment-add-button {
938 .comment-inline-form:first-child + .cb-comment-add-button {
939 display: none;
939 display: none;
940 }
940 }
941 /* hide add comment button when no comments or form */
941 /* hide add comment button when no comments or form */
942 .cb-comment-add-button:first-child {
942 .cb-comment-add-button:first-child {
943 display: none;
943 display: none;
944 }
944 }
945 /* hide add comment button when only comment is being deleted */
945 /* hide add comment button when only comment is being deleted */
946 .comment-deleting:first-child + .cb-comment-add-button {
946 .comment-deleting:first-child + .cb-comment-add-button {
947 display: none;
947 display: none;
948 }
948 }
949 }
949 }
950 /**** END COMMENTS ****/
950 /**** END COMMENTS ****/
951
951
952 }
952 }
953
953
954
954
955 table.cb {
955 table.cb {
956 width: 100%;
956 width: 100%;
957 border-collapse: collapse;
957 border-collapse: collapse;
958
958
959 .cb-text {
959 .cb-text {
960 padding: @cb-text-padding;
960 padding: @cb-text-padding;
961 }
961 }
962 .cb-hunk {
962 .cb-hunk {
963 padding: @cb-text-padding;
963 padding: @cb-text-padding;
964 }
964 }
965 .cb-expand {
965 .cb-expand {
966 display: none;
966 display: none;
967 }
967 }
968 .cb-collapse {
968 .cb-collapse {
969 display: inline;
969 display: inline;
970 }
970 }
971 &.cb-collapsed {
971 &.cb-collapsed {
972 .cb-line {
972 .cb-line {
973 display: none;
973 display: none;
974 }
974 }
975 .cb-expand {
975 .cb-expand {
976 display: inline;
976 display: inline;
977 }
977 }
978 .cb-collapse {
978 .cb-collapse {
979 display: none;
979 display: none;
980 }
980 }
981 }
981 }
982
982
983 /* intentionally general selector since .cb-line-selected must override it
983 /* intentionally general selector since .cb-line-selected must override it
984 and they both use !important since the td itself may have a random color
984 and they both use !important since the td itself may have a random color
985 generated by annotation blocks. TLDR: if you change it, make sure
985 generated by annotation blocks. TLDR: if you change it, make sure
986 annotated block selection and line selection in file view still work */
986 annotated block selection and line selection in file view still work */
987 .cb-line-fresh .cb-content {
987 .cb-line-fresh .cb-content {
988 background: white !important;
988 background: white !important;
989 }
989 }
990 .cb-warning {
990 .cb-warning {
991 background: #fff4dd;
991 background: #fff4dd;
992 }
992 }
993
993
994 &.cb-diff-sideside {
994 &.cb-diff-sideside {
995 td {
995 td {
996 &.cb-content {
996 &.cb-content {
997 width: 50%;
997 width: 50%;
998 }
998 }
999 }
999 }
1000 }
1000 }
1001
1001
1002 tr {
1002 tr {
1003 &.cb-annotate {
1003 &.cb-annotate {
1004 border-top: 1px solid #eee;
1004 border-top: 1px solid #eee;
1005
1005
1006 &+ .cb-line {
1006 &+ .cb-line {
1007 border-top: 1px solid #eee;
1007 border-top: 1px solid #eee;
1008 }
1008 }
1009
1009
1010 &:first-child {
1010 &:first-child {
1011 border-top: none;
1011 border-top: none;
1012 &+ .cb-line {
1012 &+ .cb-line {
1013 border-top: none;
1013 border-top: none;
1014 }
1014 }
1015 }
1015 }
1016 }
1016 }
1017
1017
1018 &.cb-hunk {
1018 &.cb-hunk {
1019 font-family: @font-family-monospace;
1019 font-family: @font-family-monospace;
1020 color: rgba(0, 0, 0, 0.3);
1020 color: rgba(0, 0, 0, 0.3);
1021
1021
1022 td {
1022 td {
1023 &:first-child {
1023 &:first-child {
1024 background: #edf2f9;
1024 background: #edf2f9;
1025 }
1025 }
1026 &:last-child {
1026 &:last-child {
1027 background: #f4f7fb;
1027 background: #f4f7fb;
1028 }
1028 }
1029 }
1029 }
1030 }
1030 }
1031 }
1031 }
1032
1032
1033
1033
1034 td {
1034 td {
1035 vertical-align: top;
1035 vertical-align: top;
1036 padding: 0;
1036 padding: 0;
1037
1037
1038 &.cb-content {
1038 &.cb-content {
1039 font-size: 12.35px;
1039 font-size: 12.35px;
1040
1040
1041 &.cb-line-selected .cb-code {
1041 &.cb-line-selected .cb-code {
1042 background: @comment-highlight-color !important;
1042 background: @comment-highlight-color !important;
1043 }
1043 }
1044
1044
1045 span.cb-code {
1045 span.cb-code {
1046 line-height: @cb-line-height;
1046 line-height: @cb-line-height;
1047 padding-left: @cb-line-code-padding;
1047 padding-left: @cb-line-code-padding;
1048 padding-right: @cb-line-code-padding;
1048 padding-right: @cb-line-code-padding;
1049 display: block;
1049 display: block;
1050 white-space: pre-wrap;
1050 white-space: pre-wrap;
1051 font-family: @font-family-monospace;
1051 font-family: @font-family-monospace;
1052 word-break: break-word;
1052 word-break: break-word;
1053 .nonl {
1053 .nonl {
1054 color: @color5;
1054 color: @color5;
1055 }
1055 }
1056 }
1056 }
1057
1057
1058 &> button.cb-comment-box-opener {
1058 &> button.cb-comment-box-opener {
1059 padding: 2px 6px 2px 6px;
1059
1060 margin-left: -20px;
1060 padding: 2px 5px 1px 5px;
1061 margin-top: -2px;
1061 margin-left: 0px;
1062 margin-top: -1px;
1063
1062 border-radius: @border-radius;
1064 border-radius: @border-radius;
1063 position: absolute;
1065 position: absolute;
1064 display: none;
1066 display: none;
1065 }
1067 }
1066 .cb-comment {
1068 .cb-comment {
1067 margin-top: 10px;
1069 margin-top: 10px;
1068 white-space: normal;
1070 white-space: normal;
1069 }
1071 }
1070 }
1072 }
1071 &:hover {
1073 &:hover {
1072 button.cb-comment-box-opener {
1074 button.cb-comment-box-opener {
1073 display: block;
1075 display: block;
1074 }
1076 }
1075 &+ td button.cb-comment-box-opener {
1077 &+ td button.cb-comment-box-opener {
1076 display: block
1078 display: block
1077 }
1079 }
1078 }
1080 }
1079
1081
1080 &.cb-data {
1082 &.cb-data {
1081 text-align: right;
1083 text-align: right;
1082 width: 30px;
1084 width: 30px;
1083 font-family: @font-family-monospace;
1085 font-family: @font-family-monospace;
1084
1086
1085 .icon-comment {
1087 .icon-comment {
1086 cursor: pointer;
1088 cursor: pointer;
1087 }
1089 }
1088 &.cb-line-selected > div {
1090 &.cb-line-selected > div {
1089 display: block;
1091 display: block;
1090 background: @comment-highlight-color !important;
1092 background: @comment-highlight-color !important;
1091 line-height: @cb-line-height;
1093 line-height: @cb-line-height;
1092 color: rgba(0, 0, 0, 0.3);
1094 color: rgba(0, 0, 0, 0.3);
1093 }
1095 }
1094 }
1096 }
1095
1097
1096 &.cb-lineno {
1098 &.cb-lineno {
1097 padding: 0;
1099 padding: 0;
1098 width: 50px;
1100 width: 50px;
1099 color: rgba(0, 0, 0, 0.3);
1101 color: rgba(0, 0, 0, 0.3);
1100 text-align: right;
1102 text-align: right;
1101 border-right: 1px solid #eee;
1103 border-right: 1px solid #eee;
1102 font-family: @font-family-monospace;
1104 font-family: @font-family-monospace;
1103
1105
1104 a::before {
1106 a::before {
1105 content: attr(data-line-no);
1107 content: attr(data-line-no);
1106 }
1108 }
1107 &.cb-line-selected a {
1109 &.cb-line-selected a {
1108 background: @comment-highlight-color !important;
1110 background: @comment-highlight-color !important;
1109 }
1111 }
1110
1112
1111 a {
1113 a {
1112 display: block;
1114 display: block;
1113 padding-right: @cb-line-code-padding;
1115 padding-right: @cb-line-code-padding;
1114 padding-left: @cb-line-code-padding;
1116 padding-left: @cb-line-code-padding;
1115 line-height: @cb-line-height;
1117 line-height: @cb-line-height;
1116 color: rgba(0, 0, 0, 0.3);
1118 color: rgba(0, 0, 0, 0.3);
1117 }
1119 }
1118 }
1120 }
1119
1121
1120 &.cb-empty {
1122 &.cb-empty {
1121 background: @grey7;
1123 background: @grey7;
1122 }
1124 }
1123
1125
1124 ins {
1126 ins {
1125 color: black;
1127 color: black;
1126 background: #a6f3a6;
1128 background: #a6f3a6;
1127 text-decoration: none;
1129 text-decoration: none;
1128 }
1130 }
1129 del {
1131 del {
1130 color: black;
1132 color: black;
1131 background: #f8cbcb;
1133 background: #f8cbcb;
1132 text-decoration: none;
1134 text-decoration: none;
1133 }
1135 }
1134 &.cb-addition {
1136 &.cb-addition {
1135 background: #ecffec;
1137 background: #ecffec;
1136
1138
1137 &.blob-lineno {
1139 &.blob-lineno {
1138 background: #ddffdd;
1140 background: #ddffdd;
1139 }
1141 }
1140 }
1142 }
1141 &.cb-deletion {
1143 &.cb-deletion {
1142 background: #ffecec;
1144 background: #ffecec;
1143
1145
1144 &.blob-lineno {
1146 &.blob-lineno {
1145 background: #ffdddd;
1147 background: #ffdddd;
1146 }
1148 }
1147 }
1149 }
1148
1150
1149 &.cb-annotate-info {
1151 &.cb-annotate-info {
1150 width: 320px;
1152 width: 320px;
1151 min-width: 320px;
1153 min-width: 320px;
1152 max-width: 320px;
1154 max-width: 320px;
1153 padding: 5px 2px;
1155 padding: 5px 2px;
1154 font-size: 13px;
1156 font-size: 13px;
1155
1157
1156 strong.cb-annotate-message {
1158 strong.cb-annotate-message {
1157 padding: 5px 0;
1159 padding: 5px 0;
1158 white-space: pre-line;
1160 white-space: pre-line;
1159 display: inline-block;
1161 display: inline-block;
1160 }
1162 }
1161 .rc-user {
1163 .rc-user {
1162 float: none;
1164 float: none;
1163 padding: 0 6px 0 17px;
1165 padding: 0 6px 0 17px;
1164 min-width: auto;
1166 min-width: auto;
1165 min-height: auto;
1167 min-height: auto;
1166 }
1168 }
1167 }
1169 }
1168
1170
1169 &.cb-annotate-revision {
1171 &.cb-annotate-revision {
1170 cursor: pointer;
1172 cursor: pointer;
1171 text-align: right;
1173 text-align: right;
1172 }
1174 }
1173 }
1175 }
1174 }
1176 }
@@ -1,897 +1,895 b''
1 // # Copyright (C) 2010-2016 RhodeCode GmbH
1 // # Copyright (C) 2010-2016 RhodeCode GmbH
2 // #
2 // #
3 // # This program is free software: you can redistribute it and/or modify
3 // # This program is free software: you can redistribute it and/or modify
4 // # it under the terms of the GNU Affero General Public License, version 3
4 // # it under the terms of the GNU Affero General Public License, version 3
5 // # (only), as published by the Free Software Foundation.
5 // # (only), as published by the Free Software Foundation.
6 // #
6 // #
7 // # This program is distributed in the hope that it will be useful,
7 // # This program is distributed in the hope that it will be useful,
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // # GNU General Public License for more details.
10 // # GNU General Public License for more details.
11 // #
11 // #
12 // # You should have received a copy of the GNU Affero General Public License
12 // # You should have received a copy of the GNU Affero General Public License
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 // #
14 // #
15 // # This program is dual-licensed. If you wish to learn more about the
15 // # This program is dual-licensed. If you wish to learn more about the
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 var firefoxAnchorFix = function() {
19 var firefoxAnchorFix = function() {
20 // hack to make anchor links behave properly on firefox, in our inline
20 // hack to make anchor links behave properly on firefox, in our inline
21 // comments generation when comments are injected firefox is misbehaving
21 // comments generation when comments are injected firefox is misbehaving
22 // when jumping to anchor links
22 // when jumping to anchor links
23 if (location.href.indexOf('#') > -1) {
23 if (location.href.indexOf('#') > -1) {
24 location.href += '';
24 location.href += '';
25 }
25 }
26 };
26 };
27
27
28 // returns a node from given html;
28 // returns a node from given html;
29 var fromHTML = function(html){
29 var fromHTML = function(html){
30 var _html = document.createElement('element');
30 var _html = document.createElement('element');
31 _html.innerHTML = html;
31 _html.innerHTML = html;
32 return _html;
32 return _html;
33 };
33 };
34
34
35 var tableTr = function(cls, body){
35 var tableTr = function(cls, body){
36 var _el = document.createElement('div');
36 var _el = document.createElement('div');
37 var _body = $(body).attr('id');
37 var _body = $(body).attr('id');
38 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
38 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
39 var id = 'comment-tr-{0}'.format(comment_id);
39 var id = 'comment-tr-{0}'.format(comment_id);
40 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
40 var _html = ('<table><tbody><tr id="{0}" class="{1}">'+
41 '<td class="add-comment-line tooltip tooltip" title="Add Comment"><span class="add-comment-content"></span></td>'+
41 '<td class="add-comment-line tooltip tooltip" title="Add Comment"><span class="add-comment-content"></span></td>'+
42 '<td></td>'+
42 '<td></td>'+
43 '<td></td>'+
43 '<td></td>'+
44 '<td></td>'+
44 '<td></td>'+
45 '<td>{2}</td>'+
45 '<td>{2}</td>'+
46 '</tr></tbody></table>').format(id, cls, body);
46 '</tr></tbody></table>').format(id, cls, body);
47 $(_el).html(_html);
47 $(_el).html(_html);
48 return _el.children[0].children[0].children[0];
48 return _el.children[0].children[0].children[0];
49 };
49 };
50
50
51 var removeInlineForm = function(form) {
51 var removeInlineForm = function(form) {
52 form.parentNode.removeChild(form);
52 form.parentNode.removeChild(form);
53 };
53 };
54
54
55 var createInlineForm = function(parent_tr, f_path, line) {
55 var createInlineForm = function(parent_tr, f_path, line) {
56 var tmpl = $('#comment-inline-form-template').html();
56 var tmpl = $('#comment-inline-form-template').html();
57 tmpl = tmpl.format(f_path, line);
57 tmpl = tmpl.format(f_path, line);
58 var form = tableTr('comment-form-inline', tmpl);
58 var form = tableTr('comment-form-inline', tmpl);
59 var form_hide_button = $(form).find('.hide-inline-form');
59 var form_hide_button = $(form).find('.hide-inline-form');
60
60
61 $(form_hide_button).click(function(e) {
61 $(form_hide_button).click(function(e) {
62 $('.inline-comments').removeClass('hide-comment-button');
62 $('.inline-comments').removeClass('hide-comment-button');
63 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
63 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
64 if ($(newtr.nextElementSibling).hasClass('inline-comments-button')) {
64 if ($(newtr.nextElementSibling).hasClass('inline-comments-button')) {
65 $(newtr.nextElementSibling).show();
65 $(newtr.nextElementSibling).show();
66 }
66 }
67 $(newtr).parents('.comment-form-inline').remove();
67 $(newtr).parents('.comment-form-inline').remove();
68 $(parent_tr).removeClass('form-open');
68 $(parent_tr).removeClass('form-open');
69 $(parent_tr).removeClass('hl-comment');
69 $(parent_tr).removeClass('hl-comment');
70 });
70 });
71
71
72 return form;
72 return form;
73 };
73 };
74
74
75 var getLineNo = function(tr) {
75 var getLineNo = function(tr) {
76 var line;
76 var line;
77 // Try to get the id and return "" (empty string) if it doesn't exist
77 // Try to get the id and return "" (empty string) if it doesn't exist
78 var o = ($(tr).find('.lineno.old').attr('id')||"").split('_');
78 var o = ($(tr).find('.lineno.old').attr('id')||"").split('_');
79 var n = ($(tr).find('.lineno.new').attr('id')||"").split('_');
79 var n = ($(tr).find('.lineno.new').attr('id')||"").split('_');
80 if (n.length >= 2) {
80 if (n.length >= 2) {
81 line = n[n.length-1];
81 line = n[n.length-1];
82 } else if (o.length >= 2) {
82 } else if (o.length >= 2) {
83 line = o[o.length-1];
83 line = o[o.length-1];
84 }
84 }
85 return line;
85 return line;
86 };
86 };
87
87
88 /**
88 /**
89 * make a single inline comment and place it inside
89 * make a single inline comment and place it inside
90 */
90 */
91 var renderInlineComment = function(json_data, show_add_button) {
91 var renderInlineComment = function(json_data, show_add_button) {
92 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
92 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
93 try {
93 try {
94 var html = json_data.rendered_text;
94 var html = json_data.rendered_text;
95 var lineno = json_data.line_no;
95 var lineno = json_data.line_no;
96 var target_id = json_data.target_id;
96 var target_id = json_data.target_id;
97 placeInline(target_id, lineno, html, show_add_button);
97 placeInline(target_id, lineno, html, show_add_button);
98 } catch (e) {
98 } catch (e) {
99 console.error(e);
99 console.error(e);
100 }
100 }
101 };
101 };
102
102
103 function bindDeleteCommentButtons() {
103 function bindDeleteCommentButtons() {
104 $('.delete-comment').one('click', function() {
104 $('.delete-comment').one('click', function() {
105 var comment_id = $(this).data("comment-id");
105 var comment_id = $(this).data("comment-id");
106
106
107 if (comment_id){
107 if (comment_id){
108 deleteComment(comment_id);
108 deleteComment(comment_id);
109 }
109 }
110 });
110 });
111 }
111 }
112
112
113 /**
113 /**
114 * Inject inline comment for on given TR this tr should be always an .line
114 * Inject inline comment for on given TR this tr should be always an .line
115 * tr containing the line. Code will detect comment, and always put the comment
115 * tr containing the line. Code will detect comment, and always put the comment
116 * block at the very bottom
116 * block at the very bottom
117 */
117 */
118 var injectInlineForm = function(tr){
118 var injectInlineForm = function(tr){
119 if (!$(tr).hasClass('line')) {
119 if (!$(tr).hasClass('line')) {
120 return;
120 return;
121 }
121 }
122
122
123 var _td = $(tr).find('.code').get(0);
123 var _td = $(tr).find('.code').get(0);
124 if ($(tr).hasClass('form-open') ||
124 if ($(tr).hasClass('form-open') ||
125 $(tr).hasClass('context') ||
125 $(tr).hasClass('context') ||
126 $(_td).hasClass('no-comment')) {
126 $(_td).hasClass('no-comment')) {
127 return;
127 return;
128 }
128 }
129 $(tr).addClass('form-open');
129 $(tr).addClass('form-open');
130 $(tr).addClass('hl-comment');
130 $(tr).addClass('hl-comment');
131 var node = $(tr.parentNode.parentNode.parentNode).find('.full_f_path').get(0);
131 var node = $(tr.parentNode.parentNode.parentNode).find('.full_f_path').get(0);
132 var f_path = $(node).attr('path');
132 var f_path = $(node).attr('path');
133 var lineno = getLineNo(tr);
133 var lineno = getLineNo(tr);
134 var form = createInlineForm(tr, f_path, lineno);
134 var form = createInlineForm(tr, f_path, lineno);
135
135
136 var parent = tr;
136 var parent = tr;
137 while (1) {
137 while (1) {
138 var n = parent.nextElementSibling;
138 var n = parent.nextElementSibling;
139 // next element are comments !
139 // next element are comments !
140 if ($(n).hasClass('inline-comments')) {
140 if ($(n).hasClass('inline-comments')) {
141 parent = n;
141 parent = n;
142 }
142 }
143 else {
143 else {
144 break;
144 break;
145 }
145 }
146 }
146 }
147 var _parent = $(parent).get(0);
147 var _parent = $(parent).get(0);
148 $(_parent).after(form);
148 $(_parent).after(form);
149 $('.comment-form-inline').prev('.inline-comments').addClass('hide-comment-button');
149 $('.comment-form-inline').prev('.inline-comments').addClass('hide-comment-button');
150 var f = $(form).get(0);
150 var f = $(form).get(0);
151
151
152 var _form = $(f).find('.inline-form').get(0);
152 var _form = $(f).find('.inline-form').get(0);
153
153
154 var pullRequestId = templateContext.pull_request_data.pull_request_id;
154 var pullRequestId = templateContext.pull_request_data.pull_request_id;
155 var commitId = templateContext.commit_data.commit_id;
155 var commitId = templateContext.commit_data.commit_id;
156
156
157 var commentForm = new CommentForm(_form, commitId, pullRequestId, lineno, false);
157 var commentForm = new CommentForm(_form, commitId, pullRequestId, lineno, false);
158 var cm = commentForm.getCmInstance();
158 var cm = commentForm.getCmInstance();
159
159
160 // set a CUSTOM submit handler for inline comments.
160 // set a CUSTOM submit handler for inline comments.
161 commentForm.setHandleFormSubmit(function(o) {
161 commentForm.setHandleFormSubmit(function(o) {
162 var text = commentForm.cm.getValue();
162 var text = commentForm.cm.getValue();
163
163
164 if (text === "") {
164 if (text === "") {
165 return;
165 return;
166 }
166 }
167
167
168 if (lineno === undefined) {
168 if (lineno === undefined) {
169 alert('missing line !');
169 alert('missing line !');
170 return;
170 return;
171 }
171 }
172 if (f_path === undefined) {
172 if (f_path === undefined) {
173 alert('missing file path !');
173 alert('missing file path !');
174 return;
174 return;
175 }
175 }
176
176
177 var excludeCancelBtn = false;
177 var excludeCancelBtn = false;
178 var submitEvent = true;
178 var submitEvent = true;
179 commentForm.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
179 commentForm.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
180 commentForm.cm.setOption("readOnly", true);
180 commentForm.cm.setOption("readOnly", true);
181 var postData = {
181 var postData = {
182 'text': text,
182 'text': text,
183 'f_path': f_path,
183 'f_path': f_path,
184 'line': lineno,
184 'line': lineno,
185 'csrf_token': CSRF_TOKEN
185 'csrf_token': CSRF_TOKEN
186 };
186 };
187 var submitSuccessCallback = function(o) {
187 var submitSuccessCallback = function(o) {
188 $(tr).removeClass('form-open');
188 $(tr).removeClass('form-open');
189 removeInlineForm(f);
189 removeInlineForm(f);
190 renderInlineComment(o);
190 renderInlineComment(o);
191 $('.inline-comments').removeClass('hide-comment-button');
191 $('.inline-comments').removeClass('hide-comment-button');
192
192
193 // re trigger the linkification of next/prev navigation
193 // re trigger the linkification of next/prev navigation
194 linkifyComments($('.inline-comment-injected'));
194 linkifyComments($('.inline-comment-injected'));
195 timeagoActivate();
195 timeagoActivate();
196 bindDeleteCommentButtons();
196 bindDeleteCommentButtons();
197 commentForm.setActionButtonsDisabled(false);
197 commentForm.setActionButtonsDisabled(false);
198
198
199 };
199 };
200 var submitFailCallback = function(){
200 var submitFailCallback = function(){
201 commentForm.resetCommentFormState(text)
201 commentForm.resetCommentFormState(text)
202 };
202 };
203 commentForm.submitAjaxPOST(
203 commentForm.submitAjaxPOST(
204 commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback);
204 commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback);
205 });
205 });
206
206
207 setTimeout(function() {
207 setTimeout(function() {
208 // callbacks
208 // callbacks
209 if (cm !== undefined) {
209 if (cm !== undefined) {
210 cm.focus();
210 cm.focus();
211 }
211 }
212 }, 10);
212 }, 10);
213
213
214 $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({
214 $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({
215 form:_form,
215 form:_form,
216 parent:_parent,
216 parent:_parent,
217 lineno: lineno,
217 lineno: lineno,
218 f_path: f_path}
218 f_path: f_path}
219 );
219 );
220 };
220 };
221
221
222 var deleteComment = function(comment_id) {
222 var deleteComment = function(comment_id) {
223 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
223 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
224 var postData = {
224 var postData = {
225 '_method': 'delete',
225 '_method': 'delete',
226 'csrf_token': CSRF_TOKEN
226 'csrf_token': CSRF_TOKEN
227 };
227 };
228
228
229 var success = function(o) {
229 var success = function(o) {
230 window.location.reload();
230 window.location.reload();
231 };
231 };
232 ajaxPOST(url, postData, success);
232 ajaxPOST(url, postData, success);
233 };
233 };
234
234
235 var createInlineAddButton = function(tr){
235 var createInlineAddButton = function(tr){
236 var label = _gettext('Add another comment');
236 var label = _gettext('Add another comment');
237 var html_el = document.createElement('div');
237 var html_el = document.createElement('div');
238 $(html_el).addClass('add-comment');
238 $(html_el).addClass('add-comment');
239 html_el.innerHTML = '<span class="btn btn-secondary">{0}</span>'.format(label);
239 html_el.innerHTML = '<span class="btn btn-secondary">{0}</span>'.format(label);
240 var add = new $(html_el);
240 var add = new $(html_el);
241 add.on('click', function(e) {
241 add.on('click', function(e) {
242 injectInlineForm(tr);
242 injectInlineForm(tr);
243 });
243 });
244 return add;
244 return add;
245 };
245 };
246
246
247 var placeAddButton = function(target_tr){
247 var placeAddButton = function(target_tr){
248 if(!target_tr){
248 if(!target_tr){
249 return;
249 return;
250 }
250 }
251 var last_node = target_tr;
251 var last_node = target_tr;
252 // scan
252 // scan
253 while (1){
253 while (1){
254 var n = last_node.nextElementSibling;
254 var n = last_node.nextElementSibling;
255 // next element are comments !
255 // next element are comments !
256 if($(n).hasClass('inline-comments')){
256 if($(n).hasClass('inline-comments')){
257 last_node = n;
257 last_node = n;
258 // also remove the comment button from previous
258 // also remove the comment button from previous
259 var comment_add_buttons = $(last_node).find('.add-comment');
259 var comment_add_buttons = $(last_node).find('.add-comment');
260 for(var i=0; i<comment_add_buttons.length; i++){
260 for(var i=0; i<comment_add_buttons.length; i++){
261 var b = comment_add_buttons[i];
261 var b = comment_add_buttons[i];
262 b.parentNode.removeChild(b);
262 b.parentNode.removeChild(b);
263 }
263 }
264 }
264 }
265 else{
265 else{
266 break;
266 break;
267 }
267 }
268 }
268 }
269 var add = createInlineAddButton(target_tr);
269 var add = createInlineAddButton(target_tr);
270 // get the comment div
270 // get the comment div
271 var comment_block = $(last_node).find('.comment')[0];
271 var comment_block = $(last_node).find('.comment')[0];
272 // attach add button
272 // attach add button
273 $(add).insertAfter(comment_block);
273 $(add).insertAfter(comment_block);
274 };
274 };
275
275
276 /**
276 /**
277 * Places the inline comment into the changeset block in proper line position
277 * Places the inline comment into the changeset block in proper line position
278 */
278 */
279 var placeInline = function(target_container, lineno, html, show_add_button) {
279 var placeInline = function(target_container, lineno, html, show_add_button) {
280 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
280 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
281
281
282 var lineid = "{0}_{1}".format(target_container, lineno);
282 var lineid = "{0}_{1}".format(target_container, lineno);
283 var target_line = $('#' + lineid).get(0);
283 var target_line = $('#' + lineid).get(0);
284 var comment = new $(tableTr('inline-comments', html));
284 var comment = new $(tableTr('inline-comments', html));
285 // check if there are comments already !
285 // check if there are comments already !
286 if (target_line) {
286 if (target_line) {
287 var parent_node = target_line.parentNode;
287 var parent_node = target_line.parentNode;
288 var root_parent = parent_node;
288 var root_parent = parent_node;
289
289
290 while (1) {
290 while (1) {
291 var n = parent_node.nextElementSibling;
291 var n = parent_node.nextElementSibling;
292 // next element are comments !
292 // next element are comments !
293 if ($(n).hasClass('inline-comments')) {
293 if ($(n).hasClass('inline-comments')) {
294 parent_node = n;
294 parent_node = n;
295 }
295 }
296 else {
296 else {
297 break;
297 break;
298 }
298 }
299 }
299 }
300 // put in the comment at the bottom
300 // put in the comment at the bottom
301 $(comment).insertAfter(parent_node);
301 $(comment).insertAfter(parent_node);
302 $(comment).find('.comment-inline').addClass('inline-comment-injected');
302 $(comment).find('.comment-inline').addClass('inline-comment-injected');
303 // scan nodes, and attach add button to last one
303 // scan nodes, and attach add button to last one
304 if (show_add_button) {
304 if (show_add_button) {
305 placeAddButton(root_parent);
305 placeAddButton(root_parent);
306 }
306 }
307 addCommentToggle(target_line);
307 addCommentToggle(target_line);
308 }
308 }
309
309
310 return target_line;
310 return target_line;
311 };
311 };
312
312
313 var addCommentToggle = function(target_line) {
313 var addCommentToggle = function(target_line) {
314 // exposes comment toggle button
314 // exposes comment toggle button
315 $(target_line).siblings('.comment-toggle').addClass('active');
315 $(target_line).siblings('.comment-toggle').addClass('active');
316 return;
316 return;
317 };
317 };
318
318
319 var bindToggleButtons = function() {
319 var bindToggleButtons = function() {
320 $('.comment-toggle').on('click', function() {
320 $('.comment-toggle').on('click', function() {
321 $(this).parent().nextUntil('tr.line').toggle('inline-comments');
321 $(this).parent().nextUntil('tr.line').toggle('inline-comments');
322 });
322 });
323 };
323 };
324
324
325 var linkifyComments = function(comments) {
325 var linkifyComments = function(comments) {
326 /* TODO: dan: remove this - it should no longer needed */
326 /* TODO: dan: remove this - it should no longer needed */
327 for (var i = 0; i < comments.length; i++) {
327 for (var i = 0; i < comments.length; i++) {
328 var comment_id = $(comments[i]).data('comment-id');
328 var comment_id = $(comments[i]).data('comment-id');
329 var prev_comment_id = $(comments[i - 1]).data('comment-id');
329 var prev_comment_id = $(comments[i - 1]).data('comment-id');
330 var next_comment_id = $(comments[i + 1]).data('comment-id');
330 var next_comment_id = $(comments[i + 1]).data('comment-id');
331
331
332 // place next/prev links
332 // place next/prev links
333 if (prev_comment_id) {
333 if (prev_comment_id) {
334 $('#prev_c_' + comment_id).show();
334 $('#prev_c_' + comment_id).show();
335 $('#prev_c_' + comment_id + " a.arrow_comment_link").attr(
335 $('#prev_c_' + comment_id + " a.arrow_comment_link").attr(
336 'href', '#comment-' + prev_comment_id).removeClass('disabled');
336 'href', '#comment-' + prev_comment_id).removeClass('disabled');
337 }
337 }
338 if (next_comment_id) {
338 if (next_comment_id) {
339 $('#next_c_' + comment_id).show();
339 $('#next_c_' + comment_id).show();
340 $('#next_c_' + comment_id + " a.arrow_comment_link").attr(
340 $('#next_c_' + comment_id + " a.arrow_comment_link").attr(
341 'href', '#comment-' + next_comment_id).removeClass('disabled');
341 'href', '#comment-' + next_comment_id).removeClass('disabled');
342 }
342 }
343 // place a first link to the total counter
343 // place a first link to the total counter
344 if (i === 0) {
344 if (i === 0) {
345 $('#inline-comments-counter').attr('href', '#comment-' + comment_id);
345 $('#inline-comments-counter').attr('href', '#comment-' + comment_id);
346 }
346 }
347 }
347 }
348
348
349 };
349 };
350
350
351 /**
351 /**
352 * Iterates over all the inlines, and places them inside proper blocks of data
352 * Iterates over all the inlines, and places them inside proper blocks of data
353 */
353 */
354 var renderInlineComments = function(file_comments, show_add_button) {
354 var renderInlineComments = function(file_comments, show_add_button) {
355 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
355 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
356
356
357 for (var i = 0; i < file_comments.length; i++) {
357 for (var i = 0; i < file_comments.length; i++) {
358 var box = file_comments[i];
358 var box = file_comments[i];
359
359
360 var target_id = $(box).attr('target_id');
360 var target_id = $(box).attr('target_id');
361
361
362 // actually comments with line numbers
362 // actually comments with line numbers
363 var comments = box.children;
363 var comments = box.children;
364
364
365 for (var j = 0; j < comments.length; j++) {
365 for (var j = 0; j < comments.length; j++) {
366 var data = {
366 var data = {
367 'rendered_text': comments[j].outerHTML,
367 'rendered_text': comments[j].outerHTML,
368 'line_no': $(comments[j]).attr('line'),
368 'line_no': $(comments[j]).attr('line'),
369 'target_id': target_id
369 'target_id': target_id
370 };
370 };
371 renderInlineComment(data, show_add_button);
371 renderInlineComment(data, show_add_button);
372 }
372 }
373 }
373 }
374
374
375 // since order of injection is random, we're now re-iterating
375 // since order of injection is random, we're now re-iterating
376 // from correct order and filling in links
376 // from correct order and filling in links
377 linkifyComments($('.inline-comment-injected'));
377 linkifyComments($('.inline-comment-injected'));
378 bindDeleteCommentButtons();
378 bindDeleteCommentButtons();
379 firefoxAnchorFix();
379 firefoxAnchorFix();
380 };
380 };
381
381
382
382
383 /* Comment form for main and inline comments */
383 /* Comment form for main and inline comments */
384 var CommentForm = (function() {
384 var CommentForm = (function() {
385 "use strict";
385 "use strict";
386
386
387 function CommentForm(formElement, commitId, pullRequestId, lineNo, initAutocompleteActions) {
387 function CommentForm(formElement, commitId, pullRequestId, lineNo, initAutocompleteActions) {
388
388
389 this.withLineNo = function(selector) {
389 this.withLineNo = function(selector) {
390 var lineNo = this.lineNo;
390 var lineNo = this.lineNo;
391 if (lineNo === undefined) {
391 if (lineNo === undefined) {
392 return selector
392 return selector
393 } else {
393 } else {
394 return selector + '_' + lineNo;
394 return selector + '_' + lineNo;
395 }
395 }
396 };
396 };
397
397
398 this.commitId = commitId;
398 this.commitId = commitId;
399 this.pullRequestId = pullRequestId;
399 this.pullRequestId = pullRequestId;
400 this.lineNo = lineNo;
400 this.lineNo = lineNo;
401 this.initAutocompleteActions = initAutocompleteActions;
401 this.initAutocompleteActions = initAutocompleteActions;
402
402
403 this.previewButton = this.withLineNo('#preview-btn');
403 this.previewButton = this.withLineNo('#preview-btn');
404 this.previewContainer = this.withLineNo('#preview-container');
404 this.previewContainer = this.withLineNo('#preview-container');
405
405
406 this.previewBoxSelector = this.withLineNo('#preview-box');
406 this.previewBoxSelector = this.withLineNo('#preview-box');
407
407
408 this.editButton = this.withLineNo('#edit-btn');
408 this.editButton = this.withLineNo('#edit-btn');
409 this.editContainer = this.withLineNo('#edit-container');
409 this.editContainer = this.withLineNo('#edit-container');
410
410
411 this.cancelButton = this.withLineNo('#cancel-btn');
411 this.cancelButton = this.withLineNo('#cancel-btn');
412
412
413 this.statusChange = '#change_status';
413 this.statusChange = '#change_status';
414 this.cmBox = this.withLineNo('#text');
414 this.cmBox = this.withLineNo('#text');
415 this.cm = initCommentBoxCodeMirror(this.cmBox, this.initAutocompleteActions);
415 this.cm = initCommentBoxCodeMirror(this.cmBox, this.initAutocompleteActions);
416
416
417 this.submitForm = formElement;
417 this.submitForm = formElement;
418 this.submitButton = $(this.submitForm).find('input[type="submit"]');
418 this.submitButton = $(this.submitForm).find('input[type="submit"]');
419 this.submitButtonText = this.submitButton.val();
419 this.submitButtonText = this.submitButton.val();
420
420
421 this.previewUrl = pyroutes.url('changeset_comment_preview',
421 this.previewUrl = pyroutes.url('changeset_comment_preview',
422 {'repo_name': templateContext.repo_name});
422 {'repo_name': templateContext.repo_name});
423
423
424 // based on commitId, or pullReuqestId decide where do we submit
424 // based on commitId, or pullReuqestId decide where do we submit
425 // out data
425 // out data
426 if (this.commitId){
426 if (this.commitId){
427 this.submitUrl = pyroutes.url('changeset_comment',
427 this.submitUrl = pyroutes.url('changeset_comment',
428 {'repo_name': templateContext.repo_name,
428 {'repo_name': templateContext.repo_name,
429 'revision': this.commitId});
429 'revision': this.commitId});
430
430
431 } else if (this.pullRequestId) {
431 } else if (this.pullRequestId) {
432 this.submitUrl = pyroutes.url('pullrequest_comment',
432 this.submitUrl = pyroutes.url('pullrequest_comment',
433 {'repo_name': templateContext.repo_name,
433 {'repo_name': templateContext.repo_name,
434 'pull_request_id': this.pullRequestId});
434 'pull_request_id': this.pullRequestId});
435
435
436 } else {
436 } else {
437 throw new Error(
437 throw new Error(
438 'CommentForm requires pullRequestId, or commitId to be specified.')
438 'CommentForm requires pullRequestId, or commitId to be specified.')
439 }
439 }
440
440
441 this.getCmInstance = function(){
441 this.getCmInstance = function(){
442 return this.cm
442 return this.cm
443 };
443 };
444
444
445 var self = this;
445 var self = this;
446
446
447 this.getCommentStatus = function() {
447 this.getCommentStatus = function() {
448 return $(this.submitForm).find(this.statusChange).val();
448 return $(this.submitForm).find(this.statusChange).val();
449 };
449 };
450
450
451 this.isAllowedToSubmit = function() {
451 this.isAllowedToSubmit = function() {
452 return !$(this.submitButton).prop('disabled');
452 return !$(this.submitButton).prop('disabled');
453 };
453 };
454
454
455 this.initStatusChangeSelector = function(){
455 this.initStatusChangeSelector = function(){
456 var formatChangeStatus = function(state, escapeMarkup) {
456 var formatChangeStatus = function(state, escapeMarkup) {
457 var originalOption = state.element;
457 var originalOption = state.element;
458 return '<div class="flag_status ' + $(originalOption).data('status') + ' pull-left"></div>' +
458 return '<div class="flag_status ' + $(originalOption).data('status') + ' pull-left"></div>' +
459 '<span>' + escapeMarkup(state.text) + '</span>';
459 '<span>' + escapeMarkup(state.text) + '</span>';
460 };
460 };
461 var formatResult = function(result, container, query, escapeMarkup) {
461 var formatResult = function(result, container, query, escapeMarkup) {
462 return formatChangeStatus(result, escapeMarkup);
462 return formatChangeStatus(result, escapeMarkup);
463 };
463 };
464
464
465 var formatSelection = function(data, container, escapeMarkup) {
465 var formatSelection = function(data, container, escapeMarkup) {
466 return formatChangeStatus(data, escapeMarkup);
466 return formatChangeStatus(data, escapeMarkup);
467 };
467 };
468
468
469 $(this.submitForm).find(this.statusChange).select2({
469 $(this.submitForm).find(this.statusChange).select2({
470 placeholder: _gettext('Status Review'),
470 placeholder: _gettext('Status Review'),
471 formatResult: formatResult,
471 formatResult: formatResult,
472 formatSelection: formatSelection,
472 formatSelection: formatSelection,
473 containerCssClass: "drop-menu status_box_menu",
473 containerCssClass: "drop-menu status_box_menu",
474 dropdownCssClass: "drop-menu-dropdown",
474 dropdownCssClass: "drop-menu-dropdown",
475 dropdownAutoWidth: true,
475 dropdownAutoWidth: true,
476 minimumResultsForSearch: -1
476 minimumResultsForSearch: -1
477 });
477 });
478 $(this.submitForm).find(this.statusChange).on('change', function() {
478 $(this.submitForm).find(this.statusChange).on('change', function() {
479 var status = self.getCommentStatus();
479 var status = self.getCommentStatus();
480 if (status && !self.lineNo) {
480 if (status && !self.lineNo) {
481 $(self.submitButton).prop('disabled', false);
481 $(self.submitButton).prop('disabled', false);
482 }
482 }
483 //todo, fix this name
483 //todo, fix this name
484 var placeholderText = _gettext('Comment text will be set automatically based on currently selected status ({0}) ...').format(status);
484 var placeholderText = _gettext('Comment text will be set automatically based on currently selected status ({0}) ...').format(status);
485 self.cm.setOption('placeholder', placeholderText);
485 self.cm.setOption('placeholder', placeholderText);
486 })
486 })
487 };
487 };
488
488
489 // reset the comment form into it's original state
489 // reset the comment form into it's original state
490 this.resetCommentFormState = function(content) {
490 this.resetCommentFormState = function(content) {
491 content = content || '';
491 content = content || '';
492
492
493 $(this.editContainer).show();
493 $(this.editContainer).show();
494 $(this.editButton).hide();
494 $(this.editButton).hide();
495
495
496 $(this.previewContainer).hide();
496 $(this.previewContainer).hide();
497 $(this.previewButton).show();
497 $(this.previewButton).show();
498
498
499 this.setActionButtonsDisabled(true);
499 this.setActionButtonsDisabled(true);
500 self.cm.setValue(content);
500 self.cm.setValue(content);
501 self.cm.setOption("readOnly", false);
501 self.cm.setOption("readOnly", false);
502 };
502 };
503
503
504 this.submitAjaxPOST = function(url, postData, successHandler, failHandler) {
504 this.submitAjaxPOST = function(url, postData, successHandler, failHandler) {
505 failHandler = failHandler || function() {};
505 failHandler = failHandler || function() {};
506 var postData = toQueryString(postData);
506 var postData = toQueryString(postData);
507 var request = $.ajax({
507 var request = $.ajax({
508 url: url,
508 url: url,
509 type: 'POST',
509 type: 'POST',
510 data: postData,
510 data: postData,
511 headers: {'X-PARTIAL-XHR': true}
511 headers: {'X-PARTIAL-XHR': true}
512 })
512 })
513 .done(function(data) {
513 .done(function(data) {
514 successHandler(data);
514 successHandler(data);
515 })
515 })
516 .fail(function(data, textStatus, errorThrown){
516 .fail(function(data, textStatus, errorThrown){
517 alert(
517 alert(
518 "Error while submitting comment.\n" +
518 "Error while submitting comment.\n" +
519 "Error code {0} ({1}).".format(data.status, data.statusText));
519 "Error code {0} ({1}).".format(data.status, data.statusText));
520 failHandler()
520 failHandler()
521 });
521 });
522 return request;
522 return request;
523 };
523 };
524
524
525 // overwrite a submitHandler, we need to do it for inline comments
525 // overwrite a submitHandler, we need to do it for inline comments
526 this.setHandleFormSubmit = function(callback) {
526 this.setHandleFormSubmit = function(callback) {
527 this.handleFormSubmit = callback;
527 this.handleFormSubmit = callback;
528 };
528 };
529
529
530 // default handler for for submit for main comments
530 // default handler for for submit for main comments
531 this.handleFormSubmit = function() {
531 this.handleFormSubmit = function() {
532 var text = self.cm.getValue();
532 var text = self.cm.getValue();
533 var status = self.getCommentStatus();
533 var status = self.getCommentStatus();
534
534
535 if (text === "" && !status) {
535 if (text === "" && !status) {
536 return;
536 return;
537 }
537 }
538
538
539 var excludeCancelBtn = false;
539 var excludeCancelBtn = false;
540 var submitEvent = true;
540 var submitEvent = true;
541 self.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
541 self.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
542 self.cm.setOption("readOnly", true);
542 self.cm.setOption("readOnly", true);
543 var postData = {
543 var postData = {
544 'text': text,
544 'text': text,
545 'changeset_status': status,
545 'changeset_status': status,
546 'csrf_token': CSRF_TOKEN
546 'csrf_token': CSRF_TOKEN
547 };
547 };
548
548
549 var submitSuccessCallback = function(o) {
549 var submitSuccessCallback = function(o) {
550 if (status) {
550 if (status) {
551 location.reload(true);
551 location.reload(true);
552 } else {
552 } else {
553 $('#injected_page_comments').append(o.rendered_text);
553 $('#injected_page_comments').append(o.rendered_text);
554 self.resetCommentFormState();
554 self.resetCommentFormState();
555 bindDeleteCommentButtons();
555 bindDeleteCommentButtons();
556 timeagoActivate();
556 timeagoActivate();
557 }
557 }
558 };
558 };
559 var submitFailCallback = function(){
559 var submitFailCallback = function(){
560 self.resetCommentFormState(text)
560 self.resetCommentFormState(text)
561 };
561 };
562 self.submitAjaxPOST(
562 self.submitAjaxPOST(
563 self.submitUrl, postData, submitSuccessCallback, submitFailCallback);
563 self.submitUrl, postData, submitSuccessCallback, submitFailCallback);
564 };
564 };
565
565
566 this.previewSuccessCallback = function(o) {
566 this.previewSuccessCallback = function(o) {
567 $(self.previewBoxSelector).html(o);
567 $(self.previewBoxSelector).html(o);
568 $(self.previewBoxSelector).removeClass('unloaded');
568 $(self.previewBoxSelector).removeClass('unloaded');
569
569
570 // swap buttons
570 // swap buttons
571 $(self.previewButton).hide();
571 $(self.previewButton).hide();
572 $(self.editButton).show();
572 $(self.editButton).show();
573
573
574 // unlock buttons
574 // unlock buttons
575 self.setActionButtonsDisabled(false);
575 self.setActionButtonsDisabled(false);
576 };
576 };
577
577
578 this.setActionButtonsDisabled = function(state, excludeCancelBtn, submitEvent) {
578 this.setActionButtonsDisabled = function(state, excludeCancelBtn, submitEvent) {
579 excludeCancelBtn = excludeCancelBtn || false;
579 excludeCancelBtn = excludeCancelBtn || false;
580 submitEvent = submitEvent || false;
580 submitEvent = submitEvent || false;
581
581
582 $(this.editButton).prop('disabled', state);
582 $(this.editButton).prop('disabled', state);
583 $(this.previewButton).prop('disabled', state);
583 $(this.previewButton).prop('disabled', state);
584
584
585 if (!excludeCancelBtn) {
585 if (!excludeCancelBtn) {
586 $(this.cancelButton).prop('disabled', state);
586 $(this.cancelButton).prop('disabled', state);
587 }
587 }
588
588
589 var submitState = state;
589 var submitState = state;
590 if (!submitEvent && this.getCommentStatus() && !this.lineNo) {
590 if (!submitEvent && this.getCommentStatus() && !this.lineNo) {
591 // if the value of commit review status is set, we allow
591 // if the value of commit review status is set, we allow
592 // submit button, but only on Main form, lineNo means inline
592 // submit button, but only on Main form, lineNo means inline
593 submitState = false
593 submitState = false
594 }
594 }
595 $(this.submitButton).prop('disabled', submitState);
595 $(this.submitButton).prop('disabled', submitState);
596 if (submitEvent) {
596 if (submitEvent) {
597 $(this.submitButton).val(_gettext('Submitting...'));
597 $(this.submitButton).val(_gettext('Submitting...'));
598 } else {
598 } else {
599 $(this.submitButton).val(this.submitButtonText);
599 $(this.submitButton).val(this.submitButtonText);
600 }
600 }
601
601
602 };
602 };
603
603
604 // lock preview/edit/submit buttons on load, but exclude cancel button
604 // lock preview/edit/submit buttons on load, but exclude cancel button
605 var excludeCancelBtn = true;
605 var excludeCancelBtn = true;
606 this.setActionButtonsDisabled(true, excludeCancelBtn);
606 this.setActionButtonsDisabled(true, excludeCancelBtn);
607
607
608 // anonymous users don't have access to initialized CM instance
608 // anonymous users don't have access to initialized CM instance
609 if (this.cm !== undefined){
609 if (this.cm !== undefined){
610 this.cm.on('change', function(cMirror) {
610 this.cm.on('change', function(cMirror) {
611 if (cMirror.getValue() === "") {
611 if (cMirror.getValue() === "") {
612 self.setActionButtonsDisabled(true, excludeCancelBtn)
612 self.setActionButtonsDisabled(true, excludeCancelBtn)
613 } else {
613 } else {
614 self.setActionButtonsDisabled(false, excludeCancelBtn)
614 self.setActionButtonsDisabled(false, excludeCancelBtn)
615 }
615 }
616 });
616 });
617 }
617 }
618
618
619 $(this.editButton).on('click', function(e) {
619 $(this.editButton).on('click', function(e) {
620 e.preventDefault();
620 e.preventDefault();
621
621
622 $(self.previewButton).show();
622 $(self.previewButton).show();
623 $(self.previewContainer).hide();
623 $(self.previewContainer).hide();
624 $(self.editButton).hide();
624 $(self.editButton).hide();
625 $(self.editContainer).show();
625 $(self.editContainer).show();
626
626
627 });
627 });
628
628
629 $(this.previewButton).on('click', function(e) {
629 $(this.previewButton).on('click', function(e) {
630 e.preventDefault();
630 e.preventDefault();
631 var text = self.cm.getValue();
631 var text = self.cm.getValue();
632
632
633 if (text === "") {
633 if (text === "") {
634 return;
634 return;
635 }
635 }
636
636
637 var postData = {
637 var postData = {
638 'text': text,
638 'text': text,
639 'renderer': DEFAULT_RENDERER,
639 'renderer': DEFAULT_RENDERER,
640 'csrf_token': CSRF_TOKEN
640 'csrf_token': CSRF_TOKEN
641 };
641 };
642
642
643 // lock ALL buttons on preview
643 // lock ALL buttons on preview
644 self.setActionButtonsDisabled(true);
644 self.setActionButtonsDisabled(true);
645
645
646 $(self.previewBoxSelector).addClass('unloaded');
646 $(self.previewBoxSelector).addClass('unloaded');
647 $(self.previewBoxSelector).html(_gettext('Loading ...'));
647 $(self.previewBoxSelector).html(_gettext('Loading ...'));
648 $(self.editContainer).hide();
648 $(self.editContainer).hide();
649 $(self.previewContainer).show();
649 $(self.previewContainer).show();
650
650
651 // by default we reset state of comment preserving the text
651 // by default we reset state of comment preserving the text
652 var previewFailCallback = function(){
652 var previewFailCallback = function(){
653 self.resetCommentFormState(text)
653 self.resetCommentFormState(text)
654 };
654 };
655 self.submitAjaxPOST(
655 self.submitAjaxPOST(
656 self.previewUrl, postData, self.previewSuccessCallback, previewFailCallback);
656 self.previewUrl, postData, self.previewSuccessCallback, previewFailCallback);
657
657
658 });
658 });
659
659
660 $(this.submitForm).submit(function(e) {
660 $(this.submitForm).submit(function(e) {
661 e.preventDefault();
661 e.preventDefault();
662 var allowedToSubmit = self.isAllowedToSubmit();
662 var allowedToSubmit = self.isAllowedToSubmit();
663 if (!allowedToSubmit){
663 if (!allowedToSubmit){
664 return false;
664 return false;
665 }
665 }
666 self.handleFormSubmit();
666 self.handleFormSubmit();
667 });
667 });
668
668
669 }
669 }
670
670
671 return CommentForm;
671 return CommentForm;
672 })();
672 })();
673
673
674 var CommentsController = function() { /* comments controller */
674 var CommentsController = function() { /* comments controller */
675 var self = this;
675 var self = this;
676
676
677 this.cancelComment = function(node) {
677 this.cancelComment = function(node) {
678 var $node = $(node);
678 var $node = $(node);
679 var $td = $node.closest('td');
679 var $td = $node.closest('td');
680 $node.closest('.comment-inline-form').removeClass('comment-inline-form-open');
680 $node.closest('.comment-inline-form').removeClass('comment-inline-form-open');
681 return false;
681 return false;
682 }
682 }
683 this.getLineNumber = function(node) {
683 this.getLineNumber = function(node) {
684 var $node = $(node);
684 var $node = $(node);
685 return $node.closest('td').attr('data-line-number');
685 return $node.closest('td').attr('data-line-number');
686 }
686 }
687 this.scrollToComment = function(node, offset) {
687 this.scrollToComment = function(node, offset) {
688 if (!node) {
688 if (!node) {
689 node = $('.comment-selected');
689 node = $('.comment-selected');
690 if (!node.length) {
690 if (!node.length) {
691 node = $('comment-current')
691 node = $('comment-current')
692 }
692 }
693 }
693 }
694 $comment = $(node).closest('.comment-current');
694 $comment = $(node).closest('.comment-current');
695 $comments = $('.comment-current');
695 $comments = $('.comment-current');
696
696
697 $('.comment-selected').removeClass('comment-selected');
697 $('.comment-selected').removeClass('comment-selected');
698
698
699 var nextIdx = $('.comment-current').index($comment) + offset;
699 var nextIdx = $('.comment-current').index($comment) + offset;
700 if (nextIdx >= $comments.length) {
700 if (nextIdx >= $comments.length) {
701 nextIdx = 0;
701 nextIdx = 0;
702 }
702 }
703 var $next = $('.comment-current').eq(nextIdx);
703 var $next = $('.comment-current').eq(nextIdx);
704 var $cb = $next.closest('.cb');
704 var $cb = $next.closest('.cb');
705 $cb.removeClass('cb-collapsed')
705 $cb.removeClass('cb-collapsed')
706
706
707 var $filediffCollapseState = $cb.closest('.filediff').prev();
707 var $filediffCollapseState = $cb.closest('.filediff').prev();
708 $filediffCollapseState.prop('checked', false);
708 $filediffCollapseState.prop('checked', false);
709 $next.addClass('comment-selected');
709 $next.addClass('comment-selected');
710 scrollToElement($next);
710 scrollToElement($next);
711 return false;
711 return false;
712 }
712 }
713 this.nextComment = function(node) {
713 this.nextComment = function(node) {
714 return self.scrollToComment(node, 1);
714 return self.scrollToComment(node, 1);
715 }
715 }
716 this.prevComment = function(node) {
716 this.prevComment = function(node) {
717 return self.scrollToComment(node, -1);
717 return self.scrollToComment(node, -1);
718 }
718 }
719 this.deleteComment = function(node) {
719 this.deleteComment = function(node) {
720 if (!confirm(_gettext('Delete this comment?'))) {
720 if (!confirm(_gettext('Delete this comment?'))) {
721 return false;
721 return false;
722 }
722 }
723 var $node = $(node);
723 var $node = $(node);
724 var $td = $node.closest('td');
724 var $td = $node.closest('td');
725 var $comment = $node.closest('.comment');
725 var $comment = $node.closest('.comment');
726 var comment_id = $comment.attr('data-comment-id');
726 var comment_id = $comment.attr('data-comment-id');
727 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
727 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
728 var postData = {
728 var postData = {
729 '_method': 'delete',
729 '_method': 'delete',
730 'csrf_token': CSRF_TOKEN
730 'csrf_token': CSRF_TOKEN
731 };
731 };
732
732
733 $comment.addClass('comment-deleting');
733 $comment.addClass('comment-deleting');
734 $comment.hide('fast');
734 $comment.hide('fast');
735
735
736 var success = function(response) {
736 var success = function(response) {
737 $comment.remove();
737 $comment.remove();
738 return false;
738 return false;
739 };
739 };
740 var failure = function(data, textStatus, xhr) {
740 var failure = function(data, textStatus, xhr) {
741 alert("error processing request: " + textStatus);
741 alert("error processing request: " + textStatus);
742 $comment.show('fast');
742 $comment.show('fast');
743 $comment.removeClass('comment-deleting');
743 $comment.removeClass('comment-deleting');
744 return false;
744 return false;
745 };
745 };
746 ajaxPOST(url, postData, success, failure);
746 ajaxPOST(url, postData, success, failure);
747 }
747 }
748 this.toggleComments = function(node, show) {
748 this.toggleComments = function(node, show) {
749 var $filediff = $(node).closest('.filediff');
749 var $filediff = $(node).closest('.filediff');
750 if (show === true) {
750 if (show === true) {
751 $filediff.removeClass('hide-comments');
751 $filediff.removeClass('hide-comments');
752 } else if (show === false) {
752 } else if (show === false) {
753 $filediff.find('.hide-line-comments').removeClass('hide-line-comments');
753 $filediff.find('.hide-line-comments').removeClass('hide-line-comments');
754 $filediff.addClass('hide-comments');
754 $filediff.addClass('hide-comments');
755 } else {
755 } else {
756 $filediff.find('.hide-line-comments').removeClass('hide-line-comments');
756 $filediff.find('.hide-line-comments').removeClass('hide-line-comments');
757 $filediff.toggleClass('hide-comments');
757 $filediff.toggleClass('hide-comments');
758 }
758 }
759 return false;
759 return false;
760 }
760 }
761 this.toggleLineComments = function(node) {
761 this.toggleLineComments = function(node) {
762 self.toggleComments(node, true);
762 self.toggleComments(node, true);
763 var $node = $(node);
763 var $node = $(node);
764 $node.closest('tr').toggleClass('hide-line-comments');
764 $node.closest('tr').toggleClass('hide-line-comments');
765 }
765 }
766 this.createComment = function(node) {
766 this.createComment = function(node) {
767 var $node = $(node);
767 var $node = $(node);
768 var $td = $node.closest('td');
768 var $td = $node.closest('td');
769 var $form = $td.find('.comment-inline-form');
769 var $form = $td.find('.comment-inline-form');
770
770
771 if (!$form.length) {
771 if (!$form.length) {
772 var tmpl = $('#cb-comment-inline-form-template').html();
772 var tmpl = $('#cb-comment-inline-form-template').html();
773 var $filediff = $node.closest('.filediff');
773 var $filediff = $node.closest('.filediff');
774 $filediff.removeClass('hide-comments');
774 $filediff.removeClass('hide-comments');
775 var f_path = $filediff.attr('data-f-path');
775 var f_path = $filediff.attr('data-f-path');
776 var lineno = self.getLineNumber(node);
776 var lineno = self.getLineNumber(node);
777 tmpl = tmpl.format(f_path, lineno);
777 tmpl = tmpl.format(f_path, lineno);
778 $form = $(tmpl);
778 $form = $(tmpl);
779
779
780 var $comments = $td.find('.inline-comments');
780 var $comments = $td.find('.inline-comments');
781 if (!$comments.length) {
781 if (!$comments.length) {
782 $comments = $(
782 $comments = $(
783 $('#cb-comments-inline-container-template').html());
783 $('#cb-comments-inline-container-template').html());
784 $td.append($comments);
784 $td.append($comments);
785 }
785 }
786
786
787 $td.find('.cb-comment-add-button').before($form);
787 $td.find('.cb-comment-add-button').before($form);
788
788
789 var pullRequestId = templateContext.pull_request_data.pull_request_id;
789 var pullRequestId = templateContext.pull_request_data.pull_request_id;
790 var commitId = templateContext.commit_data.commit_id;
790 var commitId = templateContext.commit_data.commit_id;
791 var _form = $form[0];
791 var _form = $form[0];
792 var commentForm = new CommentForm(_form, commitId, pullRequestId, lineno, false);
792 var commentForm = new CommentForm(_form, commitId, pullRequestId, lineno, false);
793 var cm = commentForm.getCmInstance();
793 var cm = commentForm.getCmInstance();
794
794
795 // set a CUSTOM submit handler for inline comments.
795 // set a CUSTOM submit handler for inline comments.
796 commentForm.setHandleFormSubmit(function(o) {
796 commentForm.setHandleFormSubmit(function(o) {
797 var text = commentForm.cm.getValue();
797 var text = commentForm.cm.getValue();
798
798
799 if (text === "") {
799 if (text === "") {
800 return;
800 return;
801 }
801 }
802
802
803 if (lineno === undefined) {
803 if (lineno === undefined) {
804 alert('missing line !');
804 alert('missing line !');
805 return;
805 return;
806 }
806 }
807 if (f_path === undefined) {
807 if (f_path === undefined) {
808 alert('missing file path !');
808 alert('missing file path !');
809 return;
809 return;
810 }
810 }
811
811
812 var excludeCancelBtn = false;
812 var excludeCancelBtn = false;
813 var submitEvent = true;
813 var submitEvent = true;
814 commentForm.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
814 commentForm.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
815 commentForm.cm.setOption("readOnly", true);
815 commentForm.cm.setOption("readOnly", true);
816 var postData = {
816 var postData = {
817 'text': text,
817 'text': text,
818 'f_path': f_path,
818 'f_path': f_path,
819 'line': lineno,
819 'line': lineno,
820 'csrf_token': CSRF_TOKEN
820 'csrf_token': CSRF_TOKEN
821 };
821 };
822 var submitSuccessCallback = function(json_data) {
822 var submitSuccessCallback = function(json_data) {
823 $form.remove();
823 $form.remove();
824 console.log(json_data)
825 try {
824 try {
826 var html = json_data.rendered_text;
825 var html = json_data.rendered_text;
827 var lineno = json_data.line_no;
826 var lineno = json_data.line_no;
828 var target_id = json_data.target_id;
827 var target_id = json_data.target_id;
829
828
830 $comments.find('.cb-comment-add-button').before(html);
829 $comments.find('.cb-comment-add-button').before(html);
831 console.log(lineno, target_id, $comments);
832
830
833 } catch (e) {
831 } catch (e) {
834 console.error(e);
832 console.error(e);
835 }
833 }
836
834
837
835
838 // re trigger the linkification of next/prev navigation
836 // re trigger the linkification of next/prev navigation
839 linkifyComments($('.inline-comment-injected'));
837 linkifyComments($('.inline-comment-injected'));
840 timeagoActivate();
838 timeagoActivate();
841 bindDeleteCommentButtons();
839 bindDeleteCommentButtons();
842 commentForm.setActionButtonsDisabled(false);
840 commentForm.setActionButtonsDisabled(false);
843
841
844 };
842 };
845 var submitFailCallback = function(){
843 var submitFailCallback = function(){
846 commentForm.resetCommentFormState(text)
844 commentForm.resetCommentFormState(text)
847 };
845 };
848 commentForm.submitAjaxPOST(
846 commentForm.submitAjaxPOST(
849 commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback);
847 commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback);
850 });
848 });
851
849
852 setTimeout(function() {
850 setTimeout(function() {
853 // callbacks
851 // callbacks
854 if (cm !== undefined) {
852 if (cm !== undefined) {
855 cm.focus();
853 cm.focus();
856 }
854 }
857 }, 10);
855 }, 10);
858
856
859 $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({
857 $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({
860 form: _form,
858 form: _form,
861 parent: $td[0],
859 parent: $td[0],
862 lineno: lineno,
860 lineno: lineno,
863 f_path: f_path}
861 f_path: f_path}
864 );
862 );
865 }
863 }
866
864
867 $form.addClass('comment-inline-form-open');
865 $form.addClass('comment-inline-form-open');
868 }
866 }
869
867
870 this.renderInlineComments = function(file_comments) {
868 this.renderInlineComments = function(file_comments) {
871 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
869 show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
872
870
873 for (var i = 0; i < file_comments.length; i++) {
871 for (var i = 0; i < file_comments.length; i++) {
874 var box = file_comments[i];
872 var box = file_comments[i];
875
873
876 var target_id = $(box).attr('target_id');
874 var target_id = $(box).attr('target_id');
877
875
878 // actually comments with line numbers
876 // actually comments with line numbers
879 var comments = box.children;
877 var comments = box.children;
880
878
881 for (var j = 0; j < comments.length; j++) {
879 for (var j = 0; j < comments.length; j++) {
882 var data = {
880 var data = {
883 'rendered_text': comments[j].outerHTML,
881 'rendered_text': comments[j].outerHTML,
884 'line_no': $(comments[j]).attr('line'),
882 'line_no': $(comments[j]).attr('line'),
885 'target_id': target_id
883 'target_id': target_id
886 };
884 };
887 }
885 }
888 }
886 }
889
887
890 // since order of injection is random, we're now re-iterating
888 // since order of injection is random, we're now re-iterating
891 // from correct order and filling in links
889 // from correct order and filling in links
892 linkifyComments($('.inline-comment-injected'));
890 linkifyComments($('.inline-comment-injected'));
893 bindDeleteCommentButtons();
891 bindDeleteCommentButtons();
894 firefoxAnchorFix();
892 firefoxAnchorFix();
895 };
893 };
896
894
897 } No newline at end of file
895 }
General Comments 0
You need to be logged in to leave comments. Login now