mirror of
https://github.com/discourse/discourse.git
synced 2025-04-25 20:14:29 +08:00
FEATURE: add html-block rich editor extension (#31181)
Continues the work done on https://github.com/discourse/discourse/pull/30815. Adds an `html_block` node and its parsing/serialization logic. It's rendered as a code block with HTML syntax highlighting, and serialized as-is to the Markdown output.
This commit is contained in:
parent
03429b0f8f
commit
71303a509f
@ -0,0 +1,35 @@
|
||||
/** @type {RichEditorExtension} */
|
||||
const extension = {
|
||||
nodeSpec: {
|
||||
html_block: {
|
||||
attrs: { params: { default: "html" } },
|
||||
group: "block",
|
||||
content: "text*",
|
||||
code: true,
|
||||
defining: true,
|
||||
marks: "",
|
||||
isolating: true,
|
||||
selectable: true,
|
||||
draggable: true,
|
||||
parseDOM: [{ tag: "pre.html-block", preserveWhitespace: "full" }],
|
||||
toDOM() {
|
||||
return ["pre", { class: "html-block" }, ["code", 0]];
|
||||
},
|
||||
},
|
||||
},
|
||||
parse: {
|
||||
html_block: (state, token) => {
|
||||
state.openNode(state.schema.nodes.html_block);
|
||||
state.addText(token.content.trim());
|
||||
state.closeNode();
|
||||
},
|
||||
},
|
||||
serializeNode: {
|
||||
html_block: (state, node) => {
|
||||
state.renderContent(node);
|
||||
state.write("\n\n");
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default extension;
|
@ -3,6 +3,7 @@ import codeBlock from "./code-block";
|
||||
import emoji from "./emoji";
|
||||
import hashtag from "./hashtag";
|
||||
import heading from "./heading";
|
||||
import htmlBlock from "./html-block";
|
||||
import htmlInline from "./html-inline";
|
||||
import image from "./image";
|
||||
import link from "./link";
|
||||
@ -31,6 +32,7 @@ const defaultExtensions = [
|
||||
strikethrough,
|
||||
underline,
|
||||
htmlInline,
|
||||
htmlBlock,
|
||||
table,
|
||||
markdownPaste,
|
||||
];
|
||||
|
@ -0,0 +1,38 @@
|
||||
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 - html block extension",
|
||||
function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
Object.entries({
|
||||
"unclosed html block": [
|
||||
"<div>Hello World\n\n",
|
||||
'<pre class="html-block"><code><div>Hello World</code></pre>',
|
||||
"<div>Hello World\n\n",
|
||||
],
|
||||
"html block with attributes": [
|
||||
'Hey\n\n<div class="test">Hello World</div>\nYou',
|
||||
'<p>Hey</p><pre class="html-block"><code><div class="test">Hello World</div>\nYou</code></pre>',
|
||||
'Hey\n\n<div class="test">Hello World</div>\nYou\n\n',
|
||||
],
|
||||
"html block with multiple lines": [
|
||||
"<div>\n <p>Hello</p>\n <p>World</p>\n</div>",
|
||||
'<pre class="html-block"><code><div>\n <p>Hello</p>\n <p>World</p>\n</div></code></pre>',
|
||||
"<div>\n <p>Hello</p>\n <p>World</p>\n</div>\n\n",
|
||||
],
|
||||
"html block multiple times": [
|
||||
"<div>1</div>\n\nA\n\n<div>2</div>",
|
||||
'<pre class="html-block"><code><div>1</div></code></pre><p>A</p><pre class="html-block"><code><div>2</div></code></pre>',
|
||||
"<div>1</div>\n\nA\n\n<div>2</div>\n\n",
|
||||
],
|
||||
}).forEach(([name, [markdown, html, expectedMarkdown]]) => {
|
||||
test(name, async function (assert) {
|
||||
this.siteSettings.rich_editor = true;
|
||||
await testMarkdown(assert, markdown, html, expectedMarkdown);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user