URL dialog 是一种特殊的 TinyMCE UI 组件,它会在一个对话框(有时称为 modals)内加载外部网页。URL dialog 适用于非常复杂的用例,在这类场景中无法使用 TinyMCE 标准对话框所支持的组件。例如,要在 TinyMCE 对话框中加载自定义文件管理器,可能就需要使用 URL dialog。
标准 TinyMCE 对话框适用于大多数用例,并且配置起来可能更简单。
基础示例
基础 URL dialog 的配置可能如下所示:
tinymce.activeEditor.windowManager.openUrl({
title: 'Just a title',
url: 'http://www.tiny.cloud/example.html'
});URL dialog 配置
URL Dialog 配置由三部分组成,分别对应对话框 UI 的三个主要部分:
标题:对话框的标题。该标题会显示在对话框的头部。
URL:要在对话框内加载的外部页面的 URL。
按钮:(可选)一个底部按钮数组,显示在对话框的底部。
选项
| 名称 | 值 | 是否必填 | 说明 |
|---|---|---|---|
title | string | 必填 | 对话框的标题。 |
url | string | 必填 | 要加载的外部页面的 URL。 |
width | number | 可选 | 对话框的宽度(以像素为单位)。 |
height | number | 可选 | 对话框的高度(以像素为单位)。 |
buttons | FooterButton[] | 可选 | 要在对话框底部渲染的按钮数组。 |
onAction |
| 可选 | 当点击 Custom 类型的底部按钮时调用的函数。 |
onCancel |
| 可选 | 当取消对话框时调用的函数。对话框头部的关闭按钮以及 Cancel 类型的底部按钮都会调用此函数。 |
onClose |
| 可选 | 当关闭对话框时调用的函数。对话框头部的关闭按钮、Cancel 类型的底部按钮以及对话框实例 API 的 |
onMessage |
| 可选 | 当从外部页面收到消息时调用的函数。 |
有关传递给某些配置选项的 dialogApi 对象的更多信息,请参见 URL dialog instance API 文档。
底部按钮
按钮是一个可点击的组件,可以包含文本或图标。按钮有两种类型(主要按钮和次要按钮),区别仅在于样式不同。主要按钮旨在更加醒目。其颜色取决于所选的 skin。
配置
| 名称 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
type |
| 必填 | 必须为 |
text | string | 必填 | 当未指定 |
name | string | 可选 | 按钮的标识符。如果未指定,则会为按钮分配一个随机生成的 |
icon | string | 可选 | 要显示的图标的名称。必须对应一个图标:位于 icon pack 中、位于 自定义 icon pack 中,或通过 |
buttonType |
| 可选 | 默认值: |
enabled | boolean | 可选 | 默认值: |
align |
| 可选 | 默认值: |
目前按钮不支持同时混合使用图标和文本。
按钮类型与事件回调
不同类型的底部按钮在点击时会触发不同的回调函数:
-
Cancel 类型按钮会触发对话框配置中提供的
onCancel和onClose回调函数。当用户点击对话框右上角的X按钮时,也会触发这些回调函数。 -
Custom 类型按钮会触发对话框配置中提供的
onAction回调函数,并将按钮的name作为参数传递给details对象。这使得开发者能够为对话框中每个 Custom 类型的底部按钮创建点击处理程序。有关如何在标准对话框中使用此功能的示例,请参见 Redial 示例。
与 标准对话框不同,URL 对话框没有 Submit 类型的底部按钮,因此也没有 onSubmit 回调函数。有关事件回调的更多信息,请参阅 URL 对话框配置选项文档。
URL 对话框实例 API
当创建一个 URL 对话框时,会返回一个对话框实例 API。例如:const instanceApi = editor.windowManager.openUrl(config);。URL 对话框 API 实例也会传递给某些对话框配置选项。
实例 API 是一个 JavaScript 对象,包含附加到对话框实例的方法。当对话框关闭时,实例 API 会被销毁。
实例 API 方法
| 方法 | 描述 |
|---|---|
|
| 调用 |
|
| 调用 |
|
| 调用 |
|
| 调用 |
URL 对话框消息传递
当使用 URL 对话框时,由于 TinyMCE 和外部页面不再运行在同一个窗口中,因此需要一种方式在它们之间进行通信。为了实现这一点,TinyMCE 使用了浏览器的 window.postMessage() API,允许跨不同源发送数据。以下是一个如何从外部页面向 TinyMCE 发送消息的示例:
window.parent.postMessage({
mceAction: 'insertContent',
content: 'Some content'
}, '*');同样,要从 TinyMCE 向外部页面发送消息,可以使用 URL 对话框实例 API 中的 sendMessage() 函数发送消息,然后在外部页面添加事件监听器以接收消息:
window.addEventListener('message', (event) => {
var data = event.data;
// 对这里接收到的数据进行处理
console.log('message received from TinyMCE', data);
});发送消息时,建议指定 TinyMCE 运行的目标源,而不是使用通配符 ('*')。同样,在接收消息时,请检查event.origin是否与 TinyMCE 运行的源匹配。例如,如果 TinyMCE 运行在 http://mysite.com/tinymce.html,那么如果event.origin不匹配http://mysite.com,则应忽略该消息。
支持的消息操作
这些操作内置于 URL 对话框功能中,并根据指定的 mceAction 在编辑器内执行操作。支持的操作有:
insertContent
此操作将内容插入到编辑器中当前选中的位置。content 属性指定要插入到编辑器中的内容。
{
mceAction: 'setContent',
content: 'My custom content'
}setContent
此操作用于设置编辑器的内容。content 属性指定要在编辑器中设置的内容。
{
mceAction: 'setContent',
content: 'My custom content'
}execCommand
此操作在编辑器中执行命令。此操作可用的选项有:
-
cmd:要在编辑器中执行的命令名称。 -
ui:一个可选的布尔值,用于指定是否呈现 UI(对话框)。 -
value:一个可选的值,供命令使用。
{
mceAction: 'execCommand',
cmd: 'mceInsertLink',
value: 'https://www.tiny.cloud'
}close
此操作会关闭打开的 URL 对话框。这与使用 api.close() 函数相同。
{
mceAction: 'close'
}block
此操作会禁用整个对话框窗口并显示加载图片。这与使用 api.block(message) 函数相同。
{
mceAction: 'block',
message: 'Loading…'
}unblock
此操作会解除窗口/对话框的阻止。这与使用 api.unblock() 函数相同。
{
mceAction: 'unblock'
}Custom message actions
自定义消息是指包含未在上述支持操作中列出的 mceAction 的消息。例如,以下代码片段可用于向 TinyMCE 发送消息,然后通过 onMessage 回调进行处理,以在 TinyMCE 内部执行自定义操作。
{
mceAction: 'customAction',
data: {
customField: 'custom value'
}
}TinyMCE 会忽略所有不包含 mceAction 属性的接收消息。Interactive example
此示例展示了一个工具栏按钮,该按钮会在 640 像素×640 像素的对话框中打开外部 URL,且没有任何页脚按钮。通过点击 {;} 工具栏按钮可以打开该对话框。
HTML
<textarea id="url-dialog">
<p>Click on the custom {;} toolbar button.</p>
</textarea>JS
tinymce.init({
selector: 'textarea#url-dialog',
toolbar: 'urldialog',
height: 300,
setup: (editor) => {
editor.ui.registry.addButton('urldialog', {
icon: 'code-sample',
onAction: () => editor.windowManager.openUrl({
title: 'URL Dialog Demo',
url: 'external-page.html',
height: 640,
width: 640
})
})
},
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});