[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:
parent
22de4ae9c4
commit
2cf91d58e7
4 changed files with 44 additions and 13 deletions
|
@ -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]
|
||||
|
|
|
@ -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({
|
||||
$('#edit-empty-content-modal')
|
||||
.modal({
|
||||
onApprove() {
|
||||
$('.edit.form').trigger('submit');
|
||||
},
|
||||
}).modal('show');
|
||||
})
|
||||
.modal('show');
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
5
web_src/js/utils/dom.test.js
Normal file
5
web_src/js/utils/dom.test.js
Normal 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>');
|
||||
});
|
Loading…
Reference in a new issue