此插件仅作为 付费附加组件 提供,需配合 TinyMCE 订阅 使用。
Revision History 插件让用户能够查看文档随时间的变化,并轻松恢复之前的版本。
交互示例
HTML
<textarea id="revisionhistory">
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<h2 style="text-align: center;">Welcome to the TinyMCE Revision History demo!</h2>
<p style="text-align: center;">Try out the Revision History feature by typing in the editor and then clicking the Revision History icon in the toolbar.</p>
<p style="text-align: center;">And visit the <a href="https://www.tiny.cloud/pricing">pricing page</a> to learn more about our Premium plugins.</p>
<h2>A simple table to play with</h2>
<table style="border-collapse: collapse; width: 100%;" border="1">
<thead>
<tr style="text-align: left;">
<th>Product</th>
<th>Cost</th>
<th>Really?</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">TinyMCE Cloud</td>
<td style="text-align: center;">Get started for free</td>
<td style="text-align: center;"><strong>Yes!</strong></td>
</tr>
</tbody>
</table>
<h2>Got questions or need help?</h2>
<ul>
<li>Our <a class="mceNonEditable" href="https://www.tiny.cloud/docs/tinymce/latest/">documentation</a> is a great resource for learning how to configure TinyMCE.</li>
<li>Have a specific question? Try the <a href="https://stackoverflow.com/questions/tagged/tinymce" target="_blank" rel="noopener"><code>tinymce</code> tag at Stack Overflow</a>.</li>
<li>We also offer enterprise grade support as part of <a href="https://www.tiny.cloud/pricing">TinyMCE premium subscriptions</a>.</li>
</ul>
<h2>Found a bug?</h2>
<p>If you think you have found a bug please create an issue on the <a href="https://github.com/tinymce/tinymce/issues">GitHub repo</a> to report it to the developers.</p>
<h2>Finally …</h2>
<p>Need file uploads in your app? Consider using <a href="https://www.tiny.cloud/docs/tinymce/latest/uploadcare/" target="_blank" rel="noopener noreferrer">Uploadcare</a> with TinyMCE for a fast, modern upload experience.</p>
<p>Thanks for supporting TinyMCE! We hope it helps you and your users create great content.</p>
<p>All the best from the TinyMCE team.</p>
</textarea>JS
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
const fakeDelay = 200;
const revisions = [
{
revisionId: '3',
createdAt: '2023-11-24T22:26:21.578Z',
author: {
id: 'james-wilson',
name: 'James Wilson',
avatar: 'https://sneak-preview.tiny.cloud/demouserdirectory/images/employee_james-wilson_128_52f19412.jpg',
},
metadata: { source: 'ai' },
content: `
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<h2 style="text-align: center;">欢迎使用 TinyMCE 编辑器演示!</h2>
<h2>一个可供操作的简单表格</h2>
<table style="border-collapse: collapse; width: 100%;" border="1">
<thead>
<tr>
<th>产品</th>
<th>成本</th>
<th>真的吗?</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">TinyMCE</td>
<td style="text-align: center;">免费</td>
<td style="text-align: center;">是的!</td>
</tr>
</tbody>
</table>
<h2>发现了 Bug?</h2>
<p>如果您认为发现了 Bug,请在 <a href="https://github.com/tinymce/tinymce/issues">GitHub 仓库</a> 上创建一个 issue 向开发人员报告。</p>
<h2>最后...</h2>
<p><s>您的应用需要文件上传功能吗?考虑将 <a href="https://www.tiny.cloud/docs/tinymce/latest/uploadcare/" target="_blank" rel="noopener noreferrer">Uploadcare</a> 与 TinyMCE 结合使用,以获得快速、现代的上传体验。</s></p>
<p>感谢您支持 TinyMCE!我们希望它能帮助您和您的用户创建出色的内容。<br>来自 TinyMCE 团队的诚挚问候。</p>
`,
},
{
revisionId: '2',
createdAt: '2023-11-25T08:30:21.578Z',
author: {
id: 'mia.andersson',
name: 'Mia Andersson',
avatar: 'https://sneak-preview.tiny.cloud/demouserdirectory/images/employee_mia-andersson_128_e6f9424b.jpg',
},
content: `
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<h2 style="text-align: center;">欢迎使用 TinyMCE 编辑器演示!</h2>
<h2>有问题或需要帮助?</span></h2>
<ol>
<li>我们的 <a href="../">文档</a> 是学习如何配置 TinyMCE 的绝佳资源。</li>
<li>有具体问题?试试在 Stack Overflow 上使用 <a href="https://stackoverflow.com/questions/tagged/tinymce" target="_blank" rel="noopener"><code>tinymce</code> 标签</a>。</li>
<li>作为 <a href="../../../../pricing">TinyMCE 高级计划</a> 的一部分,我们还提供企业级支持。</li>
</ol>
<h2>一个可供操作的简单表格</h2>
<table style="border-collapse: collapse; width: 100%;" border="1">
<thead>
<tr>
<th>产品</th>
<th>成本</th>
<th>真的吗?</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">TinyMCE</td>
<td style="text-align: center;">免费</td>
<td style="text-align: center;">是的!</td>
</tr>
</tbody>
</table>
<h2>发现了 Bug?</h2>
<p>如果您认为发现了 Bug,请在 <a href="https://github.com/tinymce/tinymce/issues">GitHub 仓库</a> 上创建一个 issue 向开发人员报告。</p>
<h2>最后...</h2>
<p>您的应用需要文件上传功能吗?考虑将 <a href="https://www.tiny.cloud/docs/tinymce/latest/uploadcare/" target="_blank" rel="noopener noreferrer">Uploadcare</a> 与 TinyMCE 结合使用,以获得快速、现代的上传体验。</p>
<p>感谢您支持 TinyMCE!我们希望它能帮助您和您的用户创建出色的内容。<br>来自 TinyMCE 团队的诚挚问候。</p>
`,
},
{
revisionId: '1',
createdAt: '2023-11-29T10:11:21.578Z',
author: {
id: 'mia.andersson',
name: 'Mia Andersson',
avatar: 'https://sneak-preview.tiny.cloud/demouserdirectory/images/employee_mia-andersson_128_e6f9424b.jpg',
},
content: `
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<h2 style="text-align: center;">欢迎使用 TinyMCE 编辑器演示!</h2>
<h2>有问题或需要帮助?</h2>
<ul>
<li>我们的 <a href="../">文档</a> 是学习如何配置 TinyMCE 的绝佳资源。</li>
<li>有具体问题?试试在 Stack Overflow 上使用 <a href="https://stackoverflow.com/questions/tagged/tinymce" target="_blank" rel="noopener"><code>tinymce</code> 标签</a>。</li>
<li>作为 <a href="../../../../pricing">TinyMCE 高级计划</a> 的一部分,我们还提供企业级支持。</li>
</ul>
<h2>一个可供操作的简单表格</h2>
<table style="border-collapse: collapse; width: 100%;" border="1">
<thead>
<tr>
<t如果您认为发现了一个 bug,请在 GitHub 仓库 上创建一个 issue 向开发者报告。
最后……
您的应用需要文件上传功能吗?考虑使用 Uploadcare 与 TinyMCE 配合使用,以获得快速、现代的上传体验。
感谢您支持 TinyMCE!希望它能帮助您和您的用户创建优质内容。来自 TinyMCE 团队的诚挚问候。
`,
}
];
const revisionhistory_fetch = () => new Promise((resolve) => {
setTimeout(() => {
const sortedRevisions = revisions
.sort((a, b) => new Date(a.createdAt) < new Date(b.createdAt) ? -1 : 1);
resolve(sortedRevisions);
}, fakeDelay);
});
const revisionhistory_fetch_revision = (_editor, revision) => new Promise((resolve, reject) => {
setTimeout(() => {
const revision = revisions.find((r) => r.revisionId === revision.revisionId);
if (revision) {
resolve(revision);
} else {
reject(`Revision ${revision.revisionId} is not found`);
}
}, fakeDelay);
});
tinymce.init({
selector: 'textarea#revisionhistory',
height: 800,
plugins: 'revisionhistory help code link lists image',
toolbar: 'undo redo | styles | bold italic underline | revisionhistory | link image | code',
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
revisionhistory_fetch,
revisionhistory_fetch_revision,
revisionhistory_display_author: true,
user_id: 'kai-nakamura',
fetch_users: (userIds) => Promise.all(userIds
.map((userId) =>
fetch(`${API_URL}/${userId}`)
.then((response) => response.json())
.catch(() => ({ id: userId })))),
});此功能仅在 TinyMCE 以 classic 模式运行时支持,在 inline 模式下不支持。有关编辑模式差异的更多信息,请参阅 Classic editing mode。
工作原理
可通过 revisionhistory 工具栏按钮或 View 菜单中的菜单按钮访问 Revision History 视图。
主要组件包括:
在 Revision History 视图的标题栏中,有两个按钮。
Restore this version:将所选 revision 的内容设置为编辑器内容并关闭视图。注意:对于initial和draftrevision,此按钮将被禁用。Close:关闭 Revision History 视图。
只读 diff 视图显示所选 revision 与其前一个 revision 之间的差异,并通过清晰高亮便于识别。差异内容还通过颜色编码加以区分:
红色:已删除内容。
绿色:新增内容。
黄色:正在修改的内容。对 HTML 内容的修改意味着属性或格式(如粗体、斜体等)的更改。
revision 侧边栏显示所有可用的文档 revision。当选择一个 revision 时,diff 视图会相应更新。
可通过 revisionhistory_css_url 选项自定义默认的高亮颜色。Revision History 插件会将注释的 HTML 视为有效内容,但在 revision 比较过程中会忽略它们。仅包含注释内容的 revision 在视图中显示为空。
基本设置
要在编辑器中设置 Revision History 插件:
将
revisionhistory添加到编辑器配置的plugins选项中;将
revisionhistory添加到编辑器配置的toolbar选项中;将
revisionhistory_fetch选项添加到编辑器配置中;
例如:
tinymce.init({
selector: 'textarea', // 根据您的 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]), // 将此替换为获取已保存 revision 的 API 请求
});有关将此插件与模块打包工具捆绑的信息,请参阅 Bundling TinyMCE - Overview。
了解 revision 类型
Revision History 插件提供三种 revision 类型:
Initial:此 revision 在 TinyMCE 的
Loaded事件期间生成,捕获编辑器的初始内容。Draft:在打开 Revision History 时生成,此 revision 反映编辑器当前的内容。若包含此 revision,它将成为 revision 列表中的
latest revision。Saved:这些 revision 在打开 Revision History 视图时通过
revisionhistory_fetch和revisionhistory_fetch_revision选项从客户端存储中获取。
当处理一个没有保存修订版本的文档时,Revision History 插件通常会维护两个修订版本:initial 和 draft。如果在初始化后没有对内容进行任何更改,则 initial 修订版本不会显示,因为它与 draft 修订版本相同。
对于已保存修订版本的文档,initial 修订版本会被忽略,假设它已存在于已保存的修订版本中。若要包含初始内容,请使用 revisionhistory_fetch 选项将其添加为修订版本。
数据结构
修订版本(Revision)
修订版本是一个 Object,包含以下字段:
| 字段 | 类型 | 是否必需? | 描述 |
|---|---|---|---|
|
| 必需 | 修订版本的唯一字符串 ID。 |
|
| 必需 | ISO-8061 格式的 UTC 日期时间字符串。 |
|
| 可选 | 修订版本内容的 HTML 字符串。空字符串被视为有效内容。 |
| 作者 | 可选 | 修订版本的作者。 |
| 元数据 | 可选 | 关于修订版本的附加信息,例如是否为 AI 辅助生成,以及修订版本卡片上显示哪些标签。 |
作者(Author)
作者是一个 Object,表示修订版本的作者或创建者。它包含以下字段:
| 字段 | 类型 | 是否必需? | 描述 |
|---|---|---|---|
|
| 必需 | 作者的唯一字符串 ID。 |
|
| 可选 | 修订版本作者的姓名。如果未提供,默认值为 |
|
| 可选 | 作者头像图像的 URL。如果未提供或无效,Revision History 将使用作者姓名首字母生成头像。 |
元数据(Metadata)
元数据是一个 Object,用于保存关于修订版本的附加信息。它包含以下字段:
| 字段 | 类型 | 是否必需? | 描述 |
|---|---|---|---|
|
| 可选 | 修订版本内容的来源。值为 |
| 标签 | 可选 | 在修订版本卡片上显示的标签。每个标签显示为一个标签,样式与修订版本类型标签(如 |
标签(Tag)
标签是一个 Object,表示修订版本卡片上显示的标签。它包含以下字段:
| 字段 | 类型 | 是否必需? | 描述 |
|---|---|---|---|
|
| 必需 | 标签的文本。插件将原样显示该文本,不会更改大小写。 |
以下示例定义了一个包含两个标签的已保存修订版本:
const revision = {
revisionId: '3',
createdAt: '2026-10-14T10:11:21.578Z',
content: '<p>Approved content.</p>',
metadata: {
tags: [
{ label: 'REVIEWED' },
{ label: 'Legal' }
]
}
};标签仅显示在 saved 修订版本上。draft 和 initial 修订版本由编辑器当前内容生成,不携带 metadata。参见《了解修订版本类型》。
标记 AI 辅助修订版本
通过 metadata 对象的 source 字段可将修订版本标识为 AI 辅助生成。当 metadata.source 为 'ai' 时,默认会在该修订版本卡片上显示 AI 徽章。将 revisionhistory_ai_attribution 设置为 false 可隐藏该徽章。
Revision History 插件不会自动设置此标记。相反,应用程序必须监听内容事件,并保存每个带有该标记的修订版本。TinyMCE AI 插件会在插入内容时,在 BeforeSetContent 和 SetContent 事件中将 ai 设置为 true,因此任一事件都可作为 AI 参与的信号:
BeforeSetContent在 AI 内容插入前立即触发。此时调用editor.getContent()将返回 AI 编辑前的内容。SetContent在 AI 内容插入后立即触发。此时调用editor.getContent()将返回 AI 生成的结果。
这两种事件都可以驱动内容归属追踪,并且可以同时使用。具体监听哪种事件取决于应用程序所需的细化程度。每次修订(revision)涵盖了自上次修订以来所有变更内容,因此仅监听单个事件生成的修订可能会同时包含 AI 生成内容和人工编辑内容:
仅监听
BeforeSetContent会保存自上次修订以来的人工编辑内容,以及此前的 AI 编辑内容。仅监听
SetContent会保存 AI 编辑内容,以及此前的人工编辑内容。同时监听两种事件则会将二者分开,分别保存每次 AI 编辑之前的内容状态以及 AI 生成的结果作为不同的修订版本。
如果目标是在内容发生任何变更时都保存修订版本,那么监听其中任一事件均可。如果必须区分 AI 生成内容和人工编辑内容,则需要同时监听这两个事件。要确保内容归属的准确性,需执行以下三个步骤:
检测:监听
BeforeSetContent、SetContent或二者,并检查ai属性是否为true。这两种事件在非 AI 插件引起的内容变更时也会触发,因此该检查可确保无关的变更不会归入带有归属标记的修订版本中。保存:当检查通过时,保存一个修订版本,并将
metadata.source设置为'ai',以标记该内容由 AI 生成。还原:当还原某个修订版本时,需保存该版本并保留其归属标记,以确保还原后的内容仍能正确标记归属。
AI 徽标仅在saved修订版本中显示。draft和initial修订版本由编辑器当前内容生成,不包含metadata,因此即使内容有 AI 辅助,也不会显示徽标。详见 Understanding revision types。
保存 AI 辅助修订版本
应用程序负责保存修订版本,并通过 revisionhistory_fetch 选项返回这些版本。以下示例同时监听两种事件,并使用一个共享的辅助函数来创建当前内容的快照,当其 aiAssisted 参数为 true 时,将该修订版本标记为 AI 辅助。BeforeSetContent 会将每次 AI 编辑之前的内容保存为单独的修订版本,而 SetContent 则保存 AI 生成的结果:
// 在将当前内容快照保存为修订版本时调用此函数。
const saveRevision = (aiAssisted) => {
const revision = {
revisionId: createRevisionId(), // Replace with your ID generation
createdAt: new Date().toISOString(),
content: editor.getContent(),
// 当内容来自 AI 插件时,标记该修订版本为 AI 辅助。
...(aiAssisted ? { metadata: { source: 'ai' } } : {})
};
saveToStorage(revision); // Replace with your storage call
};
// 在 TinyMCE AI 插件插入编辑内容之前,保存 AI 编辑前的(人工)内容。
editor.on('BeforeSetContent', (e) => {
if (e.ai) {
saveRevision(false);
}
});
// 保存 AI 编辑后的内容,并标记为 AI 辅助。
editor.on('SetContent', (e) => {
if (e.ai) {
saveRevision(true);
}
});如果仅通过单个事件驱动内容归属,则只保留所需的监听器。此方式生成的修订版本会包含 AI 生成内容和人工编辑内容,具体见 Attributing AI-assisted revisions 中的描述。
还原 AI 辅助修订版本
还原修订版本时,会将其内容重新设置到编辑器中,并触发 VersionRestored 事件。还原后的内容不会被标记为 AI 辅助,因此需查找被还原的修订版本,并使用如 Saving an AI-assisted revision 中所示的 saveRevision() 辅助函数保存该版本并保留其归属标记:
editor.on('VersionRestored', (e) => {
const restored = getFromStorage(e.revisionId); // Replace with your storage lookup
// 保留归属信息,使还原的内容保留其标记。
saveRevision(restored?.metadata?.source === 'ai');
});选项
以下配置选项影响 Revision History 插件的行为。
revisionhistory_fetch
revisionhistory_fetch 函数用于检索已保存的修订版本,并在用户打开修订历史视图时调用。
Revision History 插件正常运行需要 revisionhistory_fetch 函数。它预期为一个异步函数,返回一个 Promise,该 Promise 解析为修订版本数组。
Revision History 插件在显示之前不会对结果进行排序,允许集成人员根据自己的偏好对结果进行排序。Tiny 建议按时间倒序排列结果,这样用户更容易根据日期识别修订版本。
类型: Function(返回一个 Promise)
输入参数: 无
返回数据: Revision Objects 数组
示例:revisionhistory_fetch 响应
const revisions = [
{
revisionId: '3',
createdAt: '2023-11-29T10:11:21.578Z',
content: `
<h2>欢迎使用 TinyMCE 文档!</h2>
<p>这里是一些内容,这些内容<strong>加粗</strong>且<em>倾斜</em>。</p>
`,
},
{
revisionId: '2',
createdAt: '2023-11-25T08:30:21.578Z',
content: `
<p>欢迎使用 TinyMCE 文档!</p>
<p>这里是一些内容,这些内容加粗且倾斜。</p>
`,
},
{
revisionId: '1',
createdAt: '2023-11-24T22:26:21.578Z',
content: `
<p>欢迎使用 Tinymce!</p>
`,
}
];示例:使用 revisionhistory_fetch
tinymce.init({
selector: 'textarea', // 根据你的 HTML 修改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () =>
fetch('<API URL>') // 根据你的 API 更新 URL 和响应处理代码
.then((response) => response.json())
.then((data) => data)
.catch((error) => console.log('获取修订版本失败\n' + error))
});revisionhistory_fetch_revision
当选择了一个修订版本时,插件会使用此选项来更新所选的或最接近的无内容的修订版本。该函数应返回一个用更新后的修订版本 resolve 的 Promise。
类型: Function(返回一个 Promise)
输入参数:
| 字段 | 类型 | 是否必需? | 描述 |
|---|---|---|---|
|
| 必需 | 当前的编辑器实例(如果页面上有多个编辑器,则此参数很有用)。 |
| 修订版本 | 必需 | 目标修订版本。 |
返回数据: 修订版本 Object
示例:使用 revisionhistory_fetch_revision
const lightRevisions = [ { revisionId: '3', createdAt: '2023-11-29T10:11:21.578Z', }, { revisionId: '2', createdAt: '2023-11-25T08:30:21.578Z', }, { revisionId: '1', createdAt: '2023-11-24T22:26:21.578Z', }];const revisions = [
{
revisionId: '3',
createdAt: '2023-11-29T10:11:21.578Z',
content: `
<h2>欢迎使用 TinyMCE 文档!</h2>
<p>这里是一些内容,这些内容<strong>加粗</strong>且<em>倾斜</em>。</p>
`,
},
{
revisionId: '2',
createdAt: '2023-11-25T08:30:21.578Z',
content: `
<p>欢迎使用 TinyMCE 文档!</p>
<p>这里是一些内容,这些内容加粗且倾斜。</p>
`,
},
{
revisionId: '1',
createdAt: '2023-11-24T22:26:21.578Z',
content: `
<p>欢迎使用 Tinymce!</p>
`,
}
];tinymce.init({ selector: 'textarea', // 根据你的 HTML 修改此值 plugins: 'revisionhistory', toolbar: 'revisionhistory', revisionhistory_fetch: () => Promise.resolve(lightRevisions), revisionhistory_fetch_revision: (_editor, revision) => new Promise((resolve) => { let newRevision = null; for (let i = 0; i < revisions.length; i++) { const temp = revisions[i]; if (temp.revisionId === revision.revisionId) { newRevision = temp; break; } } resolve(newRevision); })});revisionhistory_allow_restore
revisionhistory_allow_restore 选项启用或禁用恢复修订版本的功能。
类型: Boolean
默认值: true
可能的值: true、false
示例:使用 revisionhistory_allow_restore
tinymce.init({
selector: 'textarea', // 根据你的 HTML 修改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]), // 插件的必需选项 - 请用实际的 API 请求替换
revisionhistory_allow_restore: false
});user_id
此选项设置编辑器中当前用户的唯一标识符。它用于 UserLookup API。
类型: String
默认值: 'Anonymous'
user_id 选项tinymce.init({
selector: 'textarea', // 根据你的 HTML 修改此值
user_id: 'james-wilson' // 用一个唯一的字符串替换它以标识用户
});fetch_users
一个必需的回调函数,用于获取用户数据。此函数使用一个用户 ID 数组调用,并应返回一个 Promise,该 Promise 用一个用户对象数组 resolve。UserLookup API 使用此回调。如果返回的数组不包含所有请求的用户 ID,则缺失用户的 promise 将以 “User {id} not found” 错误被 reject。
类型: Function
参数:- ids(Array<string>):要获取的用户 ID 数组。
返回值:- Promise<Array<Object>>:一个解析为用户对象数组的 Promise。
fetch_users 选项const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
tinymce.init({
selector: 'textarea',
user_id: 'james-wilson',
fetch_users: (userIds) => Promise.all(userIds
.map((userId) =>
fetch(`${API_URL}/${userId}`)
.then((response) => response.json())
.catch(() => ({ id: userId })))),
}); 示例:带验证返回用户数组const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
tinymce.init({
selector: 'textarea',
user_id: 'james-wilson',
fetch_users: async (userIds) => {
const users = await Promise.all(userIds
.map((userId) =>
fetch(`${API_URL}/${userId}`)
.then((response) => response.json())
.catch(() => ({ id: userId }))));
return userIds.map(
(userId) =>
users.find((user) => user.id === userId)
|| ({ id: userId }) // 即使服务器未返回用户信息,仍返回有效的用户对象
);
},
});revisionhistory_author
此选项在 TinyMCE 8 中已弃用,可能会在未来的 TinyMCE 主要版本中移除。请改用user_id和fetch_users的组合。 |用户查找 API
此选项配置initial(初始版本)和draft(草稿版本)修订版本的作者。
类型: 作者 Object
示例:使用 revisionhistory_author
tinymce.init({
selector: 'textarea', // 根据 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]),
revisionhistory_display_author: true,
revisionhistory_author: {
id: 'john.doe',
name: 'John Doe',
avatar: 'https://example.com/avatar.jpg'
}
});revisionhistory_display_author
此选项配置修订版本作者的显示。当设置为 true 时,作者姓名会显示在 Revision History 侧边栏的每个修订版本中。如果未提供作者姓名,则默认为匿名。
类型: Boolean
默认值: false
可能的值: true、false
示例:使用 revisionhistory_display_author
tinymce.init({
selector: 'textarea', // 根据 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]),
revisionhistory_display_author: true
});revisionhistory_ai_attribution
此选项控制修订卡片上 AI 徽章的显示。默认情况下,metadata 中 source 设置为 'ai' 的每个修订版本都会显示 AI 徽章。将此选项设置为 false 可隐藏徽章。有关 AI 修订版本归因的详细信息,请参阅 Attributing AI-assisted revisions。
类型: Boolean
默认值: true
可能的值: true、false
示例:使用 revisionhistory_ai_attribution
tinymce.init({
selector: 'textarea', // 根据 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]),
revisionhistory_ai_attribution: false
});revisionhistory_css_url
此选项设置应从中加载包含更改标注样式的 CSS 文件的位置。它可以与 revisionhistory_diff_classes 一起使用,以覆盖默认的 CSS 类。
确保文件包含 revisionhistory_diff_classes 所需的所有 CSS 类。类型: String
默认值: '${pluginUrl}/css/revisionhistory.css'
示例:使用 revisionhistory_css_url
tinymce.init({
selector: 'textarea', // 根据 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]), // 插件的必需选项 - 请替换为实际的 API 请求
revisionhistory_css_url: './revisionhistory.css'
});revisionhistory_diff_classes
此选项配置应用于更改标注的 CSS 类。此选项可与 revisionhistory_css_url 结合使用,以向更改标注提供自定义样式。
CSS 类名必须存在于 revisionhistory_css_url 指定的文件中。类型: Object
默认值: addition、removal、modification
{
addition: 'tox-revisionhistory__annotation--added',
removal: 'tox-revisionhistory__annotation--removed',
modification: 'tox-revisionhistory__annotation--modified'
}示例:使用 revisionhistory_diff_classes
tinymce.init({
selector: 'textarea', // 根据 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]), // 插件必需选项 - 替换为实际 API 请求
revisionhistory_css_url: './revisionhistory.css',
revisionhistory_diff_classes: {
addition: 'added',
removal: 'removed',
modification: 'modified'
}
});在编辑器加载时显示视图
view_show 选项可用于在编辑器加载时显示Revision History(修订历史)视图。
tinymce.init({
selector: 'textarea', // 根据 HTML 更改此值
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
view_show: 'revision',
revisionhistory_fetch: () => Promise.resolve([]), // 替换为获取保存的修订版本的 API 请求
});工具栏按钮
Revision History 插件提供以下工具栏按钮:
| 工具栏按钮标识符 | 描述 |
|---|---|
| 打开 Revision History 视图。 |
这些工具栏按钮可通过以下方式添加到编辑器:
toolbar配置选项。quickbars_insert_toolbar配置选项。
菜单项
Revision History 插件提供以下菜单项:
| 菜单项标识符 | 默认菜单位置 | 描述 |
|---|---|---|
| 视图 | 打开 Revision History 视图。 |
这些菜单项可通过以下方式添加到编辑器:
menu配置选项。contextmenu配置选项。
命令
Revision History 插件提供以下 TinyMCE 命令。
| 命令 | 描述 |
|---|---|
revisionHistory | 切换 Revision History 视图 |
tinymce.activeEditor.execCommand('revisionHistory');事件
Revision History 插件提供以下事件。
Revision History 插件提供以下事件。
| 名称 | 数据 | 描述 |
|---|---|---|
VersionRestored |
| 恢复版本时触发。 |
API
Revision History 插件提供以下 API。
interface PluginAPI {
diff: (originalHTML: string, changedHTML: string) => string
}diff
返回一个 HTML 字符串,其中包含的注释标记指示了 originalHTML 相对于 changedHTML 的变化。可以通过 revisionhistory_diff_classes 选项自定义注释的样式。
const input1 = `<p>The banner is <span style="color: rgb(224, 62, 45);">red</span></p>`; const input2 = `<p>The flag is <span style="color: rgb(22, 145, 121);">red</span></p>`; tinymce.activeEditor.plugins.revisionhistory.diff(input1, input2); /* 预期输出: <p>The <del class="tox-revisionhistory__annotation--removed">banner</del><ins class="tox-revisionhistory__annotation--added">flag</ins> is <ins class="tox-revisionhistory__annotation--modified"><span style="color: rgb(22, 145, 121);">red</span></ins> </p> */