TinyMCE Annotations API 提供了添加、修改和删除标注的功能;监听选区事件以及检索所有具有相同标注名称的标注。Annotations API 是 TinyMCE core 的一部分,其功能与 TinyMCE core 中的格式化 API 相同。

Annotations API 的主要价值在于它为每个标注分配了一个唯一的标识符(uid),可以通过 editor.annotator 访问。这会高亮显示已标注的内容,并将其包裹在标注标记中。根据用户配置(persistent 设置),这些标记可以保留在内容中,也可以在 getContent 时被移除。

使用 Annotator

按照以下步骤设置 TinyMCE Annotations 功能:

1. 配置标注按钮

要配置工具栏上的标注按钮:

setup: (editor) => {
  editor.ui.registry.addButton('annotate-alpha', {
    text: 'Annotate',
    onAction: () => {
      const comment = prompt('Comment with?');
      editor.annotator.annotate('alpha', {
        comment
      });
      editor.focus();
    }
  })
}

2. 注册 Annotator

annotator API 支持多种标注功能。每个标注功能都必须向 annotator(editor.annotator)注册。

editor.on('init', () => {
  editor.annotator.register('alpha', {
    persistent: true,
    decorate: (uid, data) => ({
      attributes: {
        'data-mce-comment': data.comment ? data.comment : '',
        'data-mce-author': data.author ? data.author : 'anonymous'
      }
    })
  });
});

这将注册一个名为 alpha 的标注。在我们的示例中,当向文档添加一个 alpha 时,将创建一个带有 class alpha 和作者数据属性的 span 标记。

这里传递的数据与调用 annotate API 时指定的数据相同。decorate 用于将标注数据转换为文档对象模型(DOM)表示。传递给 decorate 的 uid 是数据对象中的 uid 字段(如果存在),否则是一个随机生成的 uid。Annotator 将负责把 uid 放在 span 上。用户无需执行该部分操作。

3. 使 Annotator 可用

要将已注册为 alpha 的标注工具添加到工具栏,请将工具栏的值设置为:

toolbar: 'annotate-alpha'

4. 应用标注

注册标注后,通过将其应用于当前选区来使用它。有关可标注的内容,请参阅:支持的内容。

如果选区是折叠的(单个光标而非范围选区)且位于单词内,它将首先执行抓取单词功能,然后将标注应用于结果的单词选区。

应用标注的 API 是 annotate。可以使用以下方式以编程方式将标注应用于所选内容:

editor.annotator.annotate('alpha', {
  author: 'me'
});

通过 { author: 'me' } 传递的数据会被传递给在为特定标注(此处为 alpha)注册期间指定的 decorate 函数。此数据可以是任何对象。这样,用户可以根据每个标注为标记分配任何他们想要的属性/类。在这里,我们将得到一个带有设置为 me 的 data-author 属性的 span。如果用户愿意,他们可以在此处指定一个 uid 作为数据的一部分。当作为第一个参数传递给 decorate 时,这将代替随机生成的 uid。

指定自己的 uid 的示例:

editor.annotator.annotate('alpha', {
  uid: 'use-this-id-instead-of-your-random-one-annotator!',
  author: 'me'
});

5. 监听选区事件

当选择光标移入或移出指定标注时,Annotator API 会通知用户。例如,对于 alpha 场景:

editor.annotator.annotationChanged('alpha', (state, name, obj) => {
  if (state === false) {
    // NOTE: name will be 'alpha' here
    console.log(`We are no longer in a ${name} area`);
  } else {
    console.log(`We are now in comment: ${obj.uid}`);
  }
});

只有当 state 为 true 时,obj 参数才会被设置。并且 state 为:

  • true 当选择光标移入标注时;以及

  • false 当选择光标移出标注时。

