如何以编程方式在 CKEditor 5 的当前位置插入链接

Posted

技术标签:

【中文标题】如何以编程方式在 CKEditor 5 的当前位置插入链接【英文标题】:How to programatically insert link at current position in CKEditor 5 【发布时间】:2018-05-16 14:38:48 【问题描述】:

在我的应用程序中,我有一个特定的对话框来创建内部链接。用户完成填写对话框后,我想以编程方式将生成的链接插入到编辑器中的当前插入符号位置。到目前为止,我一直在使用 SummerNote,而且很简单:

editor.summernote('createLink', 
     text: linkTitle,
     url: url
);

在 CKEditor 5 中,我发现这种方法似乎可以满足我的需求:

doc.enqueueChanges(() => 
    editor.data.insertContent(content, doc.selection);
);

我的问题是我不知道如何创建这个“内容”参数。我试图在 html 中创建一个链接并将其传递给那里,但这不起作用。

我还尝试创建LinkElement 的实例,但该类在 JS 运行时中似乎不存在(我正在从构建运行 CKEditor,而不是从源代码)。

如果不为 CKEditor 编写插件,我不清楚这是否可能(这在我看来有点过头了)。

【问题讨论】:

【参考方案1】:

1.0.0-beta(2018 年 3 月)之后:

要将一些数据插入编辑器,只需使用“更改块”:

editor.model.change( writer => 
    const insertPosition = editor.model.document.selection.getFirstPosition();
    writer.insertText( linkText,  linkHref: linkUrl , insertPosition );
 );

其中 linkTextlinkUrl 是您应该从自定义 UI 中提供的变量。

以上内容适用于折叠选择。链接的文本将插入到插入符号位置。

1.0.0-beta 版中引入的最大区别是我们在 change() 调用中提供了 writer 对象,因此您不需要(也不应该)直接使用框架类构造函数。

您也可以按照您建议的方式使用editor.model.insertContent

editor.model.change( writer => 
    const linkedText = writer.createText( linkText,  linkHref: linkUrl  );
    editor.model.insertContent( linkedText, editor.model.document.selection );
 );

如果选择没有折叠,这也可以正常工作,因为insertContent 做的更多(例如,如果选择没有折叠并且在两个段落之间,则选择内容将被删除并合并段落)。

1.0.0-beta 之前

DataController#insertContent() 接受模型的 DocumentFragmentNode(所以 ElementText - 我刚刚注意到 API 文档中缺少此信息)。 p>

不幸的是,现在您需要访问ElementText 的构造函数才能创建它们。这意味着您需要build CKEditor 5 from source 而不是使用现有的构建。这并不难,但确实是矫枉过正。因此,我们现在正在开发exposing a sufficient part of the API in the existing classes,这样您就可以编写类似这样的简单集成代码,而无需在您的应用中构建 CKEditor 5。

无论如何,如果您要配置 webpack(或简单地 fork 现有构建),您可以编写一个简单的函数来插入链接文本:

import Text from '@ckeditor/ckeditor5-engine/src/model/text';

function insertLink( linkText, linkHref ) 
    const text = new Text( linkText,  linkHref  );

    editor.document.enqueueChanges( () => 
        editor.data.insertContent( text, editor.document.selection );
     );

【讨论】:

我正在使用上面的“之后”版本。问题是,如果这是我在文档上做的第一件事,光标不会移动到插入内容的末尾。但是,如果我移动光标一次,那么进一步的插入确实会移动光标。我错过了什么? 我们也应该做 editor.editing.view.focus() 吗?这表明应该在菜单操作之后完成(由于菜单选项而插入)。 您可以在菜单中的mousedown 上使用editor.editing.view.focus() 和/或evt.preventDefault()。 CKEditor 5 的按钮同时用于处理在单击项目之前编辑器中没有焦点的情况。 seleciton的问题,可能与焦点问题有关。但是 IDK——你需要做一个演示。 您是否有一个类似的示例来说明如何插入一个 html 字符串,以便像用户粘贴它一样处理它?示例:'Some bolded text',在您的示例中,它以文字字符串的形式输入,实际上并没有加粗文本。

以上是关于如何以编程方式在 CKEditor 5 的当前位置插入链接的主要内容,如果未能解决你的问题,请参考以下文章

如何将(以编程方式)谷歌字体添加到 ckeditor

如何以编程方式获取设备的当前地理位置

当我进入Source视图时,如何跳转到CKEditor 4中的当前位置?

如何在UWP中以编程方式在设置中打开位置服务?

Android:我可以通过多少种方式以编程方式获取当前位置

如何以编程方式在 Android 的 API 23 及更高版本中获取位置(纬度、经度)?