此插件仅作为 付费附加组件 提供给 TinyMCE 订阅。

建议编辑插件允许多个用户协同编辑文档。审阅窗口显示哪个用户提出了哪些编辑建议,无论是添加、删除、修改还是替换内容,并且允许用户对这些建议提供反馈,或通过接受或拒绝建议来做出最终审阅。

交互式示例

HTML

<textarea id="suggestededits" suggestededits-model='{"history":{"2":[{"id":1,"uid":"james-wilson","timestamp":1752576936000,"feedback":"Nice improvement!"}]},"version":2,"metadata":{"5":{"source":"ai"}},"contents":[{"type":"p","children":[{"type":"img","attrs":{"style":"display: block; margin-left: auto; margin-right: auto;","title":"微型 Logo","src":"https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png","alt":"TinyMCE Logo","width":"128","height":"128"}}]},{"type":"h2","attrs":{"style":"text-align: center;"},"children":[{"text":"欢迎使用 TinyMCE 建议编辑 "},{"text":"交互式 ","opData":{"id":1,"type":"insert","uid":"alex-thompson","timestamp":1752015064000}},{"text":"演示!"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"试用建议编辑功能"},{"text":" 通过在编辑器中输入内容并","opData":{"id":2,"type":"remove","uid":"alex-thompson","timestamp":1752415064000}},{"text":":在编辑器中输入内容,应用格式或删除部分内容。然","opData":{"id":2,"type":"insert","uid":"alex-thompson","timestamp":1752415064000}},{"text":"后"},{"text":",","opData":{"id":3,"type":"insert","uid":"alex-thompson","timestamp":1752515064000}},{"text":"点击"},{"text":"击","opData":{"id":4,"type":"remove","uid":"alex-thompson","timestamp":1752515064000}},{"text":"工具栏中的审阅编辑按钮"},{"text":" 查看您的更改","opData":{"id":5,"type":"insert","uid":"kai-nakamura","timestamp":1752615064000}},{"text":"。"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"并访问 "},{"text":"定价页面","opData":{"id":6,"type":"modify","uid":"kai-nakamura","timestamp":1752615064000},"format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}}],"oldFormat":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}},"em"]},{"text":" 以了解有关我们 Premium 插件的更多信息。"}]},{"type":"h2","children":[{"text":"一个可试用的简单表格"}]},{"type":"table","attrs":{"style":"border-collapse: collapse; width: 100%;","border":"1"},"children":[{"type":"thead","children":[{"type":"tr","attrs":{"style":"text-align: left;"},"children":[{"type":"th","children":[{"text":"产品"}]},{"type":"th","children":[{"text":"费用"}]},{"type":"th","children":[{"text":"真的吗?"}]}]}]},{"type":"tbody","children":[{"type":"tr","children":[{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"TinyMCE Cloud"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"免费开始使用"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"是的!","format":["strong"]}]}]}]}]},{"type":"h2","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"children":[{"text":"发现了一个 bug?"}]},{"type":"p","children":[{"text":" ","opData":{"id":7,"type":"remove","uid":"mia-andersson","timestamp":1752576331000}},{"text":"如果您认为发现了一个 bug,请在 ","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}},{"text":"GitHub 仓库","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"format":[{"type":"a","attrs":{"href":"https://github.com/tinymce/tinymce/issues"}}]},{"text":" 上创建一个 issue 以向开发人员报告该问题。","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}}]},{"type":"h2","children":[{"text":"最后……"}]},{"type":"p","children":[{"text":"应用需要文件上传功能?考虑将 "},{"text":"Uploadcare","format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/docs/tinymce/latest/uploadcare/","target":"_blank","rel":"noopener noreferrer"}}]},{"text":" 与 TinyMCE 配合使用,以获得快速、现代的上传体验。"}]},{"type":"p","children":[{"text":"感谢您支持 TinyMCE。我们希望它能帮助您和您的用户创建优质内容。"}]},{"type":"p","children":[{"text":"来自 TinyMCE 团队的美好祝愿。"}]}]}'>
  <p><img style="display: block; margin-left: auto; margin-right: auto;" title="微型 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>

  <p style="text-align: center;">试用建议编辑功能:在编辑器中输入内容,应用格式或删除部分内容。然后,点击工具栏中的审阅编辑按钮查看您的更改。</p>

  <p style="text-align: center;">并访问 <a href="https://www.tiny.cloud/pricing">定价页面</a> 以了解有关我们 Premium 插件的更多信息。</p>
  
  <h2>一个可试用的简单表格</h2>

  <table style="border-collapse: collapse; width: 100%;" border="1">
    <thead>
      <tr style="text-align: left;">
        <th>产品</th>
        <th>费用</th>
        <th>真的吗?</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="text-align: center;">TinyMCE Cloud</td>
        <td style="text-align: center;">免费开始使用</td>
        <td style="text-align: center;"><strong>是的!</strong></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。我们希望它能帮助您和您的用户创建优质内容。</p>
  <p>来自 TinyMCE 团队的美好祝愿。</p>

  <p><script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/latest/tinymce.min.js" referrerpolicy="origin"></script></p>
  <p> <script>TinyMCE.init({};</script></p>
</textarea>
我们打造了 Suggested Edits 插件(目前处于 beta 阶段),以便用户可以轻松提出编辑建议并跟踪修改情况。您可以体验我们的演示并查看 文档。

感谢所有提供反馈的用户。我们的用户创作了精彩内容。

来自 TinyMCE 团队的诚挚问候。

JS

const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

const tinymceElement = document.querySelector('textarea#suggestededits');
const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));

