diff options
author | Daniel Kesselberg <mail@danielkesselberg.de> | 2022-09-06 13:52:38 +0300 |
---|---|---|
committer | Daniel Kesselberg <mail@danielkesselberg.de> | 2022-09-20 12:17:29 +0300 |
commit | 64d29b09ded34546be4350ced162fd59009de9bb (patch) | |
tree | 857f74fd7c13a83440e5576fd5f05356d5388e2d | |
parent | 80c51d84e85baa7e6dce6dc526f91e1384554259 (diff) |
GH-7141: Add ckeditor plugin for mail
**Add mail plugin**
Move conversion for paragraph to `<p style="margin:0;"></p>` to plugin
**Drop schema listener for `<blockQuote>`**
Older versions of ckeditor did not support nested blockquotes[^1].
The schema listener is a workaround to keep nested blockquotes[^2].
CKEditor 28 added support for nested blockquotes back[^3][^4].
[^1]: https://github.com/ckeditor/ckeditor5/issues/419#issuecomment-518792442
[^2]: https://github.com/ckeditor/ckeditor5/issues/419#issuecomment-519013086
[^3]: https://github.com/ckeditor/ckeditor5/pull/9382
[^4]: https://github.com/ckeditor/ckeditor5/pull/9472
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
-rw-r--r-- | src/ckeditor/mail/MailPlugin.js | 53 | ||||
-rw-r--r-- | src/components/TextEditor.vue | 38 | ||||
-rw-r--r-- | src/tests/unit/components/MailPlugin.spec.js | 40 | ||||
-rw-r--r-- | src/tests/unit/components/TextEditor.spec.js | 3 |
4 files changed, 98 insertions, 36 deletions
diff --git a/src/ckeditor/mail/MailPlugin.js b/src/ckeditor/mail/MailPlugin.js new file mode 100644 index 000000000..6570adc7d --- /dev/null +++ b/src/ckeditor/mail/MailPlugin.js @@ -0,0 +1,53 @@ +/** + * @author Daniel Kesselberg <mail@danielkesselberg.de> + * + * @license AGPL-3.0-or-later + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin' +import { Paragraph } from '@ckeditor/ckeditor5-paragraph' + +export default class Mail extends Plugin { + + static get requires() { + return [Paragraph] + } + + init() { + this._overwriteParagraphConversion() + } + + /** + * Overwrite the elementToElement conversion + * from the default paragraph plugin to add + * margin:0 to every <p>. + * + * @private + */ + _overwriteParagraphConversion() { + this.editor.conversion.elementToElement({ + model: 'paragraph', + view: { + name: 'p', + styles: { + margin: 0, + }, + }, + converterPriority: 'high', + }) + } + +} diff --git a/src/components/TextEditor.vue b/src/components/TextEditor.vue index 1c2270b9c..f4d055b68 100644 --- a/src/components/TextEditor.vue +++ b/src/components/TextEditor.vue @@ -52,6 +52,7 @@ import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/base64u import ImagePlugin from '@ckeditor/ckeditor5-image/src/image' import ImageResizePlugin from '@ckeditor/ckeditor5-image/src/imageresize' import ImageUploadPlugin from '@ckeditor/ckeditor5-image/src/imageupload' +import MailPlugin from '../ckeditor/mail/MailPlugin' import { getLanguage } from '@nextcloud/l10n' @@ -108,6 +109,7 @@ export default { ImageUploadPlugin, Base64UploadAdapter, ImageResizePlugin, + MailPlugin, ]) toolbar.unshift(...[ 'heading', @@ -175,43 +177,9 @@ export default { * @param {module:core/editor/editor~Editor} editor editor the editor instance */ onEditorReady(editor) { - const schema = editor.model.schema - - logger.debug('TextEditor is ready', { editor, schema }) - + logger.debug('TextEditor is ready', { editor }) this.editorInstance = editor - // Set 0 pixel margin to all <p> elements - editor.conversion.for('downcast').add((dispatcher) => { - dispatcher.on( - 'insert:paragraph', - (evt, data, conversionApi) => { - const viewWriter = conversionApi.writer - viewWriter.setStyle('margin', '0', conversionApi.mapper.toViewElement(data.item)) - }, - { - priority: 'low', - } - ) - }) - - schema.on( - 'checkChild', - (evt, args) => { - const context = args[0] - - if (context.endsWith('blockQuote')) { - // Prevent next listeners from being called. - evt.stop() - // Set the checkChild()'s return value. - evt.return = true - } - }, - { - priority: 'highest', - } - ) - if (this.focus) { logger.debug('focusing TextEditor') editor.editing.view.focus() diff --git a/src/tests/unit/components/MailPlugin.spec.js b/src/tests/unit/components/MailPlugin.spec.js new file mode 100644 index 000000000..435f8056a --- /dev/null +++ b/src/tests/unit/components/MailPlugin.spec.js @@ -0,0 +1,40 @@ +/* + * @copyright 2022 Daniel Kesselberg <mail@danielkesselberg.de> + * + * @author 2022 Daniel Kesselberg <mail@danielkesselberg.de> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import VirtualTestEditor from '../../virtualtesteditor' +import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph' +import MailPlugin from '../../../ckeditor/mail/MailPlugin' + +describe('MailPlugin', () => { + + it('Add margin:0 to paragraph', async() => { + const text = '<p>bonjour bonjour</p>' + const expected = '<p style="margin:0;">bonjour bonjour</p>' + + const editor = await VirtualTestEditor.create({ + initialData: text, + plugins: [ParagraphPlugin, MailPlugin], + }) + + expect(editor.getData()).toEqual(expected) + }) + +}) diff --git a/src/tests/unit/components/TextEditor.spec.js b/src/tests/unit/components/TextEditor.spec.js index e386c54f4..2501f57a7 100644 --- a/src/tests/unit/components/TextEditor.spec.js +++ b/src/tests/unit/components/TextEditor.spec.js @@ -27,6 +27,7 @@ import Nextcloud from '../../../mixins/Nextcloud' import TextEditor from '../../../components/TextEditor' import VirtualTestEditor from '../../virtualtesteditor' import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph' +import MailPlugin from '../../../ckeditor/mail/MailPlugin' const localVue = createLocalVue() @@ -106,7 +107,7 @@ describe('TextEditor', () => { const editor = await VirtualTestEditor.create({ initialData: '<p>bonjour bonjour</p>', - plugins: [ParagraphPlugin], + plugins: [ParagraphPlugin, MailPlugin], }) wrapper.vm.onEditorReady(editor) |