From 6414bec0238dbcd7098cd0820e8d53abadca8bbb Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 30 Jun 2023 16:48:13 +0200 Subject: [PATCH 1/4] BUGFIX: 3557 placeholder plugin with autoparagraph false --- .../neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js index 50cce23673..fd73888a19 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js +++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js @@ -9,7 +9,7 @@ const htmlIsEmptyish = data => { return true; } - if (data.length > 20) { + if (data.length > 50) { return false; } const value = data.replace(/[\n|\t|\u200b]*/g, '').toLowerCase().trim(); @@ -17,6 +17,7 @@ const htmlIsEmptyish = data => { !value || value === '
' || value === ' ' || + value === ' ' || value === '

 

' || value === '

 

' || value === '


' || From c8c17d18ec17a4196c96d03819ada0defdc648e1 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 3 Jul 2023 10:32:05 +0200 Subject: [PATCH 2/4] BUGFIX: Migrate to native ckeditor placeholder feature explanation: https://github.com/neos/neos-ui/pull/3558#issuecomment-1617527199 https://ckeditor.com/docs/ckeditor5/16.0.0/api/module_core_editor_editorconfig-EditorConfig.html#member-placeholder --- .../src/ckEditorApi.js | 1 + .../src/manifest.config.js | 25 ++++-- .../src/placeholder.vanilla-css | 8 ++ .../src/plugins/neosPlaceholder.js | 76 ------------------- .../src/plugins/neosPlaceholder.vanilla-css | 5 -- .../tests/manual/index.html | 1 + 6 files changed, 29 insertions(+), 87 deletions(-) create mode 100644 packages/neos-ui-ckeditor5-bindings/src/placeholder.vanilla-css delete mode 100644 packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js delete mode 100644 packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.vanilla-css diff --git a/packages/neos-ui-ckeditor5-bindings/src/ckEditorApi.js b/packages/neos-ui-ckeditor5-bindings/src/ckEditorApi.js index 6c880347cd..74e919bfc7 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/ckEditorApi.js +++ b/packages/neos-ui-ckeditor5-bindings/src/ckEditorApi.js @@ -2,6 +2,7 @@ import debounce from 'lodash.debounce'; import DecoupledEditor from '@ckeditor/ckeditor5-editor-decoupled/src/decouplededitor'; import {actions} from '@neos-project/neos-ui-redux-store'; import {cleanupContentBeforeCommit} from './cleanupContentBeforeCommit' +import './placeholder.vanilla-css'; // eslint-disable-line no-unused-vars let currentEditor = null; let editorConfig = {}; diff --git a/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js b/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js index 09bbb788be..c50b5fbc2b 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js +++ b/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js @@ -1,7 +1,7 @@ import CkEditorConfigRegistry from './registry/CkEditorConfigRegistry'; import {$add, $get, $or} from 'plow-js'; +import {stripTags} from '@neos-project/utils-helpers'; -import NeosPlaceholder from './plugins/neosPlaceholder'; import InlineMode from './plugins/inlineMode'; import Sub from './plugins/sub'; import Sup from './plugins/sup'; @@ -82,11 +82,9 @@ export default ckEditorRegistry => { // // Base CKE configuration // - config.set('baseConfiguration', (ckEditorConfiguration, {globalRegistry, editorOptions, userPreferences}) => { - const i18nRegistry = globalRegistry.get('i18n'); + config.set('baseConfiguration', (ckEditorConfiguration, {userPreferences}) => { return Object.assign(ckEditorConfiguration, { - language: String($get('interfaceLanguage', userPreferences)), - neosPlaceholder: unescape(i18nRegistry.translate($get('placeholder', editorOptions) || '')) + language: String($get('interfaceLanguage', userPreferences)) }); }); @@ -96,7 +94,6 @@ export default ckEditorRegistry => { config.set('essentials', addPlugin(Essentials)); config.set('paragraph', addPlugin(Paragraph)); config.set('inlineMode', addPlugin(InlineMode, disableParagraph)); - config.set('neosPlaceholder', addPlugin(NeosPlaceholder)); config.set('sub', addPlugin(Sub, $get('formatting.sub'))); config.set('sup', addPlugin(Sup, $get('formatting.sup'))); config.set('bold', addPlugin(Bold, $get('formatting.strong'))); @@ -147,5 +144,21 @@ export default ckEditorRegistry => { ]} })); + // + // @see https://ckeditor.com/docs/ckeditor5/16.0.0/api/module_core_editor_editorconfig-EditorConfig.html#member-placeholder + // + config.set('placeholder', (config, {globalRegistry, editorOptions}) => { + const i18nRegistry = globalRegistry.get('i18n'); + const placeholder = $get('placeholder', editorOptions); + if (!placeholder) { + return config; + } + return { + ...config, + // stripTags, because we allow `

Edit text here

` as placeholder for legacy + placeholder: stripTags(i18nRegistry.translate(placeholder)) + }; + }); + return config; }; diff --git a/packages/neos-ui-ckeditor5-bindings/src/placeholder.vanilla-css b/packages/neos-ui-ckeditor5-bindings/src/placeholder.vanilla-css new file mode 100644 index 0000000000..7249952164 --- /dev/null +++ b/packages/neos-ui-ckeditor5-bindings/src/placeholder.vanilla-css @@ -0,0 +1,8 @@ +.ck.ck-placeholder:before, .ck .ck-placeholder:before { + content: attr(data-placeholder); + + /* See ckeditor/ckeditor5#469. */ + pointer-events: none; + + color: #999; +} diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js deleted file mode 100644 index fd73888a19..0000000000 --- a/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.js +++ /dev/null @@ -1,76 +0,0 @@ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import {stripTags} from '@neos-project/utils-helpers'; -import styles from './neosPlaceholder.vanilla-css'; // eslint-disable-line no-unused-vars - -// If the data is "empty" (BR, P) or the placeholder then return an empty string. -// Otherwise return the original data -const htmlIsEmptyish = data => { - if (!data) { - return true; - } - - if (data.length > 50) { - return false; - } - const value = data.replace(/[\n|\t|\u200b]*/g, '').toLowerCase().trim(); - const a = ( - !value || - value === '
' || - value === ' ' || - value === ' ' || - value === '

 

' || - value === '

 

' || - value === '


' || - value === ' ' || - value === ' 
' || - value === '
' || - value.match(/^<([a-z0-9]+)>
<\/\1>$/) - ); - return a; -}; - -export default class NeosPlaceholder extends Plugin { - static get pluginName() { - return 'NeosPlaceholder'; - } - - getPlaceholder() { - return stripTags(this.editor.config.get('neosPlaceholder')); - } - - addPlaceholder() { - this.editor.editing.view.change(writer => { - writer.setAttribute('data-neos-placeholder', this.getPlaceholder(), this.editor.editing.view.document.getRoot()); - }); - } - - removePlaceholder() { - this.editor.editing.view.change(writer => { - writer.removeAttribute('data-neos-placeholder', this.editor.editing.view.document.getRoot()); - }); - } - - updatePlaceholder() { - if (htmlIsEmptyish(this.editor.getData({trim: 'none'})) && !this.editor.ui.focusTracker.isFocused) { - this.addPlaceholder(); - } else { - this.removePlaceholder(); - } - } - - init() { - if (this.editor.config.get('neosPlaceholder')) { - this.updatePlaceholder(); - - const model = this.editor.data.model; - - model.on('applyOperation', () => { - this.updatePlaceholder(); - return true; - }); - this.editor.ui.focusTracker.on('change:isFocused', () => { - this.updatePlaceholder(); - }); - } - } -} diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.vanilla-css b/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.vanilla-css deleted file mode 100644 index a70a2b13ef..0000000000 --- a/packages/neos-ui-ckeditor5-bindings/src/plugins/neosPlaceholder.vanilla-css +++ /dev/null @@ -1,5 +0,0 @@ -[data-neos-placeholder]:before { - color: #999; - content: attr(data-neos-placeholder); - cursor: text; -} diff --git a/packages/neos-ui-ckeditor5-bindings/tests/manual/index.html b/packages/neos-ui-ckeditor5-bindings/tests/manual/index.html index 2f9831bb83..1f2bf8b006 100644 --- a/packages/neos-ui-ckeditor5-bindings/tests/manual/index.html +++ b/packages/neos-ui-ckeditor5-bindings/tests/manual/index.html @@ -3,6 +3,7 @@ + CKEditor Manual Test From 1234d9a0dc07239f66d833b1c6cd5d8329fd535d Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:32:40 +0200 Subject: [PATCH 3/4] BUGFIX: ckeditor `editor.getData` contains `` --- .../src/cleanupContentBeforeCommit.js | 23 +----------- .../src/cleanupContentBeforeCommit.spec.js | 26 ------------- .../src/plugins/inlineMode.js | 37 ++++++++++++++++++- .../src/plugins/inlineMode.spec.js | 31 ++++++++++++++++ 4 files changed, 68 insertions(+), 49 deletions(-) create mode 100644 packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.spec.js diff --git a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js index 4efa9cb2f6..a9b6d0c3f7 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js +++ b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.js @@ -1,28 +1,9 @@ -// We remove opening and closing span tags that are produced by the inlineMode plugin + +// 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 ''; } - - 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/cleanupContentBeforeCommit.spec.js b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js index 08ab6aad9e..8fcc51b1d0 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js +++ b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js @@ -8,29 +8,3 @@ test('remove empty nbsp', () => { assertCleanedUpContent('

 

', ''); assertCleanedUpContent(' ', ''); }) - -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/inlineMode.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js index 54540cb393..096b9afb7e 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js +++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js @@ -14,8 +14,7 @@ export default class InlineMode extends Plugin { // 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' and strip the custom tag 'neos-inline-wrapper' - // in a hacky cleanup in cleanupContentBeforeCommit + // 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'); @@ -26,6 +25,12 @@ export default class InlineMode extends Plugin { 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'); @@ -35,3 +40,31 @@ export default class InlineMode extends Plugin { }, {priority: 'high'}); } } + +/** + * 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/inlineMode.spec.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.spec.js new file mode 100644 index 0000000000..f48739226c --- /dev/null +++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.spec.js @@ -0,0 +1,31 @@ +import {cleanupNeosInlineWrapper} from './inlineMode' + +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'); + }) +}) From 19402f29011e4c2420c798015bc03ca7defd8eac Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:36:28 +0200 Subject: [PATCH 4/4] TASK: Apply suggestion from code review --- .../src/cleanupContentBeforeCommit.spec.js | 2 +- .../src/manifest.config.js | 29 +++++++------------ .../src/plugins/cleanupNeosInlineWrapper.js | 27 +++++++++++++++++ ...ec.js => cleanupNeosInlineWrapper.spec.js} | 2 +- .../src/plugins/inlineMode.js | 29 +------------------ 5 files changed, 40 insertions(+), 49 deletions(-) create mode 100644 packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js rename packages/neos-ui-ckeditor5-bindings/src/plugins/{inlineMode.spec.js => cleanupNeosInlineWrapper.spec.js} (95%) diff --git a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js index 8fcc51b1d0..08e5603a64 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js +++ b/packages/neos-ui-ckeditor5-bindings/src/cleanupContentBeforeCommit.spec.js @@ -1,4 +1,4 @@ -import {cleanupContentBeforeCommit} from './cleanupContentBeforeCommit' +import {cleanupContentBeforeCommit} from './cleanupContentBeforeCommit'; const assertCleanedUpContent = (input, expected) => { expect(cleanupContentBeforeCommit(input)).toBe(expected); diff --git a/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js b/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js index c50b5fbc2b..718fe1399a 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js +++ b/packages/neos-ui-ckeditor5-bindings/src/manifest.config.js @@ -81,11 +81,18 @@ export default ckEditorRegistry => { // // Base CKE configuration + // - configuration of language + // - and placeholder feature see https://ckeditor.com/docs/ckeditor5/16.0.0/api/module_core_editor_editorconfig-EditorConfig.html#member-placeholder // - config.set('baseConfiguration', (ckEditorConfiguration, {userPreferences}) => { - return Object.assign(ckEditorConfiguration, { + config.set('baseConfiguration', (ckEditorConfiguration, {globalRegistry, editorOptions, userPreferences}) => { + const i18nRegistry = globalRegistry.get('i18n'); + const placeholder = $get('placeholder', editorOptions); + return { + ...ckEditorConfiguration, + // stripTags, because we allow `

Edit text here

` as placeholder for legacy + placeholder: placeholder ? stripTags(i18nRegistry.translate(placeholder)) : undefined, language: String($get('interfaceLanguage', userPreferences)) - }); + }; }); // @@ -144,21 +151,5 @@ export default ckEditorRegistry => { ]} })); - // - // @see https://ckeditor.com/docs/ckeditor5/16.0.0/api/module_core_editor_editorconfig-EditorConfig.html#member-placeholder - // - config.set('placeholder', (config, {globalRegistry, editorOptions}) => { - const i18nRegistry = globalRegistry.get('i18n'); - const placeholder = $get('placeholder', editorOptions); - if (!placeholder) { - return config; - } - return { - ...config, - // stripTags, because we allow `

Edit text here

` as placeholder for legacy - placeholder: stripTags(i18nRegistry.translate(placeholder)) - }; - }); - return config; }; diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js new file mode 100644 index 0000000000..24498ce2d1 --- /dev/null +++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.js @@ -0,0 +1,27 @@ +/** + * 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/inlineMode.spec.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.spec.js similarity index 95% rename from packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.spec.js rename to packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.spec.js index f48739226c..4aa01d60c0 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.spec.js +++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/cleanupNeosInlineWrapper.spec.js @@ -1,4 +1,4 @@ -import {cleanupNeosInlineWrapper} from './inlineMode' +import {cleanupNeosInlineWrapper} from './cleanupNeosInlineWrapper'; const assertCleanedUpContent = (input, expected) => { expect(cleanupNeosInlineWrapper(input)).toBe(expected); diff --git a/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js index 096b9afb7e..17b749d0d5 100644 --- a/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js +++ b/packages/neos-ui-ckeditor5-bindings/src/plugins/inlineMode.js @@ -1,4 +1,5 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import {cleanupNeosInlineWrapper} from './cleanupNeosInlineWrapper'; /** * HACK, since there is yet no native support @@ -40,31 +41,3 @@ export default class InlineMode extends Plugin { }, {priority: 'high'}); } } - -/** - * 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; -};