tinymce.init({
  selector: 'textarea#suggestededits',
  height: 500,
  plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
  toolbar: 'undo redo | suggestededits suggestededits-tracking | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
  
  suggestededits_model: model,
  suggestededits_access: 'full',
  suggestededits_content: 'html',
  view_show: 'suggestededits',
  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 编辑模式。

有关使用模块打包工具捆绑此插件的信息,请参阅 捆绑 TinyMCE - 概述。

工作原理

Suggested Edits 插件会跟踪当前用户对文档所做的每一次编辑,并将此元数据存储在文档的内部模型中。然后,可以在“审阅编辑”视图中审查这些建议,在该视图中,文档中的每个编辑都会被高亮显示,用户可以接受、拒绝或提供反馈。可以通过 suggestededits 工具栏按钮或 View 菜单中的 suggestededits 菜单项打开“审阅编辑”视图。

模型

Suggested Edits 模型是一个 JSON 对象,表示文档以及所有未审阅的编辑和反馈。该模型必须与编辑器内容保持同步,并在内容加载时同时加载到编辑器中。

模型的结构未记录,不应依赖。由插件早期版本保存的模型会继续加载并自动升级。

可以使用 getModel API 从插件中检索模型,将其作为文档的外部内容保存,并使用 suggestededits_model 选项加载到编辑器中。这确保了文档和模型保持同步,并且每个用户的贡献都被正确跟踪。如果编辑器加载时模型和内容不同步,两者之间的差异将包含在当前用户的下一次编辑中。如果在编辑器配置中未提供模型或将其设置为 undefined,插件将根据初始内容生成新模型。

或者,suggestededits_content 选项允许模型生成编辑器内容,在这种情况下,两者不需要保持同步。

审阅编辑

“审阅编辑”视图显示多个作者所做的编辑以供审阅。此视图中的可用操作取决于 suggestededits_access 选项。

在“审阅编辑”视图打开时,编辑器菜单栏、工具栏和状态栏保持可见,编辑器内容为只读,且编辑器仍可调整大小。在视图打开时,大多数工具栏按钮和菜单项被禁用。在任何编辑器模式下都能工作的项目,如全屏、预览和打印,仍然可用。有关详细信息,请参阅 内置上下文。打开侧边栏会关闭“审阅编辑”视图。打开和关闭“审阅编辑”视图会保持文档中的当前滚动位置。

页眉

侧边栏顶部的页眉显示 审阅编辑 标题和两个用于结束审阅的按钮:

  • 保存并退出:结束审阅,将已解决的建议应用到文档。未解决的建议保留在文档中以供将来审阅。对于没有 full 访问权限的用户,此按钮被禁用。

  • 退出审阅图标 退出审阅:结束审阅但不应用已解决的建议,并且不对文档做任何更改。对建议给出的反馈将被保留。

退出审阅 按钮仅显示图标。文本 退出审阅 作为工具提示和按钮的可访问标签出现。

页脚

文档下方的页脚在两个视图之间切换:

  • 差异模式:显示带有文档中所述颜色编码的建议编辑。当未解决的建议仍然存在时,差异模式会调暗未更改的内容,使未解决的建议突出显示。差异模式是默认视图。

  • 预览:显示应用建议编辑后的文档阅读效果,同时考虑已接受和已拒绝的建议。添加和修改的内容带有下划线,删除的内容被隐藏,除非选中了该建议。

文档

“审阅编辑”视图在 iframe 中显示当前编辑器文档,文档中出现的每个建议编辑都被高亮显示。

在差异模式下,使用以下颜色编码来指示更改类型:

  • 绿色:添加的内容。

  • 蓝色:修改的属性或格式,如粗体或斜体。

  • 红色:删除的内容,以删除线显示。

  • 在 Diff 模式下,被删除的图片、视频和嵌入的框架也会用红色叉号标记。只有在添加或删除换行的地方才会出现换行标记。

    替换的内容会同时显示为新增内容和删除内容,表示一次编辑中删除了部分内容并用新内容替换。当选中某个建议时,无论是在文档中还是侧边栏中,文档中对应的高亮建议都会用蓝色边框标出并滚动到可见区域。在 Diff 模式下,已接受和已拒绝的建议在未选中时显示结果且不带高亮。在卡片或建议以外的地方点击会清除选中状态。

    侧边栏

    每个建议编辑以卡片形式列出在侧边栏中,按编辑在文档中出现的顺序排列。卡片标题显示建议提出者和编辑时间。标题下方,卡片描述编辑内容并引用已更改的文本,例如:已将“the”替换为“them”。较长文本会用省略号缩短。

    通过 TinyMCE AI 插件进行的编辑会记录为 AI 辅助。默认情况下,这些卡片会显示一个 AI 徽章。将 suggestededits_ai_attribution 设为 false 可隐藏该徽章。

    对于具有 full 访问权限的用户,将鼠标指向卡片或选中卡片时,卡片标题中会显示以下按钮:

    • Accept:解决该建议,在审查完成后将编辑应用到文档。

    • Reject:解决该建议,将编辑恢复到原始状态。

    在建议被接受或拒绝后,卡片标题会显示一个 Revert 按钮,并带有指示该决定的图标。点击 Revert 会移除该决定并将建议返回到未解决状态。

    当选中一个未解决的建议时,具有 feedback 或 full 访问权限的用户可以选择 Provide feedback 以打开一个文本区域并提供关于该建议的反馈。

    选中未解决的卡片时,反馈会按时间顺序显示在卡片详情下方。反馈允许用户在解决建议之前进行讨论。在 suggestededits_access 选项中有相应权限时,反馈作者可以编辑或删除自己的反馈。

    批量操作

    具有 full 访问权限的用户可以使用侧边栏顶部的 Bulk actions 菜单一次性解决多个建议:

    • Accept all:接受所有未解决的建议。已接受或已拒绝的建议保留其决定。当部分建议已解决而其他仍未解决时,此项标签为 Accept remaining。

    • Reject all:拒绝所有未解决的建议。已接受或已拒绝的建议保留其决定。当部分建议已解决而其他仍未解决时,此项标签为 Reject remaining。

    • Revert all:将所有已接受或已拒绝的建议返回到未解决状态。

    当没有未解决的建议时,接受和拒绝项目不可用。只有在至少有一个建议被解决时,Revert all 才可用。

    键盘导航

    Review edits 视图支持以下按键:

    • Tab 和 Shift+Tab:在侧边栏标题中的按钮、Bulk actions 菜单和卡片之间移动焦点。

    • 向上箭头和向下箭头:在卡片之间移动并选中焦点建议。

    • Enter:将焦点移到聚焦卡片的内容中。

    • Escape:将焦点移到 Exit review 按钮。当 Exit review 已经有焦点时,Escape 结束审查。

    完成审查

    使用 Save & Exit 完成审查时,已解决的建议将应用到文档中,并且不会再在模型中作为建议进行跟踪。对已解决建议的反馈将被丢弃。任何“已接受”的编辑会保留在文档中,任何“已拒绝”的编辑会恢复到建议提出之前的状态。

    审查操作将按以下方式应用于文档:

    当新增内容是:

    • 已接受:内容将保留在文档中。

    • 已拒绝:内容将从文档中移除。

    当修改后的内容是:

    • 已接受:内容将保留当前格式和属性。

    • 已拒绝:内容将恢复到修改前的格式和属性,以匹配编辑前的内容状态。

    当删除的内容是:

    • 已接受:内容将从文档中移除。

    • 已拒绝:删除的内容将恢复到文档中。

    如果审查以 Exit review 结束,则不会将任何已解决的建议应用到文档。所有建议(包括在该审查会话期间提供的任何反馈)都将保留在模型中。

    初始设置

    要在编辑器中设置 Suggested Edits 插件:

    • 在编辑器配置的 plugins 选项中添加 suggestededits;

    • 在编辑器配置的 toolbar 选项中添加 suggestededits;

    例如:

    tinymce.init({
      selector: 'textarea#suggestededits',  // change this value according to your HTML
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
    });

    此配置会将 Suggested Edits 添加到编辑器工具栏,从而启用对该插件功能的访问。要充分利用该插件,必须提供额外的配置选项。

    选项

    以下配置选项会影响 Suggested Edits 插件的行为。

    suggestededits_model

    suggestededits_model 选项会将现有模型加载到 Suggested Edits 插件中。此模型包含当前所有的建议编辑内容,用于在不同会话之间保持连续性。如果未提供模型,插件将根据初始编辑器内容生成新模型。

    类型: Object

    示例:使用 suggestededits_model

    const tinymceElement = document.querySelector('textarea#suggestededits');
    const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));
    
    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据你的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      suggestededits_model: model // 将保存的模型加载到编辑器
    });

    suggestededits_content

    suggestededits_content 选项控制内容是从编辑器还是从 suggestededits_model 模型中加载,允许你定义文档的权威来源。无论哪种情况,如果未提供模型,插件都将根据初始编辑器内容生成新模型。

    当设置为:

    • 'html':编辑器正常加载内容,插件将模型与内容同步。这通过将 Suggested Edits 模型作为附加字段与编辑器内容一起附加,简化了现有集成中 Suggested Edits 的配置。

    • 'model':编辑器使用 suggestededits_model 选项生成初始内容,忽略编辑器中任何预先存在的内容。使用此配置,你只需要存储并提供模型,从而简化了 Suggested Edits 插件的集成。

    你需要负责保存模型,并在下次加载时使用 suggestededits_model 选项提供该模型。

    类型: String

    可能的值:'html','model'

    默认值: 'html'

    示例:使用 suggestededits_content

    const tinymceElement = document.querySelector('textarea#suggestededits');
    const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));
    
    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据你的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      suggestededits_model: model, // 将保存的模型加载到编辑器
      suggestededits_content: 'model' // 如果希望从 `suggestededits_model` 选项加载初始内容,则设置为 'model'
    });

    suggestededits_access

    suggestededits_access 选项确定用户对“Review edits”视图的访问级别。此设置对于控制谁可以接受或拒绝建议、添加反馈或以只读模式查看建议至关重要。suggestededits_access 选项不控制对编辑器内容的访问,但是当与 readonly 选项结合使用时,它可以对用户权限进行细粒度控制。

    当设置为:

    • 'full':用户具有对“Review edits”视图的完全访问权限,有权接受或拒绝建议、使用 Bulk actions 菜单,并通过 Save & Exit 完成审查。

    • 'feedback':用户可以访问“Review edits”视图,有权向建议添加反馈。Save & Exit 按钮被禁用。

    • 'read':用户对“Review edits”视图具有只读访问权限。Save & Exit 按钮被禁用。

    • 'none':用户无法访问“Review edits”视图。suggestededits 工具栏按钮和菜单项不可用。

    类型: String

    可能的值:'full','feedback','read','none'

    默认值:'full'

    示例:suggestededits_access: 'feedback'

    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据你的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      suggestededits_access: 'feedback', // 更改此值以设置“Review edits”视图权限
      readonly: false // 设置为 true 以限制编辑
    });

    HTML

    <textarea id="suggestededits-access-feedback" suggestededits-model='{"history":{"2":[{"id":1,"uid":"james-wilson","timestamp":1752576936000,"feedback":"Nice improvement!"}]},"version":1,"contents":[{"type":"p","children":[{"type":"img","attrs":{"style":"display: block; margin-left: auto; margin-right: auto;","title":"微型标志","src":"https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png","alt":"TinyMCE 标志","width":"128","height":"128"}}]},{"type":"h2","attrs":{"style":"text-align: center;"},"children":[{"text":"欢迎使用 TinyMCE 建议编辑 "},{"text":"交互式 ","opData":{"id":1,"type":"insert","uid":"alex-thompson","timestamp":1752015064000}},{"text":"演示!"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"试用建议编辑功能"},{"text":" 通过在编辑器中输入内容t","opData":{"id":2,"type":"remove","uid":"alex-thompson","timestamp":1752415064000}},{"text":":在编辑器中输入内容,应用格式或删除一些内容。T","opData":{"id":2,"type":"insert","uid":"alex-thompson","timestamp":1752415064000}},{"text":"然后"},{"text":",","opData":{"id":3,"type":"insert","uid":"alex-thompson","timestamp":1752515064000}},{"text":"点击"},{"text":"ing","opData":{"id":4,"type":"remove","uid":"alex-thompson","timestamp":1752515064000}},{"text":"工具栏中的“审查编辑”按钮"},{"text":" 查看您的更改","opData":{"id":5,"type":"insert","uid":"kai-nakamura","timestamp":1752615064000}},{"text":"。"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"并访问 "},{"text":"价格页面","opData":{"id":6,"type":"modify","uid":"kai-nakamura","timestamp":1752615064000},"format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}}],"oldFormat":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}},"em"]},{"text":" 以了解更多关于我们的 Premium 插件的信息。"}]},{"type":"h2","children":[{"text":"一个简单的表格供操作"}]},{"type":"table","attrs":{"style":"border-collapse: collapse; width: 100%;","border":"1"},"children":[{"type":"thead","children":[{"type":"tr","attrs":{"style":"text-align: left;"},"children":[{"type":"th","children":[{"text":"产品"}]},{"type":"th","children":[{"text":"费用"}]},{"type":"th","children":[{"text":"真的吗?"}]}]}]},{"type":"tbody","children":[{"type":"tr","children":[{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"TinyMCE Cloud"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"免费开始使用"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"是的!","format":["strong"]}]}]}]}]},{"type":"h2","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"children":[{"text":"发现了一个 bug?"}]},{"type":"p","children":[{"text":" ","opData":{"id":7,"type":"remove","uid":"mia-andersson","timestamp":1752576331000}},{"text":"如果您认为自己发现了一个 bug,请在 ","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}},{"text":"GitHub 仓库","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"format":[{"type":"a","attrs":{"href":"https://github.com/tinymce/tinymce/issues"}}]},{"text":" 上创建一个 issue,向开发者报告该问题。","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}}]},{"type":"h2","children":[{"text":"最后…"}]},{"type":"p","children":[{"text":"您的应用需要文件上传功能吗?考虑使用 "},{"text":"Uploadcare","format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/docs/tinymce/latest/uploadcare/","target":"_blank","rel":"noopener noreferrer"}}]},{"text":" 与 TinyMCE 搭配使用,以获得快速、现代的上传体验。"}]},{"type":"p","children":[{"text":"感谢您支持 TinyMCE。我们希望它能帮助您和您的用户创建出色的内容。"}]},{"type":"p","children":[{"text":"来自 TinyMCE 团队的最良好祝愿。"}]}]}'>
      <p><img style="display: block; margin-left: auto; margin-right: auto;" title="微型标志" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE 标志" width="128" height="128"></p>
    
      <h2 style="text-align: center;">欢迎使用 TinyMCE 建议编辑交互式演示!</h2>
    
      <p style="text-align: center;">试用建议编辑功能:在编辑器中输入内容,应用格式或删除一些内容。然后,点击工具栏中的“审查编辑”按钮查看您的更改。</p>
    
      <p style="text-align: center;">并访问 <a href="https://www.tiny.cloud/pricing">价格页面</a> 以了解更多关于我们的 Premium 插件的信息。</p>
      
      <h2>一个简单的表格供操作</h2>
    
      <table style="border-collapse: collapse; width: 100%;" border="1">
        <thead>
          <tr style="text-align: left;">
            <th>产品</th>
            <th>费用</th>
            <th>真的吗?</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align: center;">TinyMCE Cloud</td>
            <td style="text-align: center;">免费开始使用</td>
            <td style="text-align: center;"><strong>是的!</strong></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。我们希望它能帮助您和您的用户创建g精彩的内容。</p>
      <p>来自 TinyMCE 团队的诚挚问候。</p&gt>
    
    </textarea>

    JS

    const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
    
    const tinymceElement = document.querySelector('textarea#suggestededits-access-feedback');
    const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));
    
    tinymce.init({
      selector: 'textarea#suggestededits-access-feedback',
      height: 500,
      plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
      toolbar: 'undo redo | suggestededits | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
      readonly: false, // 设置为 true 以防止对内容进行编辑
    
      suggestededits_model: model,
      suggestededits_access: 'feedback', // 设置此值以限制 Suggested Edits 视图中的权限
      suggestededits_content: 'html',
      user_id: 'kai-nakamura',
      fetch_users: (userIds) => Promise.all(userIds
        .map((userId) =>
          fetch(`${API_URL}/${userId}`)
            .then((response) => response.json())
            .catch(() => ({ id: userId }))))
    });
    示例:suggestededits_access: 'read'
    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      suggestededits_access: 'read', // 更改此值以设置 Review edits 视图权限
      readonly: false // 设置为 true 以限制编辑
    });

    HTML

    <textarea id="suggestededits-access-read" suggestededits-model='{"history":{"2":[{"id":1,"uid":"james-wilson","timestamp":1752576936000,"feedback":"Nice improvement!"}]},"version":1,"contents":[{"type":"p","children":[{"type":"img","attrs":{"style":"display: block; margin-left: auto; margin-right: auto;","title":"微小的标志","src":"https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png","alt":"TinyMCE 标志","width":"128","height":"128"}}]},{"type":"h2","attrs":{"style":"text-align: center;"},"children":[{"text":"欢迎使用 TinyMCE 建议编辑"},{"text":"交互式 ","opData":{"id":1,"type":"insert","uid":"alex-thompson","timestamp":1752015064000}},{"text":"演示!"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"试用建议编辑功能"},{"text":" 通过在编辑器中输入内容并","opData":{"id":2,"type":"remove","uid":"alex-thompson","timestamp":1752415064000}},{"text":":在编辑器中输入内容、应用格式或删除部分内容。然","opData":{"id":2,"type":"insert","uid":"alex-thompson","timestamp":1752415064000}},{"text":"后"},{"text":",","opData":{"id":3,"type":"insert","uid":"alex-thompson","timestamp":1752515064000}},{"text":"点击"},{"text":"点击","opData":{"id":4,"type":"remove","uid":"alex-thompson","timestamp":1752515064000}},{"text":"工具栏中的“查看编辑”按钮"},{"text":" 查看您的更改","opData":{"id":5,"type":"insert","uid":"kai-nakamura","timestamp":1752615064000}},{"text":"。"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"访问"},{"text":"定价页面","opData":{"id":6,"type":"modify","uid":"kai-nakamura","timestamp":1752615064000},"format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}}],"oldFormat":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}},"em"]},{"text":"了解有关我们 Premium 插件的更多信息。"}]},{"type":"h2","children":[{"text":"一个简单的表格供您使用"}]},{"type":"table","attrs":{"style":"border-collapse: collapse; width: 100%;","border":"1"},"children":[{"type":"thead","children":[{"type":"tr","attrs":{"style":"text-align: left;"},"children":[{"type":"th","children":[{"text":"产品"}]},{"type":"th","children":[{"text":"费用"}]},{"type":"th","children":[{"text":"真的吗?"}]}]}]},{"type":"tbody","children":[{"type":"tr","children":[{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"TinyMCE Cloud"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"免费开始使用"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"是的!","format":["strong"]}]}]}]}]},{"type":"h2","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"children":[{"text":"发现了 bug?"}]},{"type":"p","children":[{"text":" ","opData":{"id":7,"type":"remove","uid":"mia-andersson","timestamp":1752576331000}},{"text":"如果您认为自己发现了一个 bug,请在"},{"text":"GitHub repo","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"format":[{"type":"a","attrs":{"href":"https://github.com/tinymce/tinymce/issues"}}]},{"text":"上创建一个 issue,向开发人员报告该问题。","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}}]},{"type":"h2","children":[{"text":"最后……"}]},{"type":"p","children":[{"text":"您的应用程序需要文件上传功能吗?考虑使用 "},{"text":"Uploadcare","format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/docs/tinymce/latest/uploadcare/","target":"_blank","rel":"noopener noreferrer"}}]},{"text":" 与 TinyMCE 配合使用,以获得快速、现代的上传体验。"}]},{"type":"p","children":[{"text":"感谢您支持 TinyMCE。我们希望它能帮助您和您的用户创建出色的内容。"}]},{"type":"p","children":[{"text":"来自 TinyMCE 团队的诚挚问候。"}]}]}'>
      <p><img style="display: block; margin-left: auto; margin-right: auto;" title="微小的标志" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE 标志" width="128" height="128"></p>
    
      <h2 style="text-align: center;">欢迎使用 TinyMCE 建议编辑交互式演示!</h2>
    
      <p style="text-align: center;">试用建议编辑功能:在编辑器中输入内容、应用格式或删除部分内容。然后,点击工具栏中的“查看编辑”按钮查看您的更改。</p>
    
      <p style="text-align: center;">访问 <a href="https://www.tiny.cloud/pricing">定价页面</a>了解有关我们 Premium 插件的更多信息。</p>
      
      <h2>一个简单的表格供您使用</h2>
    
      <table style="border-collapse: collapse; width: 100%;" border="1">
        <thead>
          <tr style="text-align: left;">
            <th>产品</th>
            <th>费用</th>
            <th>真的吗?</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align: center;">TinyMCE Cloud</td>
            <td style="text-align: center;">免费开始使用</td>
            <td style="text-align: center;"><strong>是的!</strong></td>
          </tr>
        </tbody>
      </table>
    
      <h2>发现了 bug?</h2>
    
      <p>如果您认为自己发现了一个 bug,请在 <a href="https://github.com/tinymce/tinymce/issues">GitHub repo</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。我们希望它能帮助您和您的用户创建出色的内容。</p>
      <p>来自 TinyMCE 团队的诚挚问候。</p>
    
    content.

    来自 TinyMCE 团队的诚挚问候。

    JS

    const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
    
    const tinymceElement = document.querySelector('textarea#suggestededits-access-read');
    const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));
    
    tinymce.init({
      selector: 'textarea#suggestededits-access-read',
      height: 500,
      plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
      toolbar: 'undo redo | suggestededits | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
      readonly: false, // 设置为 true 以防止对内容进行编辑
    
      suggestededits_model: model,
      suggestededits_access: 'read', // 设置此值以限制 Suggested Edits 视图中的权限
      suggestededits_content: 'html',
      user_id: 'kai-nakamura',
      fetch_users: (userIds) => Promise.all(userIds
        .map((userId) =>
          fetch(`${API_URL}/${userId}`)
            .then((response) => response.json())
            .catch(() => ({ id: userId }))))
    });

    suggestededits_auto_approve

    suggestededits_auto_approve 选项控制当前用户在会话期间所做的编辑是否自动批准,无需手动审核。启用此选项后,当前用户(通过 user_id 选项设置)所做的任何编辑以及当前用户之前提出的任何建议都将立即应用,绕过审核流程。这对于不需要审核的情况非常有用,例如创建初始草稿时或用户是受信任的编辑者时。

    设置为以下值时:

    • false:所有编辑都需要手动批准才能应用。

    • true:所有新编辑都将自动批准并应用。

    在 TinyMCE 8.7 中,此选项控制 suggestededits-tracking 工具栏按钮和菜单项的默认状态。当设置为 false 时,suggestededits-tracking 按钮将默认处于活动状态,编辑将出现在审核中。当设置为 true 时,按钮将默认处于非活动状态,意味着编辑不会出现在审核中。切换按钮或菜单项将覆盖此选项为当前会话设置的默认状态。

    类型: Boolean

    默认值:false

    示例:suggestededits_auto_approve: true
    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据您的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits suggestededits-tracking',
      suggestededits_auto_approve: true, // 更改此值以自动批准建议的编辑
    });

    HTML

    <textarea id="suggestededits-auto-approve" suggestededits-model='{"history":{"2":[{"id":1,"uid":"james-wilson","timestamp":1752576936000,"feedback":"Nice improvement!"}]},"version":1,"contents":[{"type":"p","children":[{"type":"img","attrs":{"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"}}]},{"type":"h2","attrs":{"style":"text-align: center;"},"children":[{"text":"欢迎使用 TinyMCE 建议编辑 "},{"text":"交互式 ","opData":{"id":1,"type":"insert","uid":"alex-thompson","timestamp":1752015064000}},{"text":"演示!"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"试用建议编辑功能"},{"text":" 在编辑器中输入内容并通","opData":{"id":2,"type":"remove","uid":"alex-thompson","timestamp":1752415064000}},{"text":":在编辑器中输入内容、应用格式或删除部分内容。然","opData":{"id":2,"type":"insert","uid":"alex-thompson","timestamp":1752415064000}},{"text":"后"},{"text":",","opData":{"id":3,"type":"insert","uid":"alex-thompson","timestamp":1752515064000}},{"text":"点击"},{"text":"ing","opData":{"id":4,"type":"remove","uid":"alex-thompson","timestamp":1752515064000}},{"text":"工具栏中的“审查编辑”按钮"},{"text":" 查看您的更改","opData":{"id":5,"type":"insert","uid":"kai-nakamura","timestamp":1752615064000}},{"text":"。"}]},{"type":"p","attrs":{"style":"text-align: center;"},"children":[{"text":"访问 "},{"text":"定价页面","opData":{"id":6,"type":"modify","uid":"kai-nakamura","timestamp":1752615064000},"format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}}],"oldFormat":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/pricing"}},"em"]},{"text":" 以了解有关我们 Premium 插件的更多信息。"}]},{"type":"h2","children":[{"text":"一个简单的表格供试用"}]},{"type":"table","attrs":{"style":"border-collapse: collapse; width: 100%;","border":"1"},"children":[{"type":"thead","children":[{"type":"tr","attrs":{"style":"text-align: left;"},"children":[{"type":"th","children":[{"text":"产品"}]},{"type":"th","children":[{"text":"成本"}]},{"type":"th","children":[{"text":"真的吗?"}]}]}]},{"type":"tbody","children":[{"type":"tr","children":[{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"TinyMCE Cloud"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"免费开始使用"}]},{"type":"td","attrs":{"style":"text-align: center;"},"children":[{"text":"是的!","format":["strong"]}]}]}]}]},{"type":"h2","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"children":[{"text":"发现 bug?"}]},{"type":"p","children":[{"text":" ","opData":{"id":7,"type":"remove","uid":"mia-andersson","timestamp":1752576331000}},{"text":"如果您认为自己发现了一个 bug,请在 ","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}},{"text":"GitHub 仓库","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000},"format":[{"type":"a","attrs":{"href":"https://github.com/tinymce/tinymce/issues"}}]},{"text":" 上创建 issue,向开发人员报告。","opData":{"id":7,"type":"insert","uid":"mia-andersson","timestamp":1752576331000}}]},{"type":"h2","children":[{"text":"最后…"}]},{"type":"p","children":[{"text":"应用程序需要文件上传功能吗?考虑将 "},{"text":"Uploadcare","format":[{"type":"a","attrs":{"href":"https://www.tiny.cloud/docs/tinymce/latest/uploadcare/","target":"_blank","rel":"noopener noreferrer"}}]},{"text":" 与 TinyMCE 结合使用,获得快速、现代的上传体验。"}]},{"type":"p","children":[{"text":"感谢您支持 TinyMCE。我们希望它能帮助您和您的用户创建优质内容。"}]},{"type":"p","children":[{"text":"TinyMCE 团队祝您一切顺利。"}]}]}'>
      <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>
    
      <p style="text-align: center;">试用建议编辑功能:在编辑器中输入内容、应用格式或删除部分内容。然后,点击工具栏中的“审查编辑”按钮查看您的更改。</p>
    
      <p style="text-align: center;">访问 <a href="https://www.tiny.cloud/pricing">定价页面</a> 以了解有关我们 Premium 插件的更多信息。</p>
      
      <h2>一个简单的表格供试用</h2>
    
      <table style="border-collapse: collapse; width: 100%;" border="1">
        <thead>
          <tr style="text-align: left;">
            <th>产品</th>
            <th>成本</th>
            <th>真的吗?</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align: center;">TinyMCE Cloud</td>
            <td style="text-align: center;">免费开始使用</td>
            <td style="text-align: center;"><strong>是的!</strong></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。我们希望它能帮助您和您的用户创建优质内容。</p>
      <p>TinyMCE 团队祝您一切顺利。</p>
    
    在内容。

    来自TinyMCE团队的诚挚问候。

    JS

    const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
    
    const tinymceElement = document.querySelector('textarea#suggestededits-auto-approve');
    const model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));
    
    tinymce.init({
      selector: 'textarea#suggestededits-auto-approve',
      height: 500,
      plugins: 'suggestededits advlist anchor autolink code charmap emoticons fullscreen help image link lists media preview searchreplace table',
      toolbar: 'undo redo | suggestededits suggestededits-tracking | styles fontsizeinput | bold italic | align bullist numlist | table link image | code',
      content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
      
      suggestededits_model: model,
      suggestededits_access: 'full',
      suggestededits_content: 'html',
      suggestededits_auto_approve: true,
      user_id: 'kai-nakamura',
      fetch_users: (userIds) => Promise.all(userIds
        .map((userId) =>
          fetch(`${API_URL}/${userId}`)
            .then((response) => response.json())
            .catch(() => ({ id: userId }))))
    });

    suggestededits_ai_attribution

    此选项控制建议卡片上 AI 徽章的显示。默认情况下,使用 TinyMCE AI 插件所做的编辑会在其卡片上显示 AI 徽章。设置为 false 可隐藏徽章。

    AI 辅助建议始终会记录在模型中。此选项仅控制是否显示 AI 徽章。

    类型: Boolean

    默认值: true

    示例:使用 suggestededits_ai_attribution

    tinymce.init({
      selector: 'textarea',  // 根据你的 HTML 修改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      suggestededits_ai_attribution: false
    });

    view_show

    可以使用 view_show 选项在编辑器加载时显示 Suggested Edits 视图。

    例如:
    tinymce.init({
      selector: 'textarea',  // 根据你的 HTML 修改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      view_show: 'suggestededits',
      // ... 其他 Suggested Edits 选项(例如 suggestededits_model、user_id、fetch_users)
    });

    user_id

    此选项设置编辑器中当前用户的唯一标识符。它用于 UserLookup API。

    类型: String

    默认值: 'Anonymous'

    示例:使用 user_id 选项
    tinymce.init({
      selector: 'textarea',  // 根据你的 HTML 修改此值
      user_id: 'james-wilson' // 用一个唯一的字符串替换它以识别用户
    });

    fetch_users

    一个必需的回调函数,用于获取用户数据。此函数以一个用户 ID 数组为参数调用,应返回一个解析为用户对象数组的 Promise。该回调函数由 UserLookup API 使用。如果返回的数组不包含所有请求的用户 ID,则针对缺失用户的 promise 将被拒绝,并报错“User {id} not found”。

    类型: 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 }) // 即使服务器未返回该用户,也仍然返回一个有效的用户
        );
      },
    });

    user_id 和 fetch_users 选项都是配置 User Lookup API 所必需的。此 API 在 Suggested Edits 插件中使用,用于为每个做出更改的用户提供用户信息,允许其他用户查看谁提出了哪些建议。

    • 当前用户 ID 应通过 user_id 选项设置。用户 ID 应是一个唯一标识用户的字符串,例如用户名或电子邮件地址。

    • 必须使用 fetch_users 选项来为提交建议的用户提供名称和头像。此选项可配置为从后端服务获取数据。fetch_users 函数接收一个用户 ID 数组,并应返回一个 promise,该 promise 解析为包含所请求用户 ID 数据的数组。

    工具栏按钮

    Suggested Edits 插件提供以下工具栏按钮:

    工具栏按钮标识符描述

    suggestededits

    打开“审核编辑”视图。

    suggestededits-label

    打开“审核编辑”视图(此按钮使用文本而非图标)。

    suggestededits-tracking

    切换建议编辑的跟踪。

    可通过以下方式将这些工具栏按钮添加到编辑器:

    • toolbar 配置选项。

    • quickbars_insert_toolbar 配置选项。

    • 自定义上下文工具栏。

    菜单项

    Suggested Edits 插件提供以下菜单项:

    菜单项标识符默认菜单位置描述

    suggestededits

    视图

    打开“审核编辑”视图。

    suggestededits-tracking

    不适用

    切换建议编辑的跟踪。

    可通过以下方式将这些菜单项添加到编辑器:

    • menu 配置选项。

    • contextmenu 配置选项。

    • 自定义菜单工具栏按钮。

    命令

    Suggested Edits 插件提供以下 TinyMCE 命令。

    命令描述

    suggestededits

    打开“审核编辑”视图,若视图已打开则关闭且不应用已解决的建议。该视图仅在有需审核的建议且用户具有至少 'read' 访问权限时打开。

    suggestededitsToggleTracking

    切换建议编辑的跟踪。

    示例
    tinymce.activeEditor.execCommand('suggestededits');
    tinymce.activeEditor.execCommand('suggestededitsToggleTracking');
    
    tinymce.activeEditor.queryCommandState('suggestededitsToggleTracking'); // 若建议编辑的跟踪已启用则返回 true,否则返回 false。

    事件

    Suggested Edits 插件提供以下事件。

    名称数据描述

    SuggestedEditsBeginReview

    无

    “审核编辑”视图已打开。

    SuggestedEditsReviewComplete

    无

    在“审核编辑”视图中通过保存并退出完成了审核。

    SuggestedEditsReviewCancelled

    无

    在“审核编辑”视图中的审核结束且未应用已解决的建议。当用户选择退出审核、通过 suggestededits 工具栏按钮/菜单项/命令关闭审核、打开侧边栏以及编辑器模式更改时,会触发此事件。当 suggestededits 命令运行且没有需审核的建议时,也会触发。

    SuggestedEditsHasChangesUpdate

    hasChanges

    Suggested Edits 模型已更新。hasChanges 数据为布尔值,表示是否存在需审核的建议。

    SuggestedEditsTrackingToggle

    tracking

    建议编辑的跟踪状态已更改。tracking 数据为布尔值,表示是否正在跟踪编辑。

    API

    Suggested Edits 插件提供以下 API。

    名称参数描述

    getModel

    无

    返回表示文档当前模型的 JSON 对象。

    setModel

    Object

    设置文档的当前模型。

    resetModel

    无

    根据当前内容生成模型并设置为当前模型,清除所有建议。

    hasChanges

    无

    返回布尔值,表示文档是否包含任何建议编辑。

    示例
    // 获取文档当前的模型
    tinymce.activeEditor.plugins.suggestededits.getModel();
    
    // 设置文档当前的模型
    tinymce.activeEditor.plugins.suggestededits.setModel(model);
    
    // 将模型重置为当前内容,清除所有建议
    tinymce.activeEditor.plugins.suggestededits.resetModel();
    
    // 检查文档是否包含需要审核的更改
    tinymce.activeEditor.plugins.suggestededits.hasChanges();
    getModel 示例

    此示例演示如何保存当前文档和模型,以确保它们被同步保存。使用 getModel API 检索当前模型。

    const tinymceElement = document.querySelector('textarea#suggestededits');
    const suggestededits_model = JSON.parse(tinymceElement.getAttribute('suggestededits-model'));
    
    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据您的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits save',
      suggestededits_model,
      setup: (editor) => {
        editor.on('AddUndo Undo Redo SuggestedEditsBeginReview SuggestedEditsReviewComplete SuggestedEditsReviewCancelled', () => {
          const content = editor.getContent();
          const model = editor.plugins.suggestededits.getModel();
          tinymceElement.value = content;
          tinymceElement.setAttribute('suggestededits-model', JSON.stringify(model));
        });
      }
    });
    setModel 示例

    此示例演示如何在编辑器中设置模型和文档,在此案例中从服务器获取它们。setModel 方法设置文档的当前模型和由该模型生成的编辑器内容。

    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据您的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      setup: (editor) => {
        editor.on('init', () => {
          // 获取并设置建议编辑模型
          fetch(`/api/models/${documentId}`)
            .then((response) => response.json())
            .then((model) => {
              editor.plugins.suggestededits.setModel(model);
            })
            .catch((error) => console.error(`获取 ${documentId} 的模型时出错:`, error));
        });
      }
    });
    resetModel 示例

    此示例演示如何将模型重置为编辑器的当前内容,清除所有建议。resetModel 方法根据当前内容生成一个新模型并将其设置为当前模型。

    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据您的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits clearsuggestions',
      setup: (editor) => {
        editor.ui.registry.addButton('clearsuggestions', {
          text: '清除建议',
          onAction: () => {
            // 将模型重置为当前内容,清除所有建议
            editor.plugins.suggestededits.resetModel();
    
            editor.notificationManager.open({
              text: '所有建议已被清除。',
              type: 'info',
              timeout: 5000,
            });
          }
        });
      }
    });
    hasChanges 示例

    此示例演示如何检查文档中是否有需要在保存前审核的更改。使用 hasChanges 方法来确定是否有未审核的编辑。

    tinymce.init({
      selector: 'textarea#suggestededits',  // 根据您的 HTML 更改此值
      plugins: 'suggestededits',
      toolbar: 'suggestededits',
      setup: (editor) => {
        editor.ui.registry.addButton('save', {
          text: '保存',
          onAction: () => {
            // 获取文档当前的模型
            const hasChanges = editor.plugins.suggestededits.hasChanges();
    
            if (hasChanges) {
              editor.notificationManager.open({
                text: '有需要审核的更改。',
                type: 'warning',
                timeout: 5000,
              });
            } else {
              // 在此处插入保存逻辑
            }
          }
        });
      }
    });