FEATURE: add strikethrough rich editor extension

This commit is contained in:
Renato Atilio
2025-02-03 21:52:47 -03:00
parent 9f41ce7fce
commit 992aed9ae3
3 changed files with 87 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
import { registerRichEditorExtension } from "discourse/lib/composer/rich-editor-extensions";
import strikethrough from "./strikethrough";
/**
* List of default extensions
* ProsemirrorEditor autoloads them when includeDefault=true (the default)
*
* @type {RichEditorExtension[]}
*/
const defaultExtensions = [strikethrough];
defaultExtensions.forEach(registerRichEditorExtension);

View File

@@ -0,0 +1,36 @@
/** @type {RichEditorExtension} */
const extension = {
markSpec: {
strikethrough: {
before: "link",
parseDOM: [
{ tag: "s" },
{ tag: "del" },
{
getAttrs: (value) =>
/(^|[\s])line-through([\s]|$)/u.test(value) && null,
style: "text-decoration",
},
],
toDOM() {
return ["s"];
},
},
},
inputRules: ({ schema, markInputRule }) =>
markInputRule(/~~([^~]+)~~$/, schema.marks.strikethrough),
parse: {
s: { mark: "strikethrough" },
bbcode_s: { mark: "strikethrough" },
},
serializeMark: {
strikethrough: {
open: "~~",
close: "~~",
mixable: true,
expelEnclosingWhitespace: true,
},
},
};
export default extension;

View File

@@ -0,0 +1,39 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { testMarkdown } from "discourse/tests/helpers/rich-editor-helper";
module(
"Integration | Component | prosemirror-editor - strikethrough extension",
function (hooks) {
setupRenderingTest(hooks);
const testCases = {
strikethrough: [
["[s]Hello[/s]", "<p><s>Hello</s></p>", "~~Hello~~"],
["~~Hello~~", "<p><s>Hello</s></p>", "~~Hello~~"],
[
"Hey [s]wrod[/s] ~~uord~~ World",
"<p>Hey <s>wrod</s> <s>uord</s> World</p>",
"Hey ~~wrod~~ ~~uord~~ World",
],
],
"with other marks": [
[
"___[s][`Hello`](https://example.com)[/s]___",
'<p><em><strong><s><a href="https://example.com"><code>Hello</code></a></s></strong></em></p>',
"***~~[`Hello`](https://example.com)~~***",
],
],
};
Object.entries(testCases).forEach(([name, tests]) => {
tests.forEach(([markdown, expectedHtml, expectedMarkdown]) => {
test(name, async function (assert) {
this.siteSettings.rich_editor = true;
await testMarkdown(assert, markdown, expectedHtml, expectedMarkdown);
});
});
});
}
);