Context toolbar
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 |
---|---|
|
This controls when the context toolbar will appear |
|
This controls where the context toolbar will appear with regards to the current cursor |
|
This controls whether the predicate (condition) is a |
|
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
-
HTML
-
JS
-
Edit on CodePen
<textarea id="context-toolbar">
<p>Clicking on the example image below will show the newly configured context toolbar.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<p>Select a word in this sentence, to see the other newly configured context toolbar.</p>
<p>Clicking on text should not invoke the context toolbar</p>
</textarea>
tinymce.init({
selector: 'textarea#context-toolbar',
height: 350,
setup: (editor) => {
editor.ui.registry.addContextToolbar('imagealignment', {
predicate: (node) => node.nodeName.toLowerCase() === 'img',
items: 'alignleft aligncenter alignright',
position: 'node',
scope: 'node'
});
editor.ui.registry.addContextToolbar('textselection', {
predicate: (node) => !editor.selection.isCollapsed(),
items: 'bold italic | blockquote',
position: 'selection',
scope: 'node'
});
},
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
Add labels and groups for context toolbar buttons
From TinyMCE 7.6.0 onward, registering a context toolbar allows specifying items
as an object that supports grouping with optional names and labels. This improvement enhances toolbar usability by organizing buttons into titled or labeled groups.
The object structure takes two optional properties: name
and label
.
-
name
: property is used as the group’s title for the group that contains the buttons. -
label
: property is used as a label for each group of buttons.
If neither name nor label are specified, the behavior defaults to ungrouped buttons.
|
The object structure for items
is as follows:
items: [
{
name: 'Formatting', // Optional, used as the group's title
items: [ 'bold', 'italic' ] // Array of registered button names
},
{
label: 'History', // Optional, used as a label for the group
items: [ 'undo', 'redo' ] // Array of registered button names
},
{
items: [ 'undo', 'italic' ] // No name or label specified, default behavior applies
}
]
-
TinyMCE
-
HTML
-
JS
-
Edit on CodePen
<textarea id="context-toolbar-labels">
<p>Clicking on the example image below will show the newly configured context toolbar.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<p>Select a word in this sentence, to see the other newly configured context toolbar.</p>
<p>Clicking on text should not invoke the context toolbar</p>
</textarea>
tinymce.init({
selector: 'textarea#context-toolbar-labels',
height: 350,
setup: (editor) => {
editor.ui.registry.addContextToolbar('imagealignment', {
predicate: (node) => node.nodeName.toLowerCase() === 'img',
position: 'node',
scope: 'node',
items: [
{
name: 'Formatting',
items: ['alignleft', 'aligncenter', 'alignright']
},
{
label: 'Copy',
items: ['copy', 'paste']
}
],
});
editor.ui.registry.addContextToolbar('textselection', {
predicate: (node) => !editor.selection.isCollapsed(),
position: 'selection',
scope: 'node',
items: [
{
name: 'Format',
items: ['bold', 'italic', 'underline']
},
],
});
},
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
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.
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
- The predicate is the condition(s) where the context toolbar or form should be shown. This setting is 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
, orline
).
Generally:
-
Context forms are prioritized over context toolbars.
-
Context forms with
scope: 'node'
are prioritized overscope: '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 overposition: 'node'
, andposition: '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
andposition
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:
-
Find all context forms with both:
-
scope: 'node'
-
A predicate (condition) 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.
-
-
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.
-
-
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'
orposition: '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.
-
-
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.
-
-
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.
-
-
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.
-