[PORT] Enable no-jquery/no-parse-html-literal and fix violation (gitea#31684)

Tested it, path segment creation works just like before.

---

Conflict resolution: trivial, also ported code from
https://github.com/go-gitea/gitea/pull/31283
This commit is contained in:
silverwind 2024-07-27 16:44:41 +02:00 committed by Gusted
parent 22de4ae9c4
commit 2cf91d58e7
No known key found for this signature in database
GPG Key ID: FD821B732837125F
4 changed files with 44 additions and 13 deletions

View File

@ -460,7 +460,7 @@ rules:
no-jquery/no-param: [2]
no-jquery/no-parent: [0]
no-jquery/no-parents: [2]
no-jquery/no-parse-html-literal: [0]
no-jquery/no-parse-html-literal: [2]
no-jquery/no-parse-html: [2]
no-jquery/no-parse-json: [2]
no-jquery/no-parse-xml: [2]

View File

@ -1,7 +1,7 @@
import $ from 'jquery';
import {htmlEscape} from 'escape-goat';
import {createCodeEditor} from './codeeditor.js';
import {hideElem, showElem} from '../utils/dom.js';
import {hideElem, showElem, createElementFromHTML} from '../utils/dom.js';
import {initMarkupContent} from '../markup/content.js';
import {attachRefIssueContextPopup} from './contextpopup.js';
import {POST} from '../modules/fetch.js';
@ -9,7 +9,9 @@ import {POST} from '../modules/fetch.js';
function initEditPreviewTab($form) {
const $tabMenu = $form.find('.tabular.menu');
$tabMenu.find('.item').tab();
const $previewTab = $tabMenu.find(`.item[data-tab="${$tabMenu.data('preview')}"]`);
const $previewTab = $tabMenu.find(
`.item[data-tab="${$tabMenu.data('preview')}"]`,
);
if ($previewTab.length) {
$previewTab.on('click', async function () {
const $this = $(this);
@ -24,12 +26,17 @@ function initEditPreviewTab($form) {
const formData = new FormData();
formData.append('mode', mode);
formData.append('context', context);
formData.append('text', $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val());
formData.append(
'text',
$form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(),
);
formData.append('file_path', $treePathEl.val());
try {
const response = await POST($this.data('url'), {data: formData});
const data = await response.text();
const $previewPanel = $form.find(`.tab[data-tab="${$tabMenu.data('preview')}"]`);
const $previewPanel = $form.find(
`.tab[data-tab="${$tabMenu.data('preview')}"]`,
);
renderPreviewPanelContent($previewPanel, data);
} catch (error) {
console.error('Error:', error);
@ -96,8 +103,14 @@ export function initRepoEditor() {
const value = parts[i];
if (i < parts.length - 1) {
if (value.length) {
$(`<span class="section"><a href="#">${htmlEscape(value)}</a></span>`).insertBefore($(this));
$('<div class="breadcrumb-divider">/</div>').insertBefore($(this));
$editFilename[0].before(
createElementFromHTML(
`<span class="section"><a href="#">${htmlEscape(value)}</a></span>`,
),
);
$editFilename[0].before(
createElementFromHTML(`<div class="breadcrumb-divider">/</div>`),
);
}
} else {
$(this).val(value);
@ -113,7 +126,11 @@ export function initRepoEditor() {
const $section = $('.breadcrumb span.section');
// Jump back to last directory once the filename is empty
if (e.code === 'Backspace' && getCursorPosition($(this)) === 0 && $section.length > 0) {
if (
e.code === 'Backspace' &&
getCursorPosition($(this)) === 0 &&
$section.length > 0
) {
e.preventDefault();
const $divider = $('.breadcrumb .breadcrumb-divider');
const value = $section.last().find('a').text();
@ -164,11 +181,13 @@ export function initRepoEditor() {
commitButton?.addEventListener('click', (e) => {
// A modal which asks if an empty file should be committed
if (!$editArea.val()) {
$('#edit-empty-content-modal').modal({
onApprove() {
$('.edit.form').trigger('submit');
},
}).modal('show');
$('#edit-empty-content-modal')
.modal({
onApprove() {
$('.edit.form').trigger('submit');
},
})
.modal('show');
e.preventDefault();
}
});

View File

@ -296,3 +296,10 @@ export function replaceTextareaSelection(textarea, text) {
textarea.dispatchEvent(new CustomEvent('change', {bubbles: true, cancelable: true}));
}
}
// Warning: Do not enter any unsanitized variables here
export function createElementFromHTML(htmlString) {
const div = document.createElement('div');
div.innerHTML = htmlString.trim();
return div.firstChild;
}

View File

@ -0,0 +1,5 @@
import {createElementFromHTML} from './dom.js';
test('createElementFromHTML', () => {
expect(createElementFromHTML('<a>foo<span>bar</span></a>').outerHTML).toEqual('<a>foo<span>bar</span></a>');
});