/* globals wipPrefixes, issuesTribute, emojiTribute */ /* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */ /* exported toggleDeadlineForm, setDeadline, deleteDependencyModal, submitReply, cancelCodeComment, onOAuthLoginClick */ 'use strict'; function htmlEncode(text) { return jQuery('
').text(text).html() } let csrf; let suburl; let previewFileModes; let simpleMDEditor; let codeMirrorEditor; // Disable Dropzone auto-discover because it's manually initialized if (typeof(Dropzone) !== "undefined") { Dropzone.autoDiscover = false; } // Polyfill for IE9+ support (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) if (!Array.from) { Array.from = (function () { const toStr = Object.prototype.toString; const isCallable = function (fn) { return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; }; const toInteger = function (value) { const number = Number(value); if (isNaN(number)) { return 0; } if (number === 0 || !isFinite(number)) { return number; } return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); }; const maxSafeInteger = Math.pow(2, 53) - 1; const toLength = function (value) { const len = toInteger(value); return Math.min(Math.max(len, 0), maxSafeInteger); }; // The length property of the from method is 1. return function from(arrayLike/*, mapFn, thisArg */) { // 1. Let C be the this value. const C = this; // 2. Let items be ToObject(arrayLike). const items = Object(arrayLike); // 3. ReturnIfAbrupt(items). if (arrayLike == null) { throw new TypeError("Array.from requires an array-like object - not null or undefined"); } // 4. If mapfn is undefined, then let mapping be false. const mapFn = arguments.length > 1 ? arguments[1] : void undefined; let T; if (typeof mapFn !== 'undefined') { // 5. else // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. if (!isCallable(mapFn)) { throw new TypeError('Array.from: when provided, the second argument must be a function'); } // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 2) { T = arguments[2]; } } // 10. Let lenValue be Get(items, "length"). // 11. Let len be ToLength(lenValue). const len = toLength(items.length); // 13. If IsConstructor(C) is true, then // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len. // 14. a. Else, Let A be ArrayCreate(len). const A = isCallable(C) ? Object(new C(len)) : new Array(len); // 16. Let k be 0. let k = 0; // 17. Repeat, while k < len… (also steps a - h) let kValue; while (k < len) { kValue = items[k]; if (mapFn) { A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); } else { A[k] = kValue; } k += 1; } // 18. Let putStatus be Put(A, "length", len, true). A.length = len; // 20. Return A. return A; }; }()); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign if (typeof Object.assign != 'function') { // Must be writable: true, enumerable: false, configurable: true Object.defineProperty(Object, "assign", { value: function assign(target, _varArgs) { // .length of function is 2 'use strict'; if (target == null) { // TypeError if undefined or null throw new TypeError('Cannot convert undefined or null to object'); } const to = Object(target); for (let index = 1; index < arguments.length; index++) { const nextSource = arguments[index]; if (nextSource != null) { // Skip over if undefined or null for (const nextKey in nextSource) { // Avoid bugs when hasOwnProperty is shadowed if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, writable: true, configurable: true }); } function initCommentPreviewTab($form) { const $tabMenu = $form.find('.tabular.menu'); $tabMenu.find('.item').tab(); $tabMenu.find('.item[data-tab="' + $tabMenu.data('preview') + '"]').click(function () { const $this = $(this); $.post($this.data('url'), { "_csrf": csrf, "mode": "gfm", "context": $this.data('context'), "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() }, function (data) { const $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); $previewPanel.html(data); emojify.run($previewPanel[0]); $('pre code', $previewPanel[0]).each(function () { hljs.highlightBlock(this); }); } ); }); buttonsClickOnEnter(); } function initEditPreviewTab($form) { const $tabMenu = $form.find('.tabular.menu'); $tabMenu.find('.item').tab(); const $previewTab = $tabMenu.find('.item[data-tab="' + $tabMenu.data('preview') + '"]'); if ($previewTab.length) { previewFileModes = $previewTab.data('preview-file-modes').split(','); $previewTab.click(function () { const $this = $(this); $.post($this.data('url'), { "_csrf": csrf, "mode": "gfm", "context": $this.data('context'), "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() }, function (data) { const $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); $previewPanel.html(data); emojify.run($previewPanel[0]); $('pre code', $previewPanel[0]).each(function () { hljs.highlightBlock(this); }); } ); }); } } function initEditDiffTab($form) { const $tabMenu = $form.find('.tabular.menu'); $tabMenu.find('.item').tab(); $tabMenu.find('.item[data-tab="' + $tabMenu.data('diff') + '"]').click(function () { const $this = $(this); $.post($this.data('url'), { "_csrf": csrf, "context": $this.data('context'), "content": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() }, function (data) { const $diffPreviewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('diff') + '"]'); $diffPreviewPanel.html(data); emojify.run($diffPreviewPanel[0]); } ); }); } function initEditForm() { if ($('.edit.form').length == 0) { return; } initEditPreviewTab($('.edit.form')); initEditDiffTab($('.edit.form')); } function initBranchSelector() { const $selectBranch = $('.ui.select-branch') const $branchMenu = $selectBranch.find('.reference-list-menu'); $branchMenu.find('.item:not(.no-select)').click(function () { const selectedValue = $(this).data('id'); $($(this).data('id-selector')).val(selectedValue); $selectBranch.find('.ui .branch-name').text(selectedValue); }); $selectBranch.find('.reference.column').click(function () { $selectBranch.find('.scrolling.reference-list-menu').css('display', 'none'); $selectBranch.find('.reference .text').removeClass('black'); $($(this).data('target')).css('display', 'block'); $(this).find('.text').addClass('black'); return false; }); } function updateIssuesMeta(url, action, issueIds, elementId) { return new Promise(function(resolve) { $.ajax({ type: "POST", url: url, data: { "_csrf": csrf, "action": action, "issue_ids": issueIds, "id": elementId }, success: resolve }) }) } function initRepoStatusChecker() { const migrating = $("#repo_migrating"); $('#repo_migrating_failed').hide(); if (migrating) { const repo_name = migrating.attr('repo'); if (typeof repo_name === 'undefined') { return } $.ajax({ type: "GET", url: suburl +"/"+repo_name+"/status", data: { "_csrf": csrf, }, complete: function(xhr) { if (xhr.status == 200) { if (xhr.responseJSON) { if (xhr.responseJSON["status"] == 0) { location.reload(); return } setTimeout(function () { initRepoStatusChecker() }, 2000); return } } $('#repo_migrating_progress').hide(); $('#repo_migrating_failed').show(); } }) } } function initReactionSelector(parent) { let reactions = ''; if (!parent) { parent = $(document); reactions = '.reactions > '; } parent.find(reactions + 'a.label').popup({'position': 'bottom left', 'metadata': {'content': 'title', 'title': 'none'}}); parent.find('.select-reaction > .menu > .item, ' + reactions + 'a.label').on('click', function(e){ const vm = this; e.preventDefault(); if ($(this).hasClass('disabled')) return; const actionURL = $(this).hasClass('item') ? $(this).closest('.select-reaction').data('action-url') : $(this).data('action-url'); const url = actionURL + '/' + ($(this).hasClass('blue') ? 'unreact' : 'react'); $.ajax({ type: 'POST', url: url, data: { '_csrf': csrf, 'content': $(this).data('content') } }).done(function(resp) { if (resp && (resp.html || resp.empty)) { const content = $(vm).closest('.content'); let react = content.find('.segment.reactions'); if (!resp.empty && react.length > 0) { react.remove(); } if (!resp.empty) { react = $(''); const attachments = content.find('.segment.bottom:first'); if (attachments.length > 0) { react.insertBefore(attachments); } else { react.appendTo(content); } react.html(resp.html); const hasEmoji = react.find('.has-emoji'); for (let i = 0; i < hasEmoji.length; i++) { emojify.run(hasEmoji.get(i)); } react.find('.dropdown').dropdown(); initReactionSelector(react); } } }); }); } function insertAtCursor(field, value) { if (field.selectionStart || field.selectionStart === 0) { const startPos = field.selectionStart; const endPos = field.selectionEnd; field.value = field.value.substring(0, startPos) + value + field.value.substring(endPos, field.value.length); field.selectionStart = startPos + value.length; field.selectionEnd = startPos + value.length; } else { field.value += value; } } function replaceAndKeepCursor(field, oldval, newval) { if (field.selectionStart || field.selectionStart === 0) { const startPos = field.selectionStart; const endPos = field.selectionEnd; field.value = field.value.replace(oldval, newval); field.selectionStart = startPos + newval.length - oldval.length; field.selectionEnd = endPos + newval.length - oldval.length; } else { field.value = field.value.replace(oldval, newval); } } function retrieveImageFromClipboardAsBlob(pasteEvent, callback){ if (!pasteEvent.clipboardData) { return; } const items = pasteEvent.clipboardData.items; if (typeof(items) === "undefined") { return; } for (let i = 0; i < items.length; i++) { if (items[i].type.indexOf("image") === -1) continue; const blob = items[i].getAsFile(); if (typeof(callback) === "function") { pasteEvent.preventDefault(); pasteEvent.stopPropagation(); callback(blob); } } } function uploadFile(file, callback) { const xhr = new XMLHttpRequest(); xhr.onload = function() { if (xhr.status == 200) { callback(xhr.responseText); } }; xhr.open("post", suburl + "/attachments", true); xhr.setRequestHeader("X-Csrf-Token", csrf); const formData = new FormData(); formData.append('file', file, file.name); xhr.send(formData); } function reload() { window.location.reload(); } function initImagePaste(target) { target.each(function() { const field = this; field.addEventListener('paste', function(event){ retrieveImageFromClipboardAsBlob(event, function(img) { const name = img.name.substr(0, img.name.lastIndexOf('.')); insertAtCursor(field, '![' + name + ']()'); uploadFile(img, function(res) { const data = JSON.parse(res); replaceAndKeepCursor(field, '![' + name + ']()', '![' + name + '](' + suburl + '/attachments/' + data.uuid + ')'); const input = $('').val(data.uuid); $('.files').append(input); }); }); }, false); }); } function initCommentForm() { if ($('.comment.form').length == 0) { return } initBranchSelector(); initCommentPreviewTab($('.comment.form')); initImagePaste($('.comment.form textarea')); // Listsubmit function initListSubmits(selector, outerSelector) { const $list = $('.ui.' + outerSelector + '.list'); const $noSelect = $list.find('.no-select'); const $listMenu = $('.' + selector + ' .menu'); let hasLabelUpdateAction = $listMenu.data('action') == 'update'; const labels = {}; $('.' + selector).dropdown('setting', 'onHide', function(){ hasLabelUpdateAction = $listMenu.data('action') == 'update'; // Update the var if (hasLabelUpdateAction) { const promises = []; Object.keys(labels).forEach(function(elementId) { const label = labels[elementId]; const promise = updateIssuesMeta( label["update-url"], label["action"], label["issue-id"], elementId ); promises.push(promise); }); Promise.all(promises).then(reload); } }); $listMenu.find('.item:not(.no-select)').click(function () { // we don't need the action attribute when updating assignees if (selector == 'select-assignees-modify') { // UI magic. We need to do this here, otherwise it would destroy the functionality of // adding/removing labels if ($(this).hasClass('checked')) { $(this).removeClass('checked'); $(this).find('.octicon').removeClass('octicon-check'); } else { $(this).addClass('checked'); $(this).find('.octicon').addClass('octicon-check'); } updateIssuesMeta( $listMenu.data('update-url'), "", $listMenu.data('issue-id'), $(this).data('id') ); $listMenu.data('action', 'update'); // Update to reload the page when we updated items return false; } if ($(this).hasClass('checked')) { $(this).removeClass('checked'); $(this).find('.octicon').removeClass('octicon-check'); if (hasLabelUpdateAction) { if (!($(this).data('id') in labels)) { labels[$(this).data('id')] = { "update-url": $listMenu.data('update-url'), "action": "detach", "issue-id": $listMenu.data('issue-id'), }; } else { delete labels[$(this).data('id')]; } } } else { $(this).addClass('checked'); $(this).find('.octicon').addClass('octicon-check'); if (hasLabelUpdateAction) { if (!($(this).data('id') in labels)) { labels[$(this).data('id')] = { "update-url": $listMenu.data('update-url'), "action": "attach", "issue-id": $listMenu.data('issue-id'), }; } else { delete labels[$(this).data('id')]; } } } const listIds = []; $(this).parent().find('.item').each(function () { if ($(this).hasClass('checked')) { listIds.push($(this).data('id')); $($(this).data('id-selector')).removeClass('hide'); } else { $($(this).data('id-selector')).addClass('hide'); } }); if (listIds.length == 0) { $noSelect.removeClass('hide'); } else { $noSelect.addClass('hide'); } $($(this).parent().data('id')).val(listIds.join(",")); return false; }); $listMenu.find('.no-select.item').click(function () { if (hasLabelUpdateAction || selector == 'select-assignees-modify') { updateIssuesMeta( $listMenu.data('update-url'), "clear", $listMenu.data('issue-id'), "" ).then(reload); } $(this).parent().find('.item').each(function () { $(this).removeClass('checked'); $(this).find('.octicon').removeClass('octicon-check'); }); $list.find('.item').each(function () { $(this).addClass('hide'); }); $noSelect.removeClass('hide'); $($(this).parent().data('id')).val(''); }); } // Init labels and assignees initListSubmits('select-label', 'labels'); initListSubmits('select-assignees', 'assignees'); initListSubmits('select-assignees-modify', 'assignees'); function selectItem(select_id, input_id) { const $menu = $(select_id + ' .menu'); const $list = $('.ui' + select_id + '.list'); const hasUpdateAction = $menu.data('action') == 'update'; $menu.find('.item:not(.no-select)').click(function () { $(this).parent().find('.item').each(function () { $(this).removeClass('selected active') }); $(this).addClass('selected active'); if (hasUpdateAction) { updateIssuesMeta( $menu.data('update-url'), "", $menu.data('issue-id'), $(this).data('id') ).then(reload); } switch (input_id) { case '#milestone_id': $list.find('.selected').html('' + htmlEncode($(this).text()) + ''); break; case '#assignee_id': $list.find('.selected').html('' + '' + htmlEncode($(this).text()) + ''); } $('.ui' + select_id + '.list .no-select').addClass('hide'); $(input_id).val($(this).data('id')); }); $menu.find('.no-select.item').click(function () { $(this).parent().find('.item:not(.no-select)').each(function () { $(this).removeClass('selected active') }); if (hasUpdateAction) { updateIssuesMeta( $menu.data('update-url'), "", $menu.data('issue-id'), $(this).data('id') ).then(reload); } $list.find('.selected').html(''); $list.find('.no-select').removeClass('hide'); $(input_id).val(''); }); } // Milestone and assignee selectItem('.select-milestone', '#milestone_id'); selectItem('.select-assignee', '#assignee_id'); } function initInstall() { if ($('.install').length == 0) { return; } if ($('#db_host').val()=="") { $('#db_host').val("127.0.0.1:3306"); $('#db_user').val("gitea"); $('#db_name').val("gitea"); } // Database type change detection. $("#db_type").change(function () { const sqliteDefault = 'data/gitea.db'; const tidbDefault = 'data/gitea_tidb'; const dbType = $(this).val(); if (dbType === "SQLite3") { $('#sql_settings').hide(); $('#pgsql_settings').hide(); $('#mysql_settings').hide(); $('#sqlite_settings').show(); if (dbType === "SQLite3" && $('#db_path').val() == tidbDefault) { $('#db_path').val(sqliteDefault); } return; } const dbDefaults = { "MySQL": "127.0.0.1:3306", "PostgreSQL": "127.0.0.1:5432", "MSSQL": "127.0.0.1:1433" }; $('#sqlite_settings').hide(); $('#sql_settings').show(); $('#pgsql_settings').toggle(dbType === "PostgreSQL"); $('#mysql_settings').toggle(dbType === "MySQL"); $.each(dbDefaults, function(_type, defaultHost) { if ($('#db_host').val() == defaultHost) { $('#db_host').val(dbDefaults[dbType]); return false; } }); }); // TODO: better handling of exclusive relations. $('#offline-mode input').change(function () { if ($(this).is(':checked')) { $('#disable-gravatar').checkbox('check'); $('#federated-avatar-lookup').checkbox('uncheck'); } }); $('#disable-gravatar input').change(function () { if ($(this).is(':checked')) { $('#federated-avatar-lookup').checkbox('uncheck'); } else { $('#offline-mode').checkbox('uncheck'); } }); $('#federated-avatar-lookup input').change(function () { if ($(this).is(':checked')) { $('#disable-gravatar').checkbox('uncheck'); $('#offline-mode').checkbox('uncheck'); } }); $('#enable-openid-signin input').change(function () { if ($(this).is(':checked')) { if (!$('#disable-registration input').is(':checked')) { $('#enable-openid-signup').checkbox('check'); } } else { $('#enable-openid-signup').checkbox('uncheck'); } }); $('#disable-registration input').change(function () { if ($(this).is(':checked')) { $('#enable-captcha').checkbox('uncheck'); $('#enable-openid-signup').checkbox('uncheck'); } else { $('#enable-openid-signup').checkbox('check'); } }); $('#enable-captcha input').change(function () { if ($(this).is(':checked')) { $('#disable-registration').checkbox('uncheck'); } }); } function initRepository() { if ($('.repository').length == 0) { return; } function initFilterSearchDropdown(selector) { const $dropdown = $(selector); $dropdown.dropdown({ fullTextSearch: true, selectOnKeydown: false, onChange: function (_text, _value, $choice) { if ($choice.data('url')) { window.location.href = $choice.data('url'); } }, message: {noResults: $dropdown.data('no-results')} }); } // File list and commits if ($('.repository.file.list').length > 0 || ('.repository.commits').length > 0) { initFilterBranchTagDropdown('.choose.reference .dropdown'); } // Wiki if ($('.repository.wiki.view').length > 0) { initFilterSearchDropdown('.choose.page .dropdown'); } // Options if ($('.repository.settings.options').length > 0) { $('#repo_name').keyup(function () { const $prompt = $('#repo-name-change-prompt'); if ($(this).val().toString().toLowerCase() != $(this).data('name').toString().toLowerCase()) { $prompt.show(); } else { $prompt.hide(); } }); // Enable or select internal/external wiki system and issue tracker. $('.enable-system').change(function () { if (this.checked) { $($(this).data('target')).removeClass('disabled'); if (!$(this).data('context')) $($(this).data('context')).addClass('disabled'); } else { $($(this).data('target')).addClass('disabled'); if (!$(this).data('context')) $($(this).data('context')).removeClass('disabled'); } }); $('.enable-system-radio').change(function () { if (this.value == 'false') { $($(this).data('target')).addClass('disabled'); if (typeof $(this).data('context') !== 'undefined') $($(this).data('context')).removeClass('disabled'); } else if (this.value == 'true') { $($(this).data('target')).removeClass('disabled'); if (typeof $(this).data('context') !== 'undefined') $($(this).data('context')).addClass('disabled'); } }); } // Labels if ($('.repository.labels').length > 0) { // Create label const $newLabelPanel = $('.new-label.segment'); $('.new-label.button').click(function () { $newLabelPanel.show(); }); $('.new-label.segment .cancel').click(function () { $newLabelPanel.hide(); }); $('.color-picker').each(function () { $(this).minicolors(); }); $('.precolors .color').click(function () { const color_hex = $(this).data('color-hex'); $('.color-picker').val(color_hex); $('.minicolors-swatch-color').css("background-color", color_hex); }); $('.edit-label-button').click(function () { $('#label-modal-id').val($(this).data('id')); $('.edit-label .new-label-input').val($(this).data('title')); $('.edit-label .new-label-desc-input').val($(this).data('description')); $('.edit-label .color-picker').val($(this).data('color')); $('.minicolors-swatch-color').css("background-color", $(this).data('color')); $('.edit-label.modal').modal({ onApprove: function () { $('.edit-label.form').submit(); } }).modal('show'); return false; }); } // Milestones if ($('.repository.new.milestone').length > 0) { const $datepicker = $('.milestone.datepicker'); $datepicker.datetimepicker({ lang: $datepicker.data('lang'), inline: true, timepicker: false, startDate: $datepicker.data('start-date'), formatDate: 'Y-m-d', onSelectDate: function (ct) { $('#deadline').val(ct.dateFormat('Y-m-d')); } }); $('#clear-date').click(function () { $('#deadline').val(''); return false; }); } // Issues if ($('.repository.view.issue').length > 0) { // Edit issue title const $issueTitle = $('#issue-title'); const $editInput = $('#edit-title-input input'); const editTitleToggle = function () { $issueTitle.toggle(); $('.not-in-edit').toggle(); $('#edit-title-input').toggle(); $('.in-edit').toggle(); $editInput.focus(); return false; }; $('#edit-title').click(editTitleToggle); $('#cancel-edit-title').click(editTitleToggle); $('#save-edit-title').click(editTitleToggle).click(function () { if ($editInput.val().length == 0 || $editInput.val() == $issueTitle.text()) { $editInput.val($issueTitle.text()); return false; } $.post($(this).data('update-url'), { "_csrf": csrf, "title": $editInput.val() }, function (data) { $editInput.val(data.title); $issueTitle.text(data.title); reload(); }); return false; }); // Edit issue or comment content $('.edit-content').click(function () { const $segment = $(this).parent().parent().parent().next(); const $editContentZone = $segment.find('.edit-content-zone'); const $renderContent = $segment.find('.render-content'); const $rawContent = $segment.find('.raw-content'); let $textarea; // Setup new form if ($editContentZone.html().length == 0) { $editContentZone.html($('#edit-content-form').html()); $textarea = $editContentZone.find('textarea'); issuesTribute.attach($textarea.get()); emojiTribute.attach($textarea.get()); // Give new write/preview data-tab name to distinguish from others const $editContentForm = $editContentZone.find('.ui.comment.form'); const $tabMenu = $editContentForm.find('.tabular.menu'); $tabMenu.attr('data-write', $editContentZone.data('write')); $tabMenu.attr('data-preview', $editContentZone.data('preview')); $tabMenu.find('.write.item').attr('data-tab', $editContentZone.data('write')); $tabMenu.find('.preview.item').attr('data-tab', $editContentZone.data('preview')); $editContentForm.find('.write.segment').attr('data-tab', $editContentZone.data('write')); $editContentForm.find('.preview.segment').attr('data-tab', $editContentZone.data('preview')); initCommentPreviewTab($editContentForm); $editContentZone.find('.cancel.button').click(function () { $renderContent.show(); $editContentZone.hide(); }); $editContentZone.find('.save.button').click(function () { $renderContent.show(); $editContentZone.hide(); $.post($editContentZone.data('update-url'), { "_csrf": csrf, "content": $textarea.val(), "context": $editContentZone.data('context') }, function (data) { if (data.length == 0) { $renderContent.html($('#no-content').html()); } else { $renderContent.html(data.content); emojify.run($renderContent[0]); $('pre code', $renderContent[0]).each(function () { hljs.highlightBlock(this); }); } }); }); } else { $textarea = $segment.find('textarea'); } // Show write/preview tab and copy raw content as needed $editContentZone.show(); $renderContent.hide(); if ($textarea.val().length == 0) { $textarea.val($rawContent.text()); } $textarea.focus(); return false; }); // Delete comment $('.delete-comment').click(function () { const $this = $(this); if (confirm($this.data('locale'))) { $.post($this.data('url'), { "_csrf": csrf }).success(function () { $('#' + $this.data('comment-id')).remove(); }); } return false; }); // Change status const $statusButton = $('#status-button'); $('#comment-form .edit_area').keyup(function () { if ($(this).val().length == 0) { $statusButton.text($statusButton.data('status')) } else { $statusButton.text($statusButton.data('status-and-comment')) } }); $statusButton.click(function () { $('#status').val($statusButton.data('status-val')); $('#comment-form').submit(); }); // Pull Request merge button const $mergeButton = $('.merge-button > button'); $mergeButton.on('click', function(e) { e.preventDefault(); $('.' + $(this).data('do') + '-fields').show(); $(this).parent().hide(); }); $('.merge-button > .dropdown').dropdown({ onChange: function (_text, _value, $choice) { if ($choice.data('do')) { $mergeButton.find('.button-text').text($choice.text()); $mergeButton.data('do', $choice.data('do')); } } }); $('.merge-cancel').on('click', function(e) { e.preventDefault(); $(this).closest('.form').hide(); $mergeButton.parent().show(); }); initReactionSelector(); } // Diff if ($('.repository.diff').length > 0) { $('.diff-counter').each(function () { const $item = $(this); const addLine = $item.find('span[data-line].add').data("line"); const delLine = $item.find('span[data-line].del').data("line"); const addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100; $item.find(".bar .add").css("width", addPercent + "%"); }); } // Quick start and repository home $('#repo-clone-ssh').click(function () { $('.clone-url').text($(this).data('link')); $('#repo-clone-url').val($(this).data('link')); $(this).addClass('blue'); $('#repo-clone-https').removeClass('blue'); localStorage.setItem('repo-clone-protocol', 'ssh'); }); $('#repo-clone-https').click(function () { $('.clone-url').text($(this).data('link')); $('#repo-clone-url').val($(this).data('link')); $(this).addClass('blue'); $('#repo-clone-ssh').removeClass('blue'); localStorage.setItem('repo-clone-protocol', 'https'); }); $('#repo-clone-url').click(function () { $(this).select(); }); // Pull request const $repoComparePull = $('.repository.compare.pull'); if ($repoComparePull.length > 0) { initFilterSearchDropdown('.choose.branch .dropdown'); // show pull request form $repoComparePull.find('button.show-form').on('click', function(e) { e.preventDefault(); $repoComparePull.find('.pullrequest-form').show(); $(this).parent().hide(); }); } // Branches if ($('.repository.settings.branches').length > 0) { initFilterSearchDropdown('.protected-branches .dropdown'); $('.enable-protection, .enable-whitelist').change(function () { if (this.checked) { $($(this).data('target')).removeClass('disabled'); } else { $($(this).data('target')).addClass('disabled'); } }); } } function initMigration() { const toggleMigrations = function() { const authUserName = $('#auth_username').val(); const cloneAddr = $('#clone_addr').val(); if (!$('#mirror').is(":checked") && (authUserName!=undefined && authUserName.length > 0) && (cloneAddr!=undefined && (cloneAddr.startsWith("https://github.com") || cloneAddr.startsWith("http://github.com")))) { $('#migrate_items').show(); } else { $('#migrate_items').hide(); } } toggleMigrations(); $('#clone_addr').on('input', toggleMigrations) $('#auth_username').on('input', toggleMigrations) $('#mirror').on('change', toggleMigrations) } function initPullRequestReview() { $('.show-outdated').on('click', function (e) { e.preventDefault(); const id = $(this).data('comment'); $(this).addClass("hide"); $("#code-comments-" + id).removeClass('hide'); $("#code-preview-" + id).removeClass('hide'); $("#hide-outdated-" + id).removeClass('hide'); }); $('.hide-outdated').on('click', function (e) { e.preventDefault(); const id = $(this).data('comment'); $(this).addClass("hide"); $("#code-comments-" + id).addClass('hide'); $("#code-preview-" + id).addClass('hide'); $("#show-outdated-" + id).removeClass('hide'); }); $('button.comment-form-reply').on('click', function (e) { e.preventDefault(); $(this).hide(); const form = $(this).parent().find('.comment-form') form.removeClass('hide'); assingMenuAttributes(form.find('.menu')); }); // The following part is only for diff views if ($('.repository.pull.diff').length == 0) { return; } $('.diff-detail-box.ui.sticky').sticky(); $('.btn-review').on('click', function(e) { e.preventDefault(); $(this).closest('.dropdown').find('.menu').toggle('visible'); }).closest('.dropdown').find('.link.close').on('click', function(e) { e.preventDefault(); $(this).closest('.menu').toggle('visible'); }); $('.code-view .lines-code,.code-view .lines-num') .on('mouseenter', function() { const parent = $(this).closest('td'); $(this).closest('tr').addClass( parent.hasClass('lines-num-old') || parent.hasClass('lines-code-old') ? 'focus-lines-old' : 'focus-lines-new' ); }) .on('mouseleave', function() { $(this).closest('tr').removeClass('focus-lines-new focus-lines-old'); }); $('.add-code-comment').on('click', function(e) { // https://github.com/go-gitea/gitea/issues/4745 if ($(e.target).hasClass('btn-add-single')) { return; } e.preventDefault(); const isSplit = $(this).closest('.code-diff').hasClass('code-diff-split'); const side = $(this).data('side'); const idx = $(this).data('idx'); const path = $(this).data('path'); const form = $('#pull_review_add_comment').html(); const tr = $(this).closest('tr'); let ntr = tr.next(); if (!ntr.hasClass('add-comment')) { ntr = $('