repo.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. $(document).ready(function()
  2. {
  3. var $bugFormRow = $('<tr class="action-row"><th></th><td class="action-cell"></td></tr>');
  4. var $bugForm = $('#bugForm');
  5. $bugFormRow.find('td').append($bugForm.removeClass('hide'));
  6. var $bugPanel = $('#bugPanel');
  7. var $commentCell = $('#commentCell');
  8. var $pre = $('.repoCode .content pre');
  9. var $bugsPreview = $('#bugsPreview');
  10. var hidePreview;
  11. var $bugsPreviewMenu = $('#bugsPreview').children('.dropdown-menu');
  12. var $rows = $pre.find('tr');
  13. var highlight = function($e)
  14. {
  15. $('.highlight').removeClass('highlight');
  16. $e.addClass('highlight');
  17. };
  18. var createComment = function(comment, $comments)
  19. {
  20. var $comment = $commentCell.clone()
  21. .removeClass('hide')
  22. .attr('id', 'comment-' + comment.id)
  23. .attr('data-comment', comment.id);
  24. $comment.find('.realname').text(comment.realname);
  25. $comment.find('.comment-content').text(comment.comment);
  26. $comment.find('.date').text(comment.date);
  27. $comment.find('.edit').toggle(comment.edit);
  28. $comment.find('.comment-edit-form').attr('action', createLink('repo', 'editComment', 'commentID=' + comment.id));
  29. if(comment.user.avatar)
  30. {
  31. $comment.find('.avatar').removeClass('has-text').addClass('has-img');
  32. $comment.find('.avatar span').remove();
  33. $comment.find('.avatar').html('<img src="' + comment.user.avatar + '"/>');
  34. }
  35. else
  36. {
  37. $comment.find('.avatar').removeClass('has-img').addClass('has-text');
  38. $comment.find('.avatar img').remove();
  39. var name = comment.user.name ? comment.user.name : (comment.user.realname ? comment.user.realname : comment.user.account);
  40. $comment.find('.avatar').html('<span class="text text-len-' + name.replace(/[^\x00-\xff]/g, "00").length + '">' + name + '</span>');
  41. }
  42. if($comments)
  43. {
  44. if(typeof $comments !== 'object') $comments = $('#bug-' + $comments + ' .comments');
  45. ($comments.hasClass('comments') ? $comments : $comments.find('.comments')).append($comment);
  46. }
  47. return $comment;
  48. };
  49. var createBug = function(bug, line, $commentRow, show)
  50. {
  51. var commentCount, j;
  52. var $bug = $bugPanel.clone().removeClass('hide').attr('id', 'bug-' + bug.id).attr('data-bug', bug.id);
  53. $bug.find('.bugid').text(bug.id);
  54. $bug.find('.view-bug').attr('title', bug.title);
  55. $bug.find('.edit').toggle(bug.edit);
  56. $bug.find('.code-lines').text(bug.lines);
  57. $bug.find('.delete').toggle(bug.delete);
  58. $bug.find('input[name="objectID"]').val(bug.id);
  59. $bug.find('a.view-bug').attr('href', createLink('bug', 'view', 'bugID=' + bug.id, '', true));
  60. $bug.find('a.bugEdit').attr('href', createLink('bug', 'edit', 'bugID=' + bug.id, '', true));
  61. $bug.data('data', bug);
  62. $bug.toggleClass('show', show > 1);
  63. if(show > 2) highlight($bug);
  64. if(bug.comments)
  65. {
  66. commentCount = bug.comments.length;
  67. $bugComments = $bug.find('.comments');
  68. for(j = 0; j < commentCount; j++)
  69. {
  70. createComment(bug.comments[j], $bugComments);
  71. }
  72. }
  73. if(!line && bug.line) line = bug.line;
  74. if(line)
  75. {
  76. var $row = $rows.filter('[data-line="' + line + '"]').first();
  77. var bugNum = parseInt($row.find('span .bug-num').text()) + 1;
  78. $row.find('span .bug-num').text(bugNum);
  79. if(!$commentRow)
  80. {
  81. $commentRow = $row.next('tr');
  82. if(!$commentRow.hasClass('comment-row'))
  83. {
  84. $commentRow = $('<tr class="comment-row"><th class="w-num"></th><td class="comment-cell"><div class="comment-list"></div></td></tr>');
  85. $row.after($commentRow);
  86. }
  87. }
  88. $row.addClass('commented');
  89. var bugWidth = 31 + bugNum.toString().length * 7;
  90. var minWidth = parseInt($('.repoCode tr .icon-wrapper').css('min-width'));
  91. if(bugWidth > minWidth) $('.repoCode tr .icon-wrapper').css('min-width', bugWidth + 'px');
  92. var bugThWidth = bugWidth + 22;
  93. minWidth = parseInt($('.repoCode pre > table > tbody tr > th').css('width'));
  94. if(bugThWidth > minWidth) $('.repoCode pre > table > tbody > tr > th').css('width', bugThWidth + 'px');
  95. ($commentRow.hasClass('comment-list') ? $commentRow : $commentRow.find('.comment-list')).append($bug);
  96. if(show && $commentRow.hasClass('comment-row')) $commentRow.addClass('show');
  97. }
  98. $bug.find('.iframe').initIframeModal();
  99. return $bug;
  100. };
  101. var toggleComment = function($row, show)
  102. {
  103. var $commentRow;
  104. if($row.hasClass('comment-row'))
  105. {
  106. $commentRow = $row;
  107. $row = $commentRow.prev('tr');
  108. if($row.hasClass('action-row'))
  109. {
  110. $row = $row.prev('tr');
  111. }
  112. }
  113. else
  114. {
  115. $commentRow = $row.next('tr');
  116. if($commentRow.hasClass('action-row'))
  117. {
  118. $commentRow = $commentRow.next('tr');
  119. }
  120. }
  121. if(show === undefined)
  122. {
  123. show = !$row.hasClass('open');
  124. }
  125. if($row.hasClass('commented') && $commentRow.hasClass('comment-row'))
  126. {
  127. $commentRow.toggleClass('show', show);
  128. $row.toggleClass('open', show);
  129. }
  130. };
  131. $rows.hover(function()
  132. {
  133. $(this).addClass("over");
  134. $(this).find(".icon-wrapper .icon-bug").addClass('icon-chat').removeClass('icon-bug');
  135. $(this).find(".label-badge").hide();
  136. $(this).find('.row-tip .icon-chat').hide();
  137. },
  138. function()
  139. {
  140. $(this).removeClass("over");
  141. $(this).find(".icon-wrapper .icon-chat").addClass('icon-bug').removeClass('icon-chat');
  142. $(this).find(".label-badge").show();
  143. });
  144. $pre.on('click', '.comment-btn', function(e)
  145. {
  146. $rows.removeClass('selected');
  147. var $row = $(this).closest('tr');
  148. if($pre.hasClass('with-action-row') && $row.hasClass('with-action-row'))
  149. {
  150. $pre.removeClass('with-action-row');
  151. }
  152. else
  153. {
  154. $pre.addClass('with-action-row');
  155. var line = $row.data('line');
  156. if(!$row.hasClass('with-action-row'))
  157. {
  158. $rows.removeClass('with-action-row')
  159. $row.addClass('with-action-row');
  160. $bugForm.find('input[name="begin"]').val(line);
  161. $bugForm.find('input[name="end"]').attr('min', line).val(line);
  162. $bugForm.find('select#assignedTo').val(blamePairs[line]);
  163. $bugForm.find('select#assignedTo').trigger("chosen:updated");
  164. var $nextRow = $row.next('tr');
  165. ($nextRow.hasClass('comment-row') ? $nextRow : $row).after($bugFormRow);
  166. var getCommiterLink = createLink('repo', 'ajaxgetcommitter', 'repoID=' + repoID + "&entry=&revision=" + revision + "&line=" + line);
  167. var connector = getCommiterLink.indexOf('&') >= 0 ? '&' : '?';
  168. getCommiterLink = getCommiterLink + connector + 'entry=' + file;
  169. $.ajax({url: getCommiterLink}).done(function(responseText)
  170. {
  171. $bugForm.find('#assignedTo').val(responseText).trigger("chosen:updated");
  172. });
  173. }
  174. $row.addClass('selected');
  175. highlight($bugForm);
  176. $bugForm.find('input[name="title"]').focus();
  177. }
  178. e.stopPropagation();
  179. }).on('click', '.bugEdit,.view-bug', function(e)
  180. {
  181. if(!isonlybody) return false;
  182. }).on('click', '.bugCancel', function()
  183. {
  184. $rows.removeClass('selected');
  185. $pre.removeClass('with-action-row');
  186. }).on('click', '.bugDelete', function(e)
  187. {
  188. var $bug = $(this).closest('.panel-bug');
  189. if(!$bug.length) return;
  190. if(confirm(confirmDelete))
  191. {
  192. var link = createLink('repo', 'deleteBug', 'bugID=' + $bug.data('bug') + '&confirm=yes');
  193. $.get(link, function(data)
  194. {
  195. if(data == 'deleted')
  196. {
  197. var $commentRow = $bug.closest('.comment-row');
  198. var bugNum = parseInt($commentRow.prev('tr').find('.bug-num').text());
  199. $commentRow.prev('tr').find('.bug-num').text(bugNum > 1 ? bugNum -1 : 0);
  200. if($commentRow.find('.panel-bug').length === 1)
  201. {
  202. $commentRow.removeClass('show').prev('tr').removeClass('commented');
  203. }
  204. $bug.remove();
  205. }
  206. });
  207. }
  208. e.stopPropagation();
  209. return false;
  210. }).on('click', '.addComment', function()
  211. {
  212. $(this).closest('.panel-bug').addClass('show-form').find('.commentForm textarea').focus();
  213. }).on('click', '.commentCancel', function()
  214. {
  215. $(this).closest('.panel-bug').removeClass('show-form');
  216. }).on('submit', '.commentForm', function()
  217. {
  218. var $form = $(this);
  219. $form.ajaxSubmit(
  220. {
  221. success:function(json)
  222. {
  223. var $panelBug = $form.closest('.panel-bug');
  224. $form.find('textarea').val('');
  225. $panelBug.removeClass('show-form');
  226. createComment($.parseJSON(json), $panelBug.data('bug'));
  227. },
  228. beforeSubmit:function(formData, jqForm)
  229. {
  230. var form = jqForm[0];
  231. if(!form.comment.value)
  232. {
  233. alert(commentError);
  234. return false;
  235. }
  236. }
  237. });
  238. return false;
  239. }).on('click', '.commentEdit', function()
  240. {
  241. var $comment = $(this).closest('.comment');
  242. if($comment.hasClass('show-form'))
  243. {
  244. $comment.removeClass('show-form');
  245. return;
  246. }
  247. $comment.addClass('show-form').find('textarea').val($comment.find('.comment-content').text()).focus();
  248. }).on('click', '.commentEditCancel', function()
  249. {
  250. $(this).closest('.comment').removeClass('show-form');
  251. }).on('submit', '.comment-edit-form', function()
  252. {
  253. var $form = $(this);
  254. $form.ajaxSubmit(
  255. {
  256. success:function(html)
  257. {
  258. var $comment = $form.closest('.comment');
  259. $comment.find('.comment-content').html(html);
  260. $comment.removeClass('show-form');
  261. },
  262. beforeSubmit:function(formData, jqForm)
  263. {
  264. var form = jqForm[0];
  265. if(!form.commentText.value)
  266. {
  267. alert(contentError);
  268. return false;
  269. }
  270. }
  271. });
  272. return false;
  273. }).on('click', '.commentDelete', function()
  274. {
  275. var $container = $(this).closest('.commentContainer');
  276. if(!$container.length) return;
  277. if(confirm(confirmDeleteComment))
  278. {
  279. var commentID = $container.data('comment');
  280. var link = createLink('repo', 'deleteComment', 'commentID=' + commentID + '&confirm=yes');
  281. $.get(link, function(data)
  282. {
  283. if(data == 'deleted')
  284. {
  285. var $commentRow = $container.closest('.comment-row');
  286. if($commentRow.find('.bugContainer, .commentContainer').length === 1)
  287. {
  288. $commentRow.removeClass('show').prev('tr').removeClass('commented');
  289. }
  290. $container.remove();
  291. }
  292. });
  293. }
  294. return false;
  295. }).on('click', 'tr.commented', function()
  296. {
  297. toggleComment($(this));
  298. }).on('click', '.panel-bug > .panel-heading', function()
  299. {
  300. $(this).closest('.panel-bug').toggleClass('show');
  301. });
  302. $bugForm.submit(function()
  303. {
  304. $(this).ajaxSubmit(
  305. {
  306. success:function(json)
  307. {
  308. json = $.parseJSON(json);
  309. if(json.result == 'fail')
  310. {
  311. alert(json.message);
  312. return false;
  313. }
  314. createBug(json, null, null, 3);
  315. $pre.removeClass('with-action-row');
  316. $pre.find('tr.with-action-row.selected').removeClass('selected');
  317. $bugForm.find('#title').val('');
  318. KindEditor.html('#commentText', '');
  319. },
  320. beforeSubmit:function(formData, jqForm)
  321. {
  322. var form = jqForm[0];
  323. if(!form.product.value)
  324. {
  325. alert(productError);
  326. return false;
  327. }
  328. if(!form.title.value)
  329. {
  330. alert(titleError);
  331. $bugForm.find('input[name="title"]').focus();
  332. return false;
  333. }
  334. }
  335. });
  336. return false;
  337. }).on('change', 'input[name="begin"]', function()
  338. {
  339. var begin = $(this).val();
  340. var $end = $bugForm.find('input[name="end"]').attr('min', begin);
  341. if(parseInt($end.val()) < parseInt(begin)) $end.val(begin);
  342. $bugForm.find('select#assignedTo').val(blamePairs[begin]);
  343. $bugForm.find('select#assignedTo').trigger("chosen:updated");
  344. });
  345. if(bugs)
  346. {
  347. var lineBugs, bugsCount, i;
  348. for(var line in bugs)
  349. {
  350. if(line)
  351. {
  352. lineBugs = bugs[line];
  353. bugsCount = lineBugs.length;
  354. for(i = 0; i < bugsCount; i++)
  355. {
  356. createBug(lineBugs[i], line);
  357. }
  358. }
  359. }
  360. }
  361. setTimeout(anchor, 200);
  362. $(document).on('click', function()
  363. {
  364. $('.highlight').removeClass('highlight');
  365. });
  366. function anchor()
  367. {
  368. var hash = window.location.hash;
  369. if(hash)
  370. {
  371. var $row = $(hash).closest('tr');
  372. if($row.length)
  373. {
  374. var anchor = $row.offset().top;
  375. $('body,html').animate({scrollTop:anchor - 50}, 500);
  376. $row.addClass('highlight');
  377. if($row.hasClass('commented'))
  378. {
  379. var $commentRow = $row.next('tr');
  380. if($commentRow.hasClass('comment-row'))
  381. {
  382. toggleComment($row, true);
  383. $commentRow.addClass('highlight').find('.panel-bug').first().addClass('show');
  384. }
  385. }
  386. }
  387. }
  388. }
  389. });