mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 09:42:02 +08:00
DEV: Use async/await in checklist (#22943)
This commit is contained in:
parent
7405aae85a
commit
f9b4cfe67e
|
@ -39,13 +39,16 @@ function addUlClasses(boxes) {
|
||||||
) {
|
) {
|
||||||
parent = parent.parentElement;
|
parent = parent.parentElement;
|
||||||
}
|
}
|
||||||
if (parent.nodeName === "LI" && parent.parentElement.nodeName === "UL") {
|
|
||||||
if (!hasPrecedingContent(val)) {
|
if (
|
||||||
parent.classList.add("has-checkbox");
|
parent.nodeName === "LI" &&
|
||||||
val.classList.add("list-item-checkbox");
|
parent.parentElement.nodeName === "UL" &&
|
||||||
if (!val.nextSibling) {
|
!hasPrecedingContent(val)
|
||||||
val.insertAdjacentHTML("afterend", "​"); // Ensure otherwise empty <li> does not collapse height
|
) {
|
||||||
}
|
parent.classList.add("has-checkbox");
|
||||||
|
val.classList.add("list-item-checkbox");
|
||||||
|
if (!val.nextSibling) {
|
||||||
|
val.insertAdjacentHTML("afterend", "​"); // Ensure otherwise empty <li> does not collapse height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -67,8 +70,8 @@ export function checklistSyntax(elem, postDecorator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
boxes.forEach((val, idx) => {
|
boxes.forEach((val, idx) => {
|
||||||
val.onclick = function (ev) {
|
val.onclick = async (event) => {
|
||||||
const box = ev.currentTarget;
|
const box = event.currentTarget;
|
||||||
const classList = box.classList;
|
const classList = box.classList;
|
||||||
|
|
||||||
if (classList.contains("permanent") || classList.contains("readonly")) {
|
if (classList.contains("permanent") || classList.contains("readonly")) {
|
||||||
|
@ -83,88 +86,82 @@ export function checklistSyntax(elem, postDecorator) {
|
||||||
box.classList.add("hidden");
|
box.classList.add("hidden");
|
||||||
boxes.forEach((e) => e.classList.add("readonly"));
|
boxes.forEach((e) => e.classList.add("readonly"));
|
||||||
|
|
||||||
ajax(`/posts/${postModel.id}`, { type: "GET", cache: false })
|
try {
|
||||||
.then((result) => {
|
const post = await ajax(`/posts/${postModel.id}`);
|
||||||
const blocks = [];
|
const blocks = [];
|
||||||
|
|
||||||
// Computing offsets where checkbox are not evaluated (i.e. inside
|
// Computing offsets where checkbox are not evaluated (i.e. inside
|
||||||
// code blocks).
|
// code blocks).
|
||||||
[
|
[
|
||||||
// inline code
|
// inline code
|
||||||
/`[^`\n]*\n?[^`\n]*`/gm,
|
/`[^`\n]*\n?[^`\n]*`/gm,
|
||||||
// multi-line code
|
// multi-line code
|
||||||
/^```[^]*?^```/gm,
|
/^```[^]*?^```/gm,
|
||||||
// bbcode
|
// bbcode
|
||||||
/\[code\][^]*?\[\/code\]/gm,
|
/\[code\][^]*?\[\/code\]/gm,
|
||||||
// italic/bold
|
// italic/bold
|
||||||
/_(?=\S).*?\S_/gm,
|
/_(?=\S).*?\S_/gm,
|
||||||
// strikethrough
|
// strikethrough
|
||||||
/~~(?=\S).*?\S~~/gm,
|
/~~(?=\S).*?\S~~/gm,
|
||||||
].forEach((regex) => {
|
].forEach((regex) => {
|
||||||
let match;
|
let match;
|
||||||
while ((match = regex.exec(result.raw)) != null) {
|
while ((match = regex.exec(post.raw)) != null) {
|
||||||
blocks.push([match.index, match.index + match[0].length]);
|
blocks.push([match.index, match.index + match[0].length]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
[
|
[
|
||||||
// italic/bold
|
// italic/bold
|
||||||
/([^\[\n]|^)\*\S.+?\S\*(?=[^\]\n]|$)/gm,
|
/([^\[\n]|^)\*\S.+?\S\*(?=[^\]\n]|$)/gm,
|
||||||
].forEach((regex) => {
|
].forEach((regex) => {
|
||||||
let match;
|
let match;
|
||||||
while ((match = regex.exec(result.raw)) != null) {
|
while ((match = regex.exec(post.raw)) != null) {
|
||||||
// Simulate lookbehind - skip the first character
|
// Simulate lookbehind - skip the first character
|
||||||
blocks.push([match.index + 1, match.index + match[0].length]);
|
blocks.push([match.index + 1, match.index + match[0].length]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// make the first run go to index = 0
|
|
||||||
let nth = -1;
|
|
||||||
let found = false;
|
|
||||||
const newRaw = result.raw.replace(
|
|
||||||
/\[(\s|\_|\-|\x|\\?\*)?\]/gi,
|
|
||||||
(match, ignored, off) => {
|
|
||||||
if (found) {
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
nth += blocks.every(
|
|
||||||
(b) => b[0] >= off + match.length || off > b[1]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (nth === idx) {
|
|
||||||
found = true; // Do not replace any further matches
|
|
||||||
return newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// make the first run go to index = 0
|
||||||
|
let nth = -1;
|
||||||
|
let found = false;
|
||||||
|
const newRaw = post.raw.replace(
|
||||||
|
/\[(\s|\_|\-|\x|\\?\*)?\]/gi,
|
||||||
|
(match, ignored, off) => {
|
||||||
|
if (found) {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
const save = postModel.save({
|
nth += blocks.every(
|
||||||
raw: newRaw,
|
(b) => b[0] >= off + match.length || off > b[1]
|
||||||
edit_reason: I18n.t("checklist.edit_reason"),
|
);
|
||||||
});
|
|
||||||
|
|
||||||
if (save && save.then) {
|
if (nth === idx) {
|
||||||
save
|
found = true; // Do not replace any further matches
|
||||||
.then(() => {
|
return newValue;
|
||||||
postWidget.attrs.isSaving = false;
|
}
|
||||||
postWidget.scheduleRerender();
|
|
||||||
})
|
return match;
|
||||||
.finally(() => removeReadonlyClass(boxes));
|
|
||||||
} else {
|
|
||||||
removeReadonlyClass(boxes);
|
|
||||||
}
|
}
|
||||||
})
|
);
|
||||||
.catch(() => removeReadonlyClass(boxes));
|
|
||||||
|
await postModel.save({
|
||||||
|
raw: newRaw,
|
||||||
|
edit_reason: I18n.t("checklist.edit_reason"),
|
||||||
|
});
|
||||||
|
|
||||||
|
postWidget.attrs.isSaving = false;
|
||||||
|
postWidget.scheduleRerender();
|
||||||
|
} finally {
|
||||||
|
removeReadonlyClass(boxes);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "checklist",
|
name: "checklist",
|
||||||
initialize: function () {
|
|
||||||
|
initialize() {
|
||||||
withPluginApi("0.1", (api) => initializePlugin(api));
|
withPluginApi("0.1", (api) => initializePlugin(api));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
en:
|
en:
|
||||||
site_settings:
|
site_settings:
|
||||||
checklist_enabled: 'Enable checklist plugin?'
|
checklist_enabled: "Enable checklist plugin?"
|
||||||
|
|
|
@ -11,8 +11,10 @@ async function prepare(raw) {
|
||||||
const cooked = await cookAsync(raw, {
|
const cooked = await cookAsync(raw, {
|
||||||
siteSettings: { checklist_enabled: true },
|
siteSettings: { checklist_enabled: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const widget = { attrs: {}, scheduleRerender() {} };
|
||||||
const model = Post.create({ id: 42, can_edit: true });
|
const model = Post.create({ id: 42, can_edit: true });
|
||||||
const decoratorHelper = { getModel: () => model };
|
const decoratorHelper = { widget, getModel: () => model };
|
||||||
|
|
||||||
const $elem = $(`<div>${cooked.string}</div>`);
|
const $elem = $(`<div>${cooked.string}</div>`);
|
||||||
checklistSyntax($elem[0], decoratorHelper);
|
checklistSyntax($elem[0], decoratorHelper);
|
||||||
|
@ -20,7 +22,7 @@ async function prepare(raw) {
|
||||||
currentRaw = raw;
|
currentRaw = raw;
|
||||||
|
|
||||||
const updated = new Promise((resolve) => {
|
const updated = new Promise((resolve) => {
|
||||||
model.save = (fields) => resolve(fields.raw);
|
model.save = async (fields) => resolve(fields.raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
return [$elem, updated];
|
return [$elem, updated];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user