mirror of
https://github.com/go-gitea/gitea
synced 2025-03-10 20:54:30 +00:00
1. Add some "render-content" classes to "markup" elements when the content is rendered 2. Use correct "markup" wrapper for "preview" (but not set that class on the tab) 3. Remove incorrect "markup" class from LFS file view, because there is no markup content * "edit-diff" is also removed because it does nothing 5. Use "initPdfViewer" for PDF viewer 6. Remove incorrect "content" class from milestone markup 7. Init all ".markup" elements by new init framework --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
91 lines
3.6 KiB
TypeScript
91 lines
3.6 KiB
TypeScript
import {POST} from '../modules/fetch.ts';
|
|
import {showErrorToast} from '../modules/toast.ts';
|
|
|
|
const preventListener = (e: Event) => e.preventDefault();
|
|
|
|
/**
|
|
* Attaches `input` handlers to markdown rendered tasklist checkboxes in comments.
|
|
*
|
|
* When a checkbox value changes, the corresponding [ ] or [x] in the markdown string
|
|
* is set accordingly and sent to the server. On success, it updates the raw-content on
|
|
* error it resets the checkbox to its original value.
|
|
*/
|
|
export function initMarkupTasklist(elMarkup: HTMLElement): void {
|
|
if (!elMarkup.matches('[data-can-edit=true]')) return;
|
|
|
|
const container = elMarkup.parentNode;
|
|
const checkboxes = elMarkup.querySelectorAll<HTMLInputElement>(`.task-list-item input[type=checkbox]`);
|
|
|
|
for (const checkbox of checkboxes) {
|
|
if (checkbox.hasAttribute('data-editable')) {
|
|
return;
|
|
}
|
|
|
|
checkbox.setAttribute('data-editable', 'true');
|
|
checkbox.addEventListener('input', async () => {
|
|
const checkboxCharacter = checkbox.checked ? 'x' : ' ';
|
|
const position = parseInt(checkbox.getAttribute('data-source-position')) + 1;
|
|
|
|
const rawContent = container.querySelector('.raw-content');
|
|
const oldContent = rawContent.textContent;
|
|
|
|
const encoder = new TextEncoder();
|
|
const buffer = encoder.encode(oldContent);
|
|
// Indexes may fall off the ends and return undefined.
|
|
if (buffer[position - 1] !== '['.codePointAt(0) ||
|
|
buffer[position] !== ' '.codePointAt(0) && buffer[position] !== 'x'.codePointAt(0) ||
|
|
buffer[position + 1] !== ']'.codePointAt(0)) {
|
|
// Position is probably wrong. Revert and don't allow change.
|
|
checkbox.checked = !checkbox.checked;
|
|
throw new Error(`Expected position to be space or x and surrounded by brackets, but it's not: position=${position}`);
|
|
}
|
|
buffer.set(encoder.encode(checkboxCharacter), position);
|
|
const newContent = new TextDecoder().decode(buffer);
|
|
|
|
if (newContent === oldContent) {
|
|
return;
|
|
}
|
|
|
|
// Prevent further inputs until the request is done. This does not use the
|
|
// `disabled` attribute because it causes the border to flash on click.
|
|
for (const checkbox of checkboxes) {
|
|
checkbox.addEventListener('click', preventListener);
|
|
}
|
|
|
|
try {
|
|
const editContentZone = container.querySelector<HTMLDivElement>('.edit-content-zone');
|
|
const updateUrl = editContentZone.getAttribute('data-update-url');
|
|
const context = editContentZone.getAttribute('data-context');
|
|
const contentVersion = editContentZone.getAttribute('data-content-version');
|
|
|
|
const requestBody = new FormData();
|
|
requestBody.append('ignore_attachments', 'true');
|
|
requestBody.append('content', newContent);
|
|
requestBody.append('context', context);
|
|
requestBody.append('content_version', contentVersion);
|
|
const response = await POST(updateUrl, {data: requestBody});
|
|
const data = await response.json();
|
|
if (response.status === 400) {
|
|
showErrorToast(data.errorMessage);
|
|
return;
|
|
}
|
|
editContentZone.setAttribute('data-content-version', data.contentVersion);
|
|
rawContent.textContent = newContent;
|
|
} catch (err) {
|
|
checkbox.checked = !checkbox.checked;
|
|
console.error(err);
|
|
}
|
|
|
|
// Enable input on checkboxes again
|
|
for (const checkbox of checkboxes) {
|
|
checkbox.removeEventListener('click', preventListener);
|
|
}
|
|
});
|
|
|
|
// Enable the checkboxes as they are initially disabled by the markdown renderer
|
|
for (const checkbox of checkboxes) {
|
|
checkbox.disabled = false;
|
|
}
|
|
}
|
|
}
|