Important changes to Tiny Cloud pricing > Find out more

NOTE: TinyMCE 5 reached End of Support in April 2023. No more bug fixes, security updates, or new features will be introduced to TinyMCE 5. We recommend you upgrade to TinyMCE 6 or consider TinyMCE 5 Long Term Support (LTS) if you need more time.

Context toolbar

Context toolbar overview

Contribute to this page

A context toolbar can only contain either buttons that are defined for a normal toolbar, or buttons specifically registered for launching a ContextForm. The buttons comes as a list of strings, where each string is a registered name of a button.

Registering a context toolbar

A context toolbar is registered by calling the addContextToolbar API in the registry. The specification is as follows:

Name Description
predicate This controls when the context toolbar will appear
position This controls where the context toolbar will appear with regards to the current cursor
scope This controls whether the predicate is a node-based predicate, or an editor-based predicate. See context toolbar proirity section below, for more details.
items A list of strings which represent either a registered toolbar button, or a registered context form launcher.

Positioning of context toolbars

There are three options for positioning context toolbars: selection, node, or line.

  • A selection position will place the context toolbar above or below the current selection, centered if possible.

  • A node position will place the context toolbar above or below the bounds of a node (e.g. a table or image).

  • A line position will place the context toolbar to the right (or left in Right-to-Left languages) of the current selection.

Example configuration

This example shows how the quickbars plugin adds the standard selection context toolbar and an example of a custom toolbar for image alignment. The context toolbar will show whenever any content is selected.


tinymce.init({
  selector: 'textarea#context-toolbar',
  height: 350,
  setup: function (editor) {
    editor.ui.registry.addContextToolbar('imagealignment', {
      predicate: function (node) {
        return node.nodeName.toLowerCase() === 'img'
      },
      items: 'alignleft aligncenter alignright',
      position: 'node',
      scope: 'node'
    });

    editor.ui.registry.addContextToolbar('textselection', {
      predicate: function (node) {
        return !editor.selection.isCollapsed();
      },
      items: 'bold italic | blockquote',
      position: 'selection',
      scope: 'node'
    });
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
});

Launching a context toolbar programmatically

There is an editor event called contexttoolbar-show that can be fired to show a context toolbar at the current selection. The event takes a parameter toolbarKey which specifies the name of the registered context form or context toolbar to show.

Troubleshooting context toolbar and context form conflicts

There are situations where custom context toolbars or custom context forms may conflict with:

  • Context toolbars or context forms provided by the editor,
  • Context toolbars or context forms provided by the Quick Toolbars (quickbars) plugin,
  • Other custom context toolbars or custom context forms.

How these conflicts are resolved depends on the TinyMCE version.

Determining the display priority of context toolbars and context forms

There are three settings that determine the priority of context toolbars and context forms: scope, predicate, and position.

  • scope - Sets the context toolbar or form as either: specific to certain types of content (node), or a general (global) toolbar or form (editor).
  • predicate - A function for determining if the context menu or form applies to the current selection or cursor position. This function should return a boolean value.
  • position - Sets where the context toolbar or form is rendered, relative to the current context (selection, node, or line).

Generally:

  • Context forms are prioritized over context toolbars.
  • Context forms with scope: 'node' are prioritized over scope: 'editor'.
  • Only one context form can be shown for a selection or cursor position, they cannot be concatenated to another context form or a context toolbar.
  • Context toolbars with position: 'selection' are prioritized over position: 'node', and position: 'line' is given the lowest priority.
  • The editor concatenates context toolbars when there is more than one context toolbar to display with:

    • A matching predicate,
    • The same scope and position values.

    Concatenated toolbars may contain duplicate toolbar items.

  • If no matching context toolbars or context forms are found for the selection or cursor position, then editor will recursively search for matches on the parent node of the current node, until it reaches the root node of the editor content.

Description of how context toolbars and context forms are prioritized

The following description can be used for troubleshooting the behavior of context toolbars and context forms.

The editor will determine which context toolbars or context form will be shown using following process:

  1. Find all context forms with both:

    • scope: 'node'
    • A predicate matching the current selection or cursor position.

    If there are any matching context forms, the first one found will be displayed in the editor and the process will end.

  2. Find all context forms with both:

    • scope: 'editor'
    • A predicate matching the current selection or cursor position.

    If there are any matching context forms, the first one found will be displayed in the editor and the process will end.

  3. Find all context toolbars with both:

    • Any scope
    • A predicate matching the current selection or cursor position.

    If there are any matching context toolbars, the editor will prioritize the context toolbars based on the position value.

    • All context toolbars with position: 'selection' or position: 'node' will be concatenated, the concatenated toolbar will be displayed, and the process will end.
    • Otherwise, all context toolbars with position: line will be concatenated, the concatenated toolbar will be displayed, and the process will end.
  4. Find all context forms with both:

    • Any scope
    • A predicate matching the parent node of the current node, selection, or cursor position.

    If there are any context forms found, the first one found will be displayed in the editor and the process will end.

  5. Find all context toolbars with both:

    • Any scope
    • A predicate matching the parent node of the current node, selection, or cursor position.

    If there are any matching context toolbars, the editor will prioritize the context toolbars based on the position value.

    • If there are context toolbars with position: 'selection', they will be concatenated, the concatenated toolbar will be displayed, and the process will end.
    • If there are context toolbars with position: 'node', they will be concatenated, the concatenated toolbar will be displayed, and the process will end.
    • Otherwise, all context toolbars with position: line will be concatenated, the concatenated toolbar will be displayed, and the process will end.
  6. Repeat step 4 and 5 for each successive parent node in the DOM for context toolbars and context forms with scope: node until either:

    • A matching context form or context toolbars are found and displayed,
    • The root node of the editor is reached.

Determining the display priority of context toolbars and context forms (Legacy behavior)

There are two settings that determine determine the priority: predicate and scope. The priority system mirrors the old inlite theme from TinyMCE 4. The predicate is a function that takes in the current context position and returns a boolean. The scope is either node or editor. The whole priority process works as follows:

  1. The current cursor position is stored to use as the first current context position.
  2. For this current context position, each predicate with scope: node in the registered ContextForm is called. Currently, the order they are checked-in cannot be specified. The first predicate that passes will win and that ContextForm will be shown.
  3. If no predicates (scope: node) match the current context position, then all of the scope: editor predicates are tried. The first one that matches the editor context wins.
  4. If no scope: editor predicates match, then the new context position is calculated by going up the tree one level to the parent node. All scope: node predicates are then checked again. As soon as one matches, it wins and that ContextForm is shown. If nothing matches, it goes up the tree and tries again.

Note: Only scope: node predicates are checked at this stage. The scope: editor predicate is only checked once and that check only happens in (2).

Caution: Since the order in which the ContextForms and ContextToolbars are checked is not specified, try not to have their predicates overlap.

Can't find what you're looking for? Let us know.

Except as otherwise noted, the content of this page is licensed under the Creative Commons BY-NC-SA 3.0 License, and code samples are licensed under the Apache 2.0 License.