如何以编程方式在 CKEditor 5 中的当前位置插入 link
How to programatically insert link at current position in CKEditor 5
在我的应用程序中,我有一个用于创建内部 link 的特定对话框。用户完成填充对话框后,我想以编程方式将生成的 link 插入到编辑器中的当前插入位置。到目前为止,我一直在使用 SummerNote,这很简单:
editor.summernote('createLink', {
text: linkTitle,
url: url
});
在 CKEditor 5 中,我发现了这个方法,它似乎可以满足我的需要:
doc.enqueueChanges(() => {
editor.data.insertContent(content, doc.selection);
});
我的问题是我不知道如何创建这个 "content" 参数。我试图在 HTML 中创建一个 link 并将其传递到那里,但这不起作用。
我也尝试创建一个 LinkElement 的实例,但是 class 似乎不存在于 JS 运行时(我是来自构建的 运行 CKEditor,而不是来自消息来源)。
我不清楚如果不为 CKEditor 编写插件(这在我看来有点矫枉过正)是否可行。
1.0.0-beta 之后(2018 年 3 月):
要将一些数据插入编辑器,只需使用 "change block":
editor.model.change( writer => {
const insertPosition = editor.model.document.selection.getFirstPosition();
writer.insertText( linkText, { linkHref: linkUrl }, insertPosition );
} );
其中 linkText
和 linkUrl
是您应该从自定义 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()
accepts model's DocumentFragment
or Node
(so Element
or Text
– 我刚刚注意到 API 文档中缺少此信息)。
不幸的是,现在您需要访问 Element
或 Text
的构造函数才能创建它们。这意味着您需要 build CKEditor 5 from source instead of using existing builds. This isn't hard, but it's indeed an overkill. Therefore, we're working now on 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 );
} );
}
在我的应用程序中,我有一个用于创建内部 link 的特定对话框。用户完成填充对话框后,我想以编程方式将生成的 link 插入到编辑器中的当前插入位置。到目前为止,我一直在使用 SummerNote,这很简单:
editor.summernote('createLink', {
text: linkTitle,
url: url
});
在 CKEditor 5 中,我发现了这个方法,它似乎可以满足我的需要:
doc.enqueueChanges(() => {
editor.data.insertContent(content, doc.selection);
});
我的问题是我不知道如何创建这个 "content" 参数。我试图在 HTML 中创建一个 link 并将其传递到那里,但这不起作用。
我也尝试创建一个 LinkElement 的实例,但是 class 似乎不存在于 JS 运行时(我是来自构建的 运行 CKEditor,而不是来自消息来源)。
我不清楚如果不为 CKEditor 编写插件(这在我看来有点矫枉过正)是否可行。
1.0.0-beta 之后(2018 年 3 月):
要将一些数据插入编辑器,只需使用 "change block":
editor.model.change( writer => {
const insertPosition = editor.model.document.selection.getFirstPosition();
writer.insertText( linkText, { linkHref: linkUrl }, insertPosition );
} );
其中 linkText
和 linkUrl
是您应该从自定义 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()
accepts model's DocumentFragment
or Node
(so Element
or Text
– 我刚刚注意到 API 文档中缺少此信息)。
不幸的是,现在您需要访问 Element
或 Text
的构造函数才能创建它们。这意味着您需要 build CKEditor 5 from source instead of using existing builds. This isn't hard, but it's indeed an overkill. Therefore, we're working now on 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 );
} );
}