diff --git a/private/css/cms.balloon-toolbar.css b/private/css/cms.balloon-toolbar.css
index c215260..e58c5eb 100644
--- a/private/css/cms.balloon-toolbar.css
+++ b/private/css/cms.balloon-toolbar.css
@@ -20,6 +20,11 @@
&.show [role="menubar"] {
visibility: visible;
}
+ &.disabled {
+ cursor: not-allowed;
+ pointer-events: none;
+ color: var(--dca-gray-light);
+ }
[role="menubar"] {
padding: 3px;
position: absolute;
diff --git a/private/css/cms.tiptap.css b/private/css/cms.tiptap.css
index 86b2289..048ef2d 100644
--- a/private/css/cms.tiptap.css
+++ b/private/css/cms.tiptap.css
@@ -98,10 +98,11 @@
display: flex;
flex-flow: row wrap;
border: solid 1px var(--dca-gray-light, var(--hairline-color));
- box-shadow: 0 1.5px 1.5px rgba(var(--dca-shadow),.4);
+ box-shadow: 0 1.5px 1.5px rgba(var(--dca-shadow), .4);
color: var(--dca-black, var(--body-fg));
background: var(--dca-white, var(--body-bg));
opacity: 1;
+
div.grouper {
padding: 0;
margin: 0;
@@ -177,6 +178,15 @@
height: 1.2rem;
}
}
+ /* Allow to disable the full menubar */
+ [role="menubar"].disabled {
+ button, [role="button"] {
+ cursor: not-allowed;
+ pointer-events: none;
+ color: var(--dca-gray-light);
+ }
+ }
+
.dropdown-content {
color: var(--dca-black, var(--body-fg));
border-radius: 0;
diff --git a/private/js/cms.tiptap.js b/private/js/cms.tiptap.js
index dc9cb82..f75ab14 100644
--- a/private/js/cms.tiptap.js
+++ b/private/js/cms.tiptap.js
@@ -315,7 +315,7 @@ class CMSTipTapPlugin {
event.stopPropagation();
event.preventDefault();
const button = event.target.closest('button, .dropdown');
- if (button && !button.disabled) {
+ if (button && !button.disabled && !editor.options.el.querySelector('dialog.cms-form-dialog')) {
const action = button.dataset.action;
if (button.classList.contains('dropdown')) {
// Open dropdown
@@ -364,8 +364,6 @@ class CMSTipTapPlugin {
// hide the toolbar
editor.options.element.querySelectorAll('[role="menubar"], [role="button"]')
.forEach((el) => el.classList.remove('show'));
- }
- if (!editor.options.element.contains(document.activeElement)) {
// save the content (is no-op for non-inline calls)
editor.options.save_callback();
}
@@ -400,13 +398,20 @@ class CMSTipTapPlugin {
html += group + this.separator_markup;
}
} else if (item.constructor === Object) {
- const dropdown = this._populateToolbar(editor, item.items, filter);
- // Are there any items in the dropdown?
- if (dropdown.replaceAll(this.separator_markup, '').replaceAll(this.space_markup, '').length > 0) {
- const title = item.title && item.icon ? `title='${item.title}' ` : '';
- const icon = item.icon || item.title;
- html += `${icon}${dropdown}
`;
+ let dropdown;
+
+ if (typeof item.items === 'string') {
+ dropdown = item.items;
+ } else {
+ dropdown = this._populateToolbar(editor, item.items, filter);
+ // Are there any items in the dropdown?
+ if (dropdown.replaceAll(this.separator_markup, '').replaceAll(this.space_markup, '').length === 0) {
+ continue
+ }
}
+ const title = item.title && item.icon ? `title='${item.title}' ` : '';
+ const icon = item.icon || item.title;
+ html += `${icon}${dropdown}
`;
} else {
switch (item) {
case '|':
diff --git a/private/js/tiptap_plugins/cms.balloon-toolbar.js b/private/js/tiptap_plugins/cms.balloon-toolbar.js
index 4af295d..401ae21 100644
--- a/private/js/tiptap_plugins/cms.balloon-toolbar.js
+++ b/private/js/tiptap_plugins/cms.balloon-toolbar.js
@@ -52,8 +52,7 @@ export default class CmsBalloonToolbar {
this.form = null;
} else {
// Add the form dialog only if it is not already open
- this.form = new CmsForm(this.editor.options.element, () => {
- });
+ this.form = new CmsForm(this.editor.options.element, () => {});
const rect = this.toolbar.getBoundingClientRect();
const options = {
x: (rect.left + rect.right) / 2,
diff --git a/private/js/tiptap_plugins/cms.formextension.js b/private/js/tiptap_plugins/cms.formextension.js
index f571599..73621b8 100644
--- a/private/js/tiptap_plugins/cms.formextension.js
+++ b/private/js/tiptap_plugins/cms.formextension.js
@@ -1,5 +1,5 @@
-/* eslint-env es6 */
-/* jshint esversion: 6 */
+/* eslint-env es11 */
+/* jshint esversion: 11 */
/* global document, window, console */
'use strict';
@@ -54,6 +54,8 @@ function addFakeSelection(view) {
// Add meta to trigger the plugin
tr.setMeta("fake-selection", "add");
dispatch(tr);
+ view.dom.parentNode.querySelector('.cms-toolbar')?.classList.add('disabled');
+ view.dom.parentNode.querySelector('.cms-balloon')?.classList.add('disabled');
}
function clearFakeSelection(view) {
@@ -62,6 +64,8 @@ function clearFakeSelection(view) {
// Add meta to trigger the plugin
tr.setMeta("fake-selection", "remove");
dispatch(tr);
+ view.dom.parentNode.querySelector('.cms-toolbar')?.classList.remove('disabled');
+ view.dom.parentNode.querySelector('.cms-balloon')?.classList.remove('disabled');
}
@@ -72,6 +76,9 @@ const FormExtension = Extension.create({
'use strict';
return {
openCmsForm: (action, target) => ({editor, commands}) => {
+ if (editor.options.el.querySelector(`dialog.${action}-form`)) {
+ return false;
+ }
let options;
addFakeSelection(editor.view);
if (target) {
@@ -111,6 +118,7 @@ const FormExtension = Extension.create({
// Populate the form with the current attributes (if existent)
populateForm(formElement, TiptapToolbar[action].attributes(editor), formRepresentation.form);
}
+ dialog.dialog.classList.add(action + '-form');
dialog.open();
formElement.querySelectorAll('form.cms-form .js-linkfield')
.forEach((el) => {