Commands, Events and APIs for the Comments plugin

Commands

The Comments plugin provides the following TinyMCE commands.

Command Description

tc-delete-conversation-at-cursor

Attempts to delete the comment at the current cursor position. A confirmation dialog will be shown prior to deletion.

tc-try-delete-all-conversations

Attempts to delete all comments in the editor. A confirmation dialog will be shown prior to deletion.

Examples
tinymce.activeEditor.execCommand('tc-delete-conversation-at-cursor');
tinymce.activeEditor.execCommand('tc-try-delete-all-conversations');

Events

The following events are provided by the Tiny Comments plugin.

Name Data Description

mce-tinycomments-update

N/A

Fired when the comments sidebar is opened or closed.

CommentChange

{ getEventLog: () ⇒ EventLog[] }

Fired when a comment is added, resolved, deleted, edited, or replied to.

CommentChange event

This feature is only available for TinyMCE 6.1 and later.

Fired when a comment is added, resolved, deleted, edited, or replied to. Contains the getEventLog API for retrieving log of comment changes.

Example: the CommentChange event

tinymce.init({
  selector: 'textarea',
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  init_instance_callback: (editor) => {
    editor.on('CommentChange', (evt) => {
      console.log(evt.getEventLog());
    });
  }
});

APIs

The Comments plugin provides the getEventLog() API, as well as an annotator named 'tinycomments' created using the editor.annotator API.

getEventLog()

This feature is only available for TinyMCE 6.1 and later.

The getEventLog returns a log that contains information and timestamps of all changes to comments, including when:

  • A new comment is added.

{
  "type": "create",
  "timestamp": "2024-10-01T03:07:53.771Z",
  "conversationUid": "annotation-r1nn5xdo5ye",
  "conversationContext": "Welcome",
  "conversationContent": "new comment",
  "conversationAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  }
},
  • A comment is edited.

{
  "type": "edit-comment",
  "timestamp": "2024-10-01T03:08:06.551Z",
  "conversationUid": "annotation-r1nn5xdo5ye",
  "commentUid": "annotation-r1nn5xdo5ye",
  "conversationContext": "Welcome",
  "conversationContent": "new comment",
  "conversationCreatedAt": "2024-10-01T03:07:53.771Z",
  "commentContent": "new comment (Edit comment)",
  "commentAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  },
  "conversationAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  }
},
  • A reply to a comment is added.

{
  "type": "reply",
  "timestamp": "2024-10-01T03:07:53.771Z",
  "conversationUid": "annotation-r1nn5xdo5ye",
  "commentUid": "annotation-uh00rb41kma",
  "conversationContext": "Welcome",
  "conversationContent": "new comment (Edit comment)",
  "conversationCreatedAt": "2024-10-01T03:07:53.771Z",
  "commentContent": "reply to existing comment",
  "commentAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  },
  "conversationAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  }
},
  • A comment is resolved.

{
  "type": "resolve",
  "timestamp": "2024-10-01T03:08:25.783Z",
  "conversationUid": "annotation-r1nn5xdo5ye",
  "conversationContext": "Welcome",
  "conversationContent": "new comment (Edit comment)",
  "conversationAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  }
},
  • A comment is deleted.

{
  "type": "delete-comment",
  "timestamp": "2024-10-01T03:08:23.292Z",
  "conversationUid": "annotation-r1nn5xdo5ye",
  "commentUid": "annotation-uh00rb41kma",
  "conversationContext": "Welcome",
  "conversationContent": "new comment (Edit comment)",
  "commentContent": "reply to existing comment",
  "commentAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  },
  "conversationAuthor": {
      "author": "DEMO USER",
      "authorName": "DEMO USER"
  }
},

The event log can be retrieved either in full or with the after option, which restricts the returned list to Comment events after a time-stamp date in the ISO-8601 format, both shown in the following:

With the Mentions plugin

When the Mentions plugin is enabled, each of the above events will include the mentionedUids property, which contains an array of UIDs mentioned in the comment. The mentionedUids property is only included when the Mentions plugin is enabled.

