mirror of
https://github.com/hanzoai/forum.git
synced 2026-09-30 21:51:19 +00:00
This is the first in a series of PRs to introduce a ProseMirror-based WYSIWYM editor experience alongside our current textarea Markdown editor. Behind a hidden site setting, this PR adds a toggle to the composer toolbar, allowing users to switch between the two options. Our implementation builds upon the excellent ProseMirror and its non-core Markdown module, using the module's schema, parsing, and serialization definitions as the base for further Discourse-specific features. An extension API is included to enable further customizations. The necessary extensions to support all Discourse's core and core plugins features **will be implemented in subsequent PRs**. --------- Co-authored-by: David Taylor <[email protected]>
65 lines
1.6 KiB
Plaintext
65 lines
1.6 KiB
Plaintext
import { tracked } from "@glimmer/tracking";
|
|
import { click, render, settled, waitFor } from "@ember/test-helpers";
|
|
import DEditor from "discourse/components/d-editor";
|
|
|
|
export async function testMarkdown(
|
|
assert,
|
|
markdown,
|
|
expectedHtml,
|
|
expectedMarkdown
|
|
) {
|
|
const self = new (class {
|
|
@tracked value = markdown;
|
|
@tracked view;
|
|
})();
|
|
const handleSetup = (textManipulation) => {
|
|
self.view = textManipulation.view;
|
|
};
|
|
|
|
await render(<template>
|
|
<DEditor
|
|
@value={{self.value}}
|
|
@processPreview={{false}}
|
|
@onSetup={{handleSetup}}
|
|
/>
|
|
</template>);
|
|
await click(".composer-toggle-switch");
|
|
|
|
await waitFor(".ProseMirror");
|
|
await settled();
|
|
const editor = document.querySelector(".ProseMirror");
|
|
|
|
// typeIn for contentEditable isn't reliable, and is slower
|
|
const tr = self.view.state.tr;
|
|
// insert a paragraph to enforce serialization
|
|
tr.insert(
|
|
tr.doc.content.size,
|
|
self.view.state.schema.node(
|
|
"paragraph",
|
|
null,
|
|
self.view.state.schema.text("X")
|
|
)
|
|
);
|
|
// then delete it
|
|
tr.delete(tr.doc.content.size - 3, tr.doc.content.size);
|
|
|
|
self.view.dispatch(tr);
|
|
|
|
await settled();
|
|
|
|
const html = editor.innerHTML
|
|
// we don't care about some PM-specifics
|
|
.replace(' class="ProseMirror-selectednode"', "")
|
|
.replace('<img class="ProseMirror-separator" alt="">', "")
|
|
.replace('<br class="ProseMirror-trailingBreak">', "")
|
|
// or artifacts
|
|
.replace('class=""', "");
|
|
|
|
assert.strictEqual(html, expectedHtml, `HTML should match for "${markdown}"`);
|
|
assert.strictEqual(
|
|
self.value,
|
|
expectedMarkdown,
|
|
`Markdown should match for "${markdown}"`
|
|
);
|
|
}
|