Skip to content

Commit 2e16e95

Browse files
committed
js improvements
1 parent a9a85a3 commit 2e16e95

File tree

1 file changed

+42
-30
lines changed

1 file changed

+42
-30
lines changed

web_src/js/markup/tasklist.js

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,59 @@
11
/**
2-
* Attaches `change` handlers to markdown rendered tasklist checkboxes in comments.
3-
* When a checkbox value changes, the corresponding [ ] or [x] in the markdown string is set accordingly and sent to the server.
4-
* On success it updates the raw-content on error it resets the checkbox to its original value.
2+
* Attaches `input` handlers to markdown rendered tasklist checkboxes in comments.
3+
* When a checkbox value changes, the corresponding [ ] or [x] in the markdown string
4+
* is set accordingly and sent to the server. On success it updates the raw-content on
5+
* error it resets the checkbox to its original value.
56
*/
6-
export default function initMarkupTasklist() {
7-
document.querySelectorAll(`.render-content.markup[data-can-edit='true']`).forEach((el) => {
8-
const container = el.parentNode;
9-
const checkboxes = container.querySelectorAll(`.task-list-item input[type=checkbox]`);
107

11-
checkboxes.forEach((cb) => cb.addEventListener('change', async (ev) => {
12-
const checkbox = ev.target;
13-
const checkboxCharacter = checkbox.checked ? 'x' : ' ';
14-
const position = parseInt(checkbox.dataset.sourcePosition) + 1;
8+
const preventListener = (e) => e.preventDefault();
159

16-
const rawContent = container.querySelector('.raw-content');
17-
const oldContent = rawContent.textContent;
18-
const newContent = oldContent.substring(0, position) + checkboxCharacter + oldContent.substring(position + 1);
19-
20-
if (newContent !== oldContent) {
21-
checkboxes.forEach((cb) => cb.disabled = true);
10+
export default function initMarkupTasklist() {
11+
for (const el of document.querySelectorAll(`.markup[data-can-edit='true']`) || []) {
12+
const container = el.parentNode;
13+
const checkboxes = el.querySelectorAll(`.task-list-item input[type=checkbox]`);
14+
15+
for (const checkbox of checkboxes) {
16+
checkbox.addEventListener('input', async () => {
17+
const checkboxCharacter = checkbox.checked ? 'x' : ' ';
18+
const position = parseInt(checkbox.dataset.sourcePosition) + 1;
19+
20+
const rawContent = container.querySelector('.raw-content');
21+
const oldContent = rawContent.textContent;
22+
const newContent = oldContent.substring(0, position) + checkboxCharacter + oldContent.substring(position + 1);
23+
if (newContent === oldContent) return;
24+
25+
// Prevent further inputs until the request is done. This does not use the
26+
// `disabled` attribute because it causes the border to flash on click.
27+
for (const checkbox of checkboxes) {
28+
checkbox.addEventListener('click', preventListener);
29+
}
2230

2331
try {
24-
const contentZone = container.querySelector('.edit-content-zone');
25-
const url = contentZone.dataset.updateUrl;
26-
const context = contentZone.dataset.context;
32+
const editContentZone = container.querySelector('.edit-content-zone');
33+
const {updateUrl, context} = editContentZone.dataset;
2734

28-
await $.post(url, {
35+
await $.post(updateUrl, {
2936
_csrf: window.config.csrf,
3037
content: newContent,
3138
context,
3239
});
3340

3441
rawContent.textContent = newContent;
35-
} catch (e) {
42+
} catch (err) {
3643
checkbox.checked = !checkbox.checked;
37-
38-
console.error(e);
39-
} finally {
40-
checkboxes.forEach((cb) => cb.disabled = false);
44+
console.error(err);
4145
}
42-
}
43-
}));
4446

45-
checkboxes.forEach((cb) => cb.disabled = false);
46-
});
47+
// Enable input on checkboxes again
48+
for (const checkbox of checkboxes) {
49+
checkbox.removeEventListener('click', preventListener);
50+
}
51+
});
52+
}
53+
54+
// Enable the checkboxes as they are initially disabled by the markdown renderer
55+
for (const checkbox of checkboxes) {
56+
checkbox.disabled = false;
57+
}
58+
}
4759
}

0 commit comments

Comments
 (0)