当 state 为 true 且设置了 obj 参数时,该参数有两个字段:

  • uid,即当前最接近选择光标(在 DOM 层级结构中)的标注的 uid。

  • nodes,即构成此标注的 DOM 节点数组。如果用户想要给这些节点添加一个类来表示它们是 活动标注,则 nodes 对用户可用。

只有当状态或 uid 发生变化时,annotationChanged 监听器才会触发。完整的 API 是:

/**
* 当前选区匹配或不匹配注解时执行指定的回调函数。
*
* @method annotationChanged
* @param {String} name 要监听的注解名称
* @param {function} callback 当光标处的注解发生变化时触发的回调函数,包含 (state, name 和 data)。如果 state 为 false,则不会提供 data。
*/
annotationChanged: (name: string, callback): void

交互式示例

使用以下示例创建 Annotate API:

HTML

<textarea id="annotations">
  <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>
  </p>
  <h2 style="text-align: center;">欢迎使用 TinyMCE Cloud 演示!</h2>
  <h5 style="text-align: center;">注意,这包括一些“企业/高级”功能。<br>访问 <a href="https://www.tiny.cloud/pricing">定价页面</a> 以了解有关我们高级插件的更多信息。</h5>
  <p>请尝试此功能完整的示例中提供的功能。</p>

  <h2>有疑问或需要帮助?</h2>
  <ul>
    <li>我们的 <a href="https://www.tiny.cloud/docs/tinymce/8/">文档</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="https://www.tiny.cloud/pricing">TinyMCE 高级订阅</a> 的一部分。</li>
  </ul>

  <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 Cloud</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> 上创建一个问题,向开发人员报告。</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>
</textarea>

JS

tinymce.init({
  selector: 'textarea#annotations',
  toolbar: [ 'annotate-alpha' ],
  menubar: false,
  height: '750px',
  content_style: '.mce-annotation { background-color: darkgreen; color: white; } ' +
    'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
  setup: (editor) => {
    editor.ui.registry.addButton('annotate-alpha', {
      text: '添加注解',
      onAction: () => {
        const comment = prompt('添加什么注释?');
        editor.annotator.annotate('alpha', {
          uid: 'custom-generated-id',
          comment: comment
        });
        editor.focus();
      },
      onSetup: (btnApi) => {
        editor.annotator.annotationChanged('alpha', (state, name, obj) => {
          console.log('当前选区是否有注解: ', state);
          btnApi.setEnabled(!state);
        });
      }
    });

    editor.on('init', () => {
      editor.annotator.register('alpha', {
        persistent: true,
        decorate: (uid, data) => ({
          attributes: {
            'data-mce-comment': data.comment ? data.comment : '',
            'data-mce-author': data.author ? data.author : 'anonymous'
          }
        })
      });
    });
  }
});

检索特定注解名称的所有注解

Annotator API 允许检索特定注解类型的所有 uid 对象以及与这些 uid 关联的节点。例如,要检索所有 alpha 注解,可以使用以下代码:

const annotations = editor.annotator.getAll('alpha');
const nodesInFirstUid = annotations['first-uid'];

假设有一个名为 first-uid 的 uid,上述代码展示了如何访问用于创建该注解的节点。完整的 API 如下:

/**
* 检索给定名称的所有注解
*
* @method getAll
* @param {String} name 要检索的注解的名称
* @return {Object} 从 uid => DOM 节点的注解索引
*/
getAll: (name)

删除注解

使用 remove API 删除光标处的特定注解。它将删除与该名称匹配的最近的注解。例如,

editor.annotator.remove('alpha');

这会绕过任何可能更靠近选区光标的其他注解,并删除那些是 alpha 注解的注解。如果没有该名称的注解,它将不执行任何操作。完整的 API 如下:

/**
* Removes any annotations from the current selection that match
* the name
*
* @param remove
* @param {String} name the name of the annotation to remove
*/
remove: (name)

支持的内容

  • 文本

  • 块

Comments 在 TinyMCE 6.1 及更高版本中支持以下功能: