repo.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. var $bugForm = $('#bugForm');
  2. $(document).ready(function()
  3. {
  4. var $bugFormRow = $('<div class="action-row with-action-row"><div class="action-cell"></div></div>');
  5. $bugFormRow.find('.action-cell').append($bugForm);
  6. var $bugPanel = $('#bugPanel');
  7. var $monacoEditor = $('.repoCode .content .monaco-scrollable-element');
  8. var $bugsPreview = $('#bugsPreview');
  9. var hidePreview;
  10. var $bugsPreviewMenu = $('#bugsPreview').children('.dropdown-menu');
  11. var $rows = $monacoEditor.find('.content-line');
  12. var highlight = function($e)
  13. {
  14. $('.highlight').removeClass('highlight');
  15. $e.addClass('highlight');
  16. };
  17. var createBug = function(bug, line, $commentRow, show)
  18. {
  19. /* Add bug info to bugs. */
  20. var newBug = {
  21. id: bug.id,
  22. line: bug.line,
  23. title: bug.title
  24. };
  25. if(!bugs[bug.line]) bugs[bug.line] = [];
  26. bugs[bug.line].push(newBug);
  27. var commentCount, j;
  28. var $bug = $bugPanel.clone().removeClass('hide').attr('id', 'bug-' + bug.id).attr('data-bug', bug.id);
  29. $bug.find('.bugid').text(bug.id);
  30. $bug.find('.view-bug').attr('title', bug.title);
  31. $bug.find('.edit').toggle(bug.edit);
  32. $bug.find('.code-lines').text(bug.lines);
  33. $bug.find('.delete').toggle(bug.delete);
  34. $bug.find('input[name="objectID"]').val(bug.id);
  35. $bug.find('a.view-bug').attr('href', createLink('bug', 'view', 'bugID=' + bug.id + '&from=repo', '', true));
  36. $bug.find('a.bugEdit').attr('href', createLink('bug', 'edit', 'bugID=' + bug.id + '&from=repo', '', true));
  37. $bug.data('data', bug);
  38. $bug.toggleClass('show', show > 1);
  39. if(show > 2) highlight($bug);
  40. if(bug.comments)
  41. {
  42. commentCount = bug.comments.length;
  43. $bugComments = $bug.find('.comments');
  44. for(j = 0; j < commentCount; j++)
  45. {
  46. createComment(bug.comments[j], $bugComments);
  47. }
  48. }
  49. $bug.find('.iframe').initIframeModal();
  50. /* Remove old zone. */
  51. removeBugZone();
  52. /* Add a zone to show bug. */
  53. var overlayDom = document.createElement('div');
  54. var bugLine = parseInt(bug.line);
  55. if(pageType == 'diff') bugLine = jQuery.inArray(bugLine, diffContent.line.new) + 1;
  56. $bug.appendTo($(overlayDom));
  57. bugViewZoneId = addViewZone(overlayDom, bugLine, 125, 'bugLine');
  58. editor.revealLine(bugLine);
  59. return $bug;
  60. };
  61. $(document).on('click', '.bugDelete', function(e)
  62. {
  63. var $bug = $(this).closest('.panel-bug');
  64. if(!$bug.length) return;
  65. if(confirm(confirmDelete))
  66. {
  67. var bugID = $bug.data('bug');
  68. var link = createLink('repo', 'deleteBug', 'bugID=' + bugID + '&confirm=yes');
  69. $.get(link, function(data)
  70. {
  71. if(data == 'deleted')
  72. {
  73. var $commentRow = $bug.closest('.comment-row');
  74. var bugNum = parseInt($commentRow.prev('tr').find('.bug-num').text());
  75. var widgetid = $bug.parent().attr('widgetid');
  76. var line = widgetid.substr(7);
  77. for(var index in bugs[line])
  78. {
  79. if(bugs[line][index].id == bugID)
  80. {
  81. bugs[line].splice(index, 1);
  82. }
  83. };
  84. /* Refesh bug count. */
  85. var $lineNumberDom = pageType == 'diff' ? $('.modified .margin-view-overlays .line-number-' + line) : $('.margin-view-overlays .line-number-' + line);
  86. if(bugs[line].length)
  87. {
  88. $lineNumberDom.find('.bug-view .bug-count').text(bugs[line].length);
  89. $('.repoCode .bug-view').css('width', $lineNumberDom.find('.line-numbers').width() - 5);
  90. }
  91. else
  92. {
  93. delete bugs[line]
  94. $lineNumberDom.find('.bug-view').remove();
  95. }
  96. $bug.remove();
  97. /* Refesh bug zone. */
  98. removeBugZone();
  99. }
  100. });
  101. }
  102. e.stopPropagation();
  103. return false;
  104. }).on('click', '.addComment', function()
  105. {
  106. $(this).closest('.panel-bug').addClass('show-form').find('.commentForm textarea').focus();
  107. }).on('click', '.commentCancel', function()
  108. {
  109. $(this).closest('.panel-bug').removeClass('show-form');
  110. }).on('submit', '.commentForm', function()
  111. {
  112. var $form = $(this);
  113. $form.ajaxSubmit(
  114. {
  115. success:function(json)
  116. {
  117. var $panelBug = $form.closest('.panel-bug');
  118. $form.find('textarea').val('');
  119. $panelBug.removeClass('show-form');
  120. var comment = $.parseJSON(json);
  121. var widgetid = $(document).find("[widgetid^='bugLine']").attr('widgetid');
  122. var line = parseInt(widgetid.substr(7));
  123. if(pageType == 'diff') line = diffContent.line.new[line - 1];
  124. bugs[line].forEach(function(bug, index)
  125. {
  126. if(bug.id == comment.bugID)
  127. {
  128. if(!bugs[line][index].comments) bugs[line][index].comments = [];
  129. bugs[line][index].comments.push(comment);
  130. }
  131. })
  132. createComment(comment, $panelBug.data('bug'));
  133. },
  134. beforeSubmit:function(formData, jqForm)
  135. {
  136. var form = jqForm[0];
  137. if(!form.comment.value)
  138. {
  139. alert(commentError);
  140. return false;
  141. }
  142. }
  143. });
  144. return false;
  145. }).on('click', '.commentEdit', function()
  146. {
  147. var $comment = $(this).closest('.comment');
  148. if($comment.hasClass('show-form'))
  149. {
  150. $comment.removeClass('show-form');
  151. return;
  152. }
  153. $comment.addClass('show-form').find('textarea').val($comment.find('.comment-content').text()).focus();
  154. }).on('click', '.commentEditCancel', function()
  155. {
  156. $(this).closest('.comment').removeClass('show-form');
  157. }).on('submit', '.comment-edit-form', function()
  158. {
  159. var $form = $(this);
  160. $form.ajaxSubmit(
  161. {
  162. success:function(html)
  163. {
  164. var $comment = $form.closest('.comment');
  165. $comment.find('.comment-content').html(html);
  166. $comment.removeClass('show-form');
  167. },
  168. beforeSubmit:function(formData, jqForm)
  169. {
  170. var form = jqForm[0];
  171. if(!form.commentText.value)
  172. {
  173. alert(contentError);
  174. return false;
  175. }
  176. }
  177. });
  178. return false;
  179. }).on('click', '.commentDelete', function()
  180. {
  181. var $container = $(this).closest('.commentContainer');
  182. if(!$container.length) return;
  183. if(confirm(confirmDeleteComment))
  184. {
  185. var commentID = $container.data('comment');
  186. var link = createLink('repo', 'deleteComment', 'commentID=' + commentID + '&confirm=yes');
  187. $.get(link, function(data)
  188. {
  189. if(data == 'deleted')
  190. {
  191. var $commentRow = $container.closest('.comment-row');
  192. if($commentRow.find('.bugContainer, .commentContainer').length === 1)
  193. {
  194. $commentRow.removeClass('show').prev('tr').removeClass('commented');
  195. }
  196. $container.remove();
  197. }
  198. });
  199. }
  200. return false;
  201. });
  202. $(document).on('submit', '#bugForm', function()
  203. {
  204. $(this).ajaxSubmit(
  205. {
  206. success:function(json)
  207. {
  208. json = $.parseJSON(json);
  209. if(json.result == 'fail')
  210. {
  211. alert(json.message);
  212. return false;
  213. }
  214. if(!bugs[json.line]) bugs[json.line] = [];
  215. bugs[json.line].push(json);
  216. $('#bugForm').parent().remove();
  217. editor.changeViewZones(function (changeAccessor) {
  218. changeAccessor.removeZone(viewZoneId);
  219. });
  220. },
  221. beforeSubmit:function(formData, jqForm)
  222. {
  223. var form = jqForm[0];
  224. if(!form.product.value)
  225. {
  226. alert(productError);
  227. return false;
  228. }
  229. if(!form.title.value)
  230. {
  231. alert(titleError);
  232. $bugForm.find('input[name="title"]').focus();
  233. return false;
  234. }
  235. }
  236. });
  237. return false;
  238. }).on('change', 'input[name="begin"]', function()
  239. {
  240. var begin = $(this).val();
  241. var $end = $bugForm.find('input[name="end"]').attr('min', begin);
  242. if(parseInt($end.val()) < parseInt(begin)) $end.val(begin);
  243. $bugForm.find('select#assignedTo').val(blamePairs[begin]);
  244. $bugForm.find('select#assignedTo').trigger("chosen:updated");
  245. });
  246. $(document).on('click', function()
  247. {
  248. $('.highlight').removeClass('highlight');
  249. });
  250. });
  251. /**
  252. * Add view zone in editor.
  253. *
  254. * @param object $overlayDom
  255. * @param int $line
  256. * @param int $height
  257. * @param string $type
  258. * @param bool $removeOldZone
  259. *
  260. * @access public
  261. * @return int
  262. */
  263. function addViewZone(overlayDom, line, height, type, removeOldZone = true)
  264. {
  265. var zoneID = type == 'bugForm' ? viewZoneId : bugViewZoneId;
  266. if(removeOldZone && zoneID)
  267. {
  268. $('#bugForm').parent().remove();
  269. editor.changeViewZones(function (changeAccessor) {
  270. changeAccessor.removeZone(zoneID);
  271. });
  272. }
  273. editor.changeViewZones(function(changeAccessor)
  274. {
  275. var domNode = document.createElement('div');
  276. zoneId = changeAccessor.addZone(
  277. {
  278. afterLineNumber: line,
  279. heightInPx: height,
  280. domNode: domNode,
  281. onDomNodeTop: (top) => {
  282. overlayDom.style.top = `${top}px`;
  283. },
  284. onComputedHeight: (height) => {
  285. overlayDom.style.height = `${height}px`;
  286. }
  287. });
  288. });
  289. /* Add an overlay widget. */
  290. var overlayWidget = {
  291. getId: () => {
  292. return type + line;
  293. },
  294. getDomNode: () => {
  295. if(type == 'bugForm')
  296. {
  297. /* Remove old chosen div and init chosen.*/
  298. $(overlayDom).find('div[id$=chosen]').each(function(index, $chosenDiv)
  299. {
  300. $chosenDiv.remove();
  301. });
  302. $(overlayDom).find('.chosen').each(function(index, chosenSelect)
  303. {
  304. $(chosenSelect).chosen();
  305. });
  306. $(overlayDom).css('width', '495px');
  307. }
  308. else
  309. {
  310. $(overlayDom).css('width', editorWidth - 50 + 'px');
  311. $(overlayDom).css('overflow-y', 'scroll');
  312. }
  313. $(overlayDom).css('left', zoneLeft);
  314. return overlayDom;
  315. },
  316. getPosition: function()
  317. {
  318. return null;
  319. }
  320. };
  321. editor.addOverlayWidget(overlayWidget);
  322. return zoneId;
  323. }
  324. /**
  325. * Show bugs.
  326. *
  327. * @param int $line
  328. * @access public
  329. * @return void
  330. */
  331. function showBugs(line)
  332. {
  333. var realLine = diffContent ? diffContent.line.new[line - 1] : line;
  334. if(!bugs[realLine]) return false;
  335. var bugIDs = [];
  336. $.each(bugs[realLine], function(i, bug)
  337. {
  338. bugIDs.push(bug.id);
  339. });
  340. showBugsBlock(bugIDs);
  341. }
  342. /**
  343. * Remove bug zone.
  344. *
  345. * @access public
  346. * @return void
  347. */
  348. function removeBugZone()
  349. {
  350. $(document).find("[widgetid^='bugLine']").remove();
  351. editor.changeViewZones(function (changeAccessor) {
  352. changeAccessor.removeZone(bugViewZoneId);
  353. });
  354. }
  355. /**
  356. * Create comment.
  357. *
  358. * @param object $comment
  359. * @param object $comments
  360. * @access public
  361. * @return object
  362. */
  363. function createComment(comment, $comments)
  364. {
  365. var $commentCell = $('#commentCell');
  366. var $comment = $commentCell.clone().removeClass('hide').attr('id', 'comment-' + comment.id).attr('data-comment', comment.id);
  367. $comment.find('.realname').text(comment.realname);
  368. $comment.find('.comment-content').text(comment.comment);
  369. $comment.find('.date').text(comment.date);
  370. $comment.find('.edit').toggle(comment.edit);
  371. $comment.find('.comment-edit-form').attr('action', createLink('repo', 'editComment', 'commentID=' + comment.id));
  372. if(comment.user.avatar)
  373. {
  374. $comment.find('.avatar').removeClass('has-text').addClass('has-img');
  375. $comment.find('.avatar span').remove();
  376. $comment.find('.avatar').html('<img src="' + comment.user.avatar + '"/>');
  377. }
  378. else
  379. {
  380. $comment.find('.avatar').removeClass('has-img').addClass('has-text');
  381. $comment.find('.avatar img').remove();
  382. var name = comment.user.name ? comment.user.name : (comment.user.realname ? comment.user.realname : comment.user.account);
  383. $comment.find('.avatar').html('<span class="text text-len-' + name.replace(/[^\x00-\xff]/g, "00").length + '">' + name.toUpperCase().slice(0,1) + '</span>');
  384. }
  385. if($comments)
  386. {
  387. if(typeof $comments !== 'object') $comments = $('#bug-' + $comments + ' .comments');
  388. ($comments.hasClass('comments') ? $comments : $comments.find('.comments')).append($comment);
  389. }
  390. return $comment;
  391. };
  392. /**
  393. * Show bug form.
  394. *
  395. * @param int line
  396. * @access public
  397. * @return void
  398. */
  399. function showBugForm(line)
  400. {
  401. var realLine = diffContent ? diffContent.line.new[line - 1] : line;
  402. $bugForm.find('input[name="title"]').val('');
  403. $bugForm.find('input[name="begin"]').val(realLine);
  404. $bugForm.find('input[name="end"]').attr('min', realLine).val(realLine);
  405. $bugForm.find('select#assignedTo').val(blamePairs[realLine]);
  406. $bugForm.find('select#assignedTo').trigger("chosen:updated");
  407. $bugForm.show();
  408. /* Add a zone to review code. */
  409. var overlayDom = document.createElement('div');
  410. overlayDom.innerHTML = $bugForm.parent().html();
  411. $(overlayDom).find('input[name="begin"]').val(realLine);
  412. $(overlayDom).find('input[name="end"]').attr('min', realLine).val(realLine);
  413. viewZoneId = addViewZone(overlayDom, line, 545, 'bugForm');
  414. KindEditor.remove('#commentText');
  415. $('.ke-container').remove();
  416. $('#commentText').kindeditor();
  417. }