diff --git a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js
index a9b6d0c3f7..3ce6672bcd 100644
--- a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js
+++ b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js
@@ -1,9 +1,23 @@
-
-// TODO: remove when this is fixed: https://github.com/ckeditor/ckeditor5/issues/401
/** @param {String} content */
export const cleanupContentBeforeCommit = content => {
+ // TODO: remove when this is fixed: https://github.com/ckeditor/ckeditor5/issues/401
if (content.match(/^<([a-z][a-z0-9]*)\b[^>]*> <\/\1>$/)) {
return '';
}
+
+ // We remove opening and closing span tags that are produced by the `DisabledAutoparagraphMode` plugin
+ if (content.startsWith('') && content.endsWith('')) {
+ const contentWithoutOuterSpan = content
+ .replace(/^/, '')
+ .replace(/<\/span>$/, '');
+
+ if (contentWithoutOuterSpan.includes('')) {
+ // In case there is still a span tag, we can be sure that the previously trimmed ones were belonging together,
+ // as it could be the case that multiple root paragraph/span elements were inserted into the ckeditor
+ // (which is currently not prevented if the html is modified from outside), so we will preserve the output.
+ return content;
+ }
+ return contentWithoutOuterSpan;
+ }
return content;
};
diff --git a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js
index 08e5603a64..4e2ef3ccc4 100644
--- a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js
+++ b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js
@@ -8,3 +8,28 @@ test('remove empty nbsp', () => {
assertCleanedUpContent('
', '');
assertCleanedUpContent(' ', '');
})
+
+describe('ckeditor DisabledAutoparagraphMode hack, cleanup outer spans', () => {
+ test('noop', () => {
+ assertCleanedUpContent('', '');
+
+ assertCleanedUpContent('', '');
+
+ assertCleanedUpContent('foo', 'foo');
+ })
+
+ test('cleanup single root ', () => {
+ assertCleanedUpContent('', '');
+ assertCleanedUpContent('foo', 'foo');
+ })
+
+
+ test('cleanup multiple root ', () => {
+ assertCleanedUpContent('foobar', 'foobar');
+ })
+
+ test('cleanup root after other root', () => {
+ // in the case you had multiple paragraphs and a headline and switched to autoparagraph: false
+ assertCleanedUpContent('foo
bar', 'foo
bar');
+ })
+})
diff --git a/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js b/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js
index 718fe1399a..0ef6c2391c 100644
--- a/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js
+++ b/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js
@@ -2,7 +2,7 @@ import CkEditorConfigRegistry from './registry/CkEditorConfigRegistry';
import {$add, $get, $or} from 'plow-js';
import {stripTags} from '@neos-project/utils-helpers';
-import InlineMode from './plugins/inlineMode';
+import DisabledAutoparagraphMode from './plugins/disabledAutoparagraphMode';
import Sub from './plugins/sub';
import Sup from './plugins/sup';
import LinkTargetBlank from './plugins/linkTargetBlank';
@@ -33,7 +33,7 @@ const addPlugin = (Plugin, isEnabled) => (ckEditorConfiguration, options) => {
// If the editable is a span or a heading, we automatically disable paragraphs and enable the soft break mode
// Also possible to force this behavior with `autoparagraph: false`
-const disableParagraph = (editorOptions, {propertyDomNode}) =>
+const disableAutoparagraph = (editorOptions, {propertyDomNode}) =>
$get('autoparagraph', editorOptions) === false ||
propertyDomNode.tagName === 'SPAN' ||
propertyDomNode.tagName === 'H1' ||
@@ -100,7 +100,7 @@ export default ckEditorRegistry => {
//
config.set('essentials', addPlugin(Essentials));
config.set('paragraph', addPlugin(Paragraph));
- config.set('inlineMode', addPlugin(InlineMode, disableParagraph));
+ config.set('disabledAutoparagraphMode', addPlugin(DisabledAutoparagraphMode, disableAutoparagraph));
config.set('sub', addPlugin(Sub, $get('formatting.sub')));
config.set('sup', addPlugin(Sup, $get('formatting.sup')));
config.set('bold', addPlugin(Bold, $get('formatting.strong')));
diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js
deleted file mode 100644
index 24498ce2d1..0000000000
--- a/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * We remove opening and closing span tags that are produced by the inlineMode plugin
- *
- * @private only exported for testing
- * @param {String} content
- */
-export const cleanupNeosInlineWrapper = content => {
- if (content.includes('')) {
- let contentWithoutOuterInlineWrapper = content;
-
- if (content.startsWith('') && content.endsWith('')) {
- contentWithoutOuterInlineWrapper = content
- .replace(/^/, '')
- .replace(/<\/neos-inline-wrapper>$/, '');
- }
-
- if (contentWithoutOuterInlineWrapper.includes('')) {
- // in the case, multiple root paragraph elements were inserted into the ckeditor (wich is currently not prevented if the html is modified from outside)
- // we have multiple root elements of type . We will convert all of them into spans.
- return content
- .replace(//g, '')
- .replace(/<\/neos-inline-wrapper>/g, '');
- }
- return contentWithoutOuterInlineWrapper;
- }
- return content;
-};
diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.spec.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.spec.js
deleted file mode 100644
index 4aa01d60c0..0000000000
--- a/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import {cleanupNeosInlineWrapper} from './cleanupNeosInlineWrapper';
-
-const assertCleanedUpContent = (input, expected) => {
- expect(cleanupNeosInlineWrapper(input)).toBe(expected);
-}
-
-describe('ckeditor inline mode hack, cleanup ', () => {
- test('noop', () => {
- assertCleanedUpContent('', '');
-
- assertCleanedUpContent('', '');
- })
-
- test('cleanup single ', () => {
- assertCleanedUpContent('', '');
- assertCleanedUpContent('foo', 'foo');
-
- assertCleanedUpContent('foo', 'foo');
- })
-
- test('cleanup multiple ', () => {
- assertCleanedUpContent('foobar', 'foobar');
-
- assertCleanedUpContent('foobar', 'foobar');
- })
-
- test('cleanup after other root', () => {
- // in the case you had multiple paragraphs and a headline and switched to autoparagrahp: false
- assertCleanedUpContent('foo
bar', 'foo
bar');
- })
-})
diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/disabledAutoparagraphMode.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/disabledAutoparagraphMode.js
new file mode 100644
index 0000000000..dd87ff9497
--- /dev/null
+++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/disabledAutoparagraphMode.js
@@ -0,0 +1,27 @@
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+
+/**
+ * HACK, since there is yet no native support for CKEditor 4 autoparagraph false
+ * see https://github.com/ckeditor/ckeditor5/issues/762
+ *
+ * We will try to find a serious alternative see https://github.com/neos/neos-ui/pull/3553
+ */
+export default class DisabledAutoparagraphMode extends Plugin {
+ static get pluginName() {
+ return 'DisabledAutoparagraphMode';
+ }
+ init() {
+ const editor = this.editor;
+
+ // we map paragraph model into plain element
+ editor.conversion.for('downcast').elementToElement({model: 'paragraph', view: 'span', converterPriority: 'high'});
+
+ // we redefine enter key to create soft breaks (
) instead of new paragraphs
+ editor.editing.view.document.on('enter', (evt, data) => {
+ editor.execute('shiftEnter');
+ data.preventDefault();
+ evt.stop();
+ editor.editing.view.scrollToTheSelection();
+ }, {priority: 'high'});
+ }
+}
diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js
deleted file mode 100644
index 17b749d0d5..0000000000
--- a/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import {cleanupNeosInlineWrapper} from './cleanupNeosInlineWrapper';
-
-/**
- * HACK, since there is yet no native support
- * see https://github.com/ckeditor/ckeditor5/issues/762
- */
-export default class InlineMode extends Plugin {
- static get pluginName() {
- return 'InlineMode';
- }
- init() {
- const editor = this.editor;
-
- // we map paragraph model into plain element in edit mode
- editor.conversion.for('editingDowncast').elementToElement({model: 'paragraph', view: 'span', converterPriority: 'high'});
-
- // to avoid having a wrapping "span" tag, we will convert the outmost 'paragraph' ...
- // see https://neos-project.slack.com/archives/C07QEQ1U2/p1687952441254759 - i could find a better solution
- editor.conversion.for('dataDowncast').elementToElement({model: 'paragraph', view: ( modelElement, viewWriter ) => {
- const parentIsRoot = modelElement.parent.is('$root');
- const hasAttributes = [...modelElement.getAttributes()].length !== 0;
- if (!parentIsRoot || hasAttributes) {
- return viewWriter.createContainerElement('span');
- }
- return viewWriter.createContainerElement('neos-inline-wrapper');
- }, converterPriority: 'high'});
-
- // ... and strip the custom tag 'neos-inline-wrapper' in a hacky cleanup in cleanupData
- editor.data.decorate('get');
- editor.data.on('get', (event) => {
- event.return = cleanupNeosInlineWrapper(event.return)
- });
-
- // we redefine enter key to create soft breaks (
) instead of new paragraphs
- editor.editing.view.document.on('enter', (evt, data) => {
- editor.execute('shiftEnter');
- data.preventDefault();
- evt.stop();
- editor.editing.view.scrollToTheSelection();
- }, {priority: 'high'});
- }
-}