import {listen as listenForCommonEvents} from "./common-events";
import {scrollToQueryString} from "./scrolling";
import {listenForDragAndPaste} from "./drop-paste-handling";
+import {getPrimaryToolbar, registerAdditionalToolbars} from "./toolbars";
import {getPlugin as getCodeeditorPlugin} from "./plugin-codeeditor";
import {getPlugin as getDrawioPlugin} from "./plugin-drawio";
}
-/**
- * @param {WysiwygConfigOptions} options
- * @return {{toolbar: string, groupButtons: Object<string, Object>}}
- */
-function buildToolbar(options) {
- const textDirPlugins = options.textDirection === 'rtl' ? 'ltr rtl' : '';
-
- const groupButtons = {
- formatoverflow: {
- icon: 'more-drawer',
- tooltip: 'More',
- items: 'strikethrough superscript subscript inlinecode removeformat'
- },
- listoverflow: {
- icon: 'more-drawer',
- tooltip: 'More',
- items: 'outdent indent'
- },
- insertoverflow: {
- icon: 'more-drawer',
- tooltip: 'More',
- items: 'hr codeeditor drawio media details'
- }
- };
-
- const toolbar = [
- 'undo redo',
- 'styleselect',
- 'bold italic underline forecolor backcolor formatoverflow',
- 'alignleft aligncenter alignright alignjustify',
- 'bullist numlist listoverflow',
- textDirPlugins,
- 'link table imagemanager-insert insertoverflow',
- 'code about fullscreen'
- ];
-
- return {
- toolbar: toolbar.filter(row => Boolean(row)).join(' | '),
- groupButtons,
- };
-}
-
/**
* @param {WysiwygConfigOptions} options
* @return {string}
// Set language
window.tinymce.addI18n(options.language, options.translationMap);
- // Build toolbar content
- const {toolbar, groupButtons: toolBarGroupButtons} = buildToolbar(options);
// BookStack Version
const version = document.querySelector('script[src*="/dist/app.js"]').getAttribute('src').split('?version=')[1];
plugins: gatherPlugins(options),
imagetools_toolbar: 'imageoptions',
contextmenu: false,
- toolbar: toolbar,
+ toolbar: getPrimaryToolbar(options),
content_style: getContentStyle(options),
style_formats,
style_formats_merge: false,
head.innerHTML += fetchCustomHeadContent();
},
setup(editor) {
- for (const [key, config] of Object.entries(toolBarGroupButtons)) {
- editor.ui.registry.addGroupToolbarButton(key, config);
- }
+ registerAdditionalToolbars(editor, options);
getSetupCallback(options)(editor);
},
};
editor.formatter.apply('callout' + newFormat);
});
+
+ // Link selector shortcut
+ editor.shortcuts.add('meta+shift+K', '', function() {
+ window.EntitySelectorPopup.show(function(entity) {
+
+ if (editor.selection.isCollapsed()) {
+ editor.insertContent(editor.dom.createHTML('a', {href: entity.link}, editor.dom.encode(entity.name)));
+ } else {
+ editor.formatter.apply('link', {href: entity.link});
+ }
+
+ editor.selection.collapse(false);
+ editor.focus();
+ })
+ });
}
\ No newline at end of file
--- /dev/null
+/**
+ * @param {WysiwygConfigOptions} options
+ * @return {String}
+ */
+export function getPrimaryToolbar(options) {
+ const textDirPlugins = options.textDirection === 'rtl' ? 'ltr rtl' : '';
+
+ const toolbar = [
+ 'undo redo',
+ 'styleselect',
+ 'bold italic underline forecolor backcolor formatoverflow',
+ 'alignleft aligncenter alignright alignjustify',
+ 'bullist numlist listoverflow',
+ textDirPlugins,
+ 'link table imagemanager-insert insertoverflow',
+ 'code about fullscreen'
+ ];
+
+ return toolbar.filter(row => Boolean(row)).join(' | ');
+}
+
+/**
+ * @param {Editor} editor
+ */
+function registerPrimaryToolbarGroups(editor) {
+ editor.ui.registry.addGroupToolbarButton('formatoverflow', {
+ icon: 'more-drawer',
+ tooltip: 'More',
+ items: 'strikethrough superscript subscript inlinecode removeformat'
+ });
+ editor.ui.registry.addGroupToolbarButton('listoverflow', {
+ icon: 'more-drawer',
+ tooltip: 'More',
+ items: 'outdent indent'
+ });
+ editor.ui.registry.addGroupToolbarButton('insertoverflow', {
+ icon: 'more-drawer',
+ tooltip: 'More',
+ items: 'hr codeeditor drawio media details'
+ });
+}
+
+/**
+ * @param {Editor} editor
+ */
+function registerLinkContextToolbar(editor) {
+ editor.ui.registry.addContextToolbar('linkcontexttoolbar', {
+ predicate(node) {
+ return node.closest('a') !== null;
+ },
+ position: 'node',
+ scope: 'node',
+ items: 'link unlink openlink'
+ });
+}
+
+/**
+ * @param {Editor} editor
+ * @param {WysiwygConfigOptions} options
+ */
+export function registerAdditionalToolbars(editor, options) {
+ registerPrimaryToolbarGroups(editor);
+ registerLinkContextToolbar(editor);
+}
\ No newline at end of file
'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.',
'save_continue' => 'Save Page & Continue',
'callouts_cycle' => '(Keep pressing to toggle through types)',
+ 'link_selector' => 'Link to content',
'shortcuts' => 'Shortcuts',
'shortcut' => 'Shortcut',
'shortcuts_intro' => 'The following shortcuts are available in the editor:',
{{ trans('editor.callouts_cycle') }}
</td>
</tr>
+ <tr>
+ <td>
+ <code>Ctrl</code>+<code>Shift</code>+<code>K</code>
+ </td>
+ <td>
+ <code>Cmd</code>+<code>Shift</code>+<code>K</code>
+ </td>
+ <td>{{ trans('editor.link_selector') }}</td>
+ </tr>
</tbody>
</table>