想象一下,我们有 WISYWIG/Markdown 编辑器,可以在此处的官方示例中切换模式。
请注意,当您切换模式时,它不会保留您的插入符号/滚动/选择。如果我们要进一步改进它的用户体验,我们需要在切换模式时保持插入符号的位置。
问题是 WISYWIG 中的光标位置,比如:“foo b|ar ”是“5”,而在原始降价位置将是“foo **b|ar**” - “7”。
在切换模式时,这些位置如何前后投射?
如果我们解决位置投影问题,“滚动”和“选择”同步只是需要做一些微调。
想象一下,我们有 WISYWIG/Markdown 编辑器,可以在此处的官方示例中切换模式。
请注意,当您切换模式时,它不会保留您的插入符号/滚动/选择。如果我们要进一步改进它的用户体验,我们需要在切换模式时保持插入符号的位置。
问题是 WISYWIG 中的光标位置,比如:“foo b|ar ”是“5”,而在原始降价位置将是“foo **b|ar**” - “7”。
在切换模式时,这些位置如何前后投射?
如果我们解决位置投影问题,“滚动”和“选择”同步只是需要做一些微调。
我找到了这个问题的解决方案:我们只需要用一些非常特殊的符号标记目标位置,通过转换器并找到这个标记现在的位置。它是相对简单、稳健且直接的解决方案。
import {schema, defaultMarkdownParser,
defaultMarkdownSerializer} from "prosemirror-markdown"
import {Node, Slice, Fragment} from 'prosemirror-model';
// We need a special symbol which is likely not used in text
const MARKER = '█';
function projectToProsemirror(mdText: string, position: number): number {
const withMarker = mdText.substr(0, position) + MARKER + mdText.substr(position);
const node = defaultMarkdownParser.parse(withMarker);
return node.textContent.indexOf(MARKER);
}
function projectToMarkdown(node: Node, position: number): number {
const pos = node.resolve(position + 1 /* prosemirror counts position from "1" */);
const marker = Fragment.from(schema.text(MARKER, pos.marks()));
const withMarker = node.replace(pos.pos, pos.pos, new Slice(marker, 0, 0));
const markdown = defaultMarkdownSerializer.serialize(withMarker);
return markdown.indexOf(MARKER);
}
projectToProsemirror('some **formatted** text', 8); // = 6