It is recommended to use this API to retrieve which users have been mentioned in comments.

The mentionedUids array captures strings following the @ symbol without verifying if they correspond to valid user IDs. It is the integrator’s responsibility to validate these strings against the database to ensure they represent valid users.

For guidance on retrieving and verifying the mentionedUids array, refer to the getEventLog example.

Example: using getEventLog()

// Sample user database
const userDb = {
    "johnsmith": {
        "id": "johnsmith",
        "name": "John Smith",
        "fullName": "John Smith",
        "description": "Company Founder",
        "image": "https://i.pravatar.cc/150?img=11"
    },
    "jennynichols": {
        "id": "jennynichols",
        "name": "Jenny Nichols",
        "fullName": "Jenny Nichols",
        "description": "Marketing Director",
        "image": "https://i.pravatar.cc/150?img=10"
    }
};

const comments = tinymce.activeEditor.plugins.tinycomments;

console.log(comments.getEventLog());
console.log(comments.getEventLog(
  { after: '2022-02-22T12:34:56Z' }  // ISO-8601 standard: YYYY-MM-DDThh:mm:ssZ
));

const eventLog = comments.getEventLog();
const events = eventLog.events;

// Ensure that the mentioned users are valid users in the database
const validatedEvents = JSON.parse(JSON.stringify(events));
validatedEvents.forEach((event) => {
  // Filter out invalid users - change this to your own validation logic
  event.mentionedUids = event.mentionedUids ? event.mentionedUids.filter((uid) => userDb[uid]) : undefined;
});

const mentionedUsers = validatedEvents.flatMap(({ mentionedUids }) => mentionedUids || []);
console.log(mentionedUsers);

let whoMentionedWho = {};
validatedEvents.forEach((event) => {
  if ((event.type === "create" || event.type === "reply") && event.mentionedUids !== undefined) {
    console.log(event);
    if (whoMentionedWho[event.conversationAuthor.author] === undefined) {
      whoMentionedWho[event.conversationAuthor.author] = [...event.mentionedUids];
    } else {
      whoMentionedWho[event.conversationAuthor.author].push(...event.mentionedUids);
    }
  }
});
console.log(whoMentionedWho);

The 'tinycomments' annotator

The Comments plugin provides an annotator named 'tinycomments', constructed using the editor.annotator API.

The 'tinycomments' annotator is used to annotate content with conversations attached, and is available for use in each of the editor.annotator API methods.

The 'tinycomments' annotator, like all editor APIs, can only be accessed after the editor is initialized.

Example: using the 'tinycomments' annotator to notify when conversations are selected

This example makes use of the annotationChanged method in the editor.annotator API to create a custom notification.

The below notification example displays for five seconds every time any content with a 'tinycomments' annotation is selected.

tinymce.init({
  selector: 'textarea',
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  setup: (editor) => {
    editor.on('init', () => {
      editor.annotator.annotationChanged('tinycomments', (selected, annotatorName, context) => {
        if (selected) {
          editor.notificationManager.open({
            text: `The content you have selected contains a conversation. ${annotatorName}: ${context.uid}.`,
            type: 'info',
            timeout: 5000
          });
        }
      });
    });
  }
});

Example: using the 'tinycomments' annotator to highlight conversations without showing comments

This example makes use of the getAll method in the editor.annotator API to highlight every element annotated by 'tinycomments'.

When the 'highlightcomments' button on the toolbar is toggled on, every annotated element is highlighted aquamarine, without requiring the user to show comments.

tinymce.init({
  selector: 'textarea',
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments highlightcomments',
  setup: (editor) => {
    editor.ui.registry.addToggleButton('highlightcomments', {
      icon: 'highlight-bg-color',
      onAction: (api) => {
        api.setActive(!api.isActive());
        const conversations = editor.annotator.getAll('tinycomments');
        for (const [conversation, elements] of Object.entries(conversations)) {
          elements.forEach((element, _) => {
            if (api.isActive()) {
              element.style.setProperty('background-color', 'aquamarine');
            } else {
              element.style.removeProperty('background-color');
            }
          });
        }
      }
    });
  }
});