Started to use CKEditor 5 as richt text editor.

This commit is contained in:
Jan Böhmer 2022-07-25 01:09:31 +02:00
parent 156301b8a4
commit dbdfe5ea95
9 changed files with 1575 additions and 49 deletions

View file

@ -0,0 +1,115 @@
/**
* @license Copyright (c) 2014-2022, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat.js';
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote.js';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold.js';
import Code from '@ckeditor/ckeditor5-basic-styles/src/code.js';
import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock.js';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials.js';
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace.js';
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js';
import Heading from '@ckeditor/ckeditor5-heading/src/heading.js';
import Image from '@ckeditor/ckeditor5-image/src/image.js';
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle.js';
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar.js';
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload.js';
import Indent from '@ckeditor/ckeditor5-indent/src/indent.js';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic.js';
import Link from '@ckeditor/ckeditor5-link/src/link.js';
import List from '@ckeditor/ckeditor5-list/src/list.js';
import Markdown from '@ckeditor/ckeditor5-markdown-gfm/src/markdown.js';
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed.js';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.js';
import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting.js';
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters.js';
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js';
import SpecialCharactersMathematical from '@ckeditor/ckeditor5-special-characters/src/specialcharactersmathematical.js';
import Table from '@ckeditor/ckeditor5-table/src/table.js';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js';
import TextTransformation from '@ckeditor/ckeditor5-typing/src/texttransformation.js';
class Editor extends ClassicEditor {}
// Plugins to include in the build.
Editor.builtinPlugins = [
Autoformat,
BlockQuote,
Bold,
Code,
CodeBlock,
Essentials,
FindAndReplace,
GeneralHtmlSupport,
Heading,
Image,
ImageStyle,
ImageToolbar,
ImageUpload,
Indent,
Italic,
Link,
List,
Markdown,
MediaEmbed,
Paragraph,
PasteFromOffice,
SourceEditing,
SpecialCharacters,
SpecialCharactersEssentials,
SpecialCharactersMathematical,
Table,
TableToolbar,
TextTransformation
];
// Editor configuration.
Editor.defaultConfig = {
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'link',
'bulletedList',
'numberedList',
'|',
'outdent',
'indent',
'|',
'imageUpload',
'blockQuote',
'insertTable',
'mediaEmbed',
'undo',
'redo',
'specialCharacters',
'code',
'codeBlock',
'sourceEditing',
'findAndReplace'
]
},
language: 'en',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells'
]
}
};
export default Editor;

View file

@ -0,0 +1,104 @@
/**
* @license Copyright (c) 2014-2022, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat.js';
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote.js';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold.js';
import Code from '@ckeditor/ckeditor5-basic-styles/src/code.js';
import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock.js';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials.js';
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace.js';
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js';
import Heading from '@ckeditor/ckeditor5-heading/src/heading.js';
import Image from '@ckeditor/ckeditor5-image/src/image.js';
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle.js';
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar.js';
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload.js';
import Indent from '@ckeditor/ckeditor5-indent/src/indent.js';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic.js';
import Link from '@ckeditor/ckeditor5-link/src/link.js';
import List from '@ckeditor/ckeditor5-list/src/list.js';
import Markdown from '@ckeditor/ckeditor5-markdown-gfm/src/markdown.js';
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed.js';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.js';
import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting.js';
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters.js';
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js';
import SpecialCharactersMathematical from '@ckeditor/ckeditor5-special-characters/src/specialcharactersmathematical.js';
import Table from '@ckeditor/ckeditor5-table/src/table.js';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js';
import TextTransformation from '@ckeditor/ckeditor5-typing/src/texttransformation.js';
class Editor extends ClassicEditor {}
// Plugins to include in the build.
Editor.builtinPlugins = [
Autoformat,
BlockQuote,
Bold,
Code,
CodeBlock,
Essentials,
FindAndReplace,
GeneralHtmlSupport,
Heading,
Image,
ImageStyle,
ImageToolbar,
ImageUpload,
Indent,
Italic,
Link,
List,
Markdown,
MediaEmbed,
Paragraph,
PasteFromOffice,
SourceEditing,
SpecialCharacters,
SpecialCharactersEssentials,
SpecialCharactersMathematical,
Table,
TableToolbar,
TextTransformation
];
// Editor configuration.
Editor.defaultConfig = {
toolbar: {
items: [
'bold',
'italic',
'link',
'specialCharacters',
'code',
'|',
'undo',
'redo',
'|',
'findAndReplace',
'sourceEditing',
]
},
language: 'en',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells'
]
}
};
export default Editor;

View file

@ -0,0 +1,35 @@
import {Controller} from "@hotwired/stimulus";
import { default as FullEditor } from "../../ckeditor/markdown_full";
import { default as SingleLineEditor} from "../../ckeditor/markdown_single_line";
/* stimulusFetch: 'lazy' */
export default class extends Controller {
connect() {
const mode = this.element.dataset.mode;
const output_format = this.element.dataset.outputFormat;
let EDITOR_TYPE = "Invalid";
if(output_format == 'markdown') {
if(mode == 'full') {
EDITOR_TYPE = FullEditor;
} else if(mode == 'single_line') {
EDITOR_TYPE = SingleLineEditor;
}
} else {
console.error("Unknown output format: " + output-format);
return;
}
this.editor = EDITOR_TYPE.create(this.element, {
})
.then(editor => {
console.log(editor);
})
.catch(error => {
console.error(error);
});
}
}

View file

@ -2,18 +2,18 @@
"devDependencies": {
"@fortawesome/fontawesome-free": "^6.1.1",
"@hotwired/stimulus": "^3.0.0",
"@symfony/stimulus-bridge": "^3.2.0",
"@symfony/webpack-encore": "^3.0.0",
"core-js": "^3.23.0",
"regenerator-runtime": "^0.13.9",
"webpack-notifier": "^1.15.0",
"@hotwired/turbo": "^7.0.1",
"@popperjs/core": "^2.10.2",
"@symfony/stimulus-bridge": "^3.2.0",
"@symfony/ux-turbo": "file:vendor/symfony/ux-turbo/Resources/assets",
"@symfony/webpack-encore": "^3.0.0",
"bootstrap": "^5.1.3",
"core-js": "^3.23.0",
"jquery": "^3.5.1",
"popper.js": "^1.14.7",
"webpack-bundle-analyzer": "^4.3.0"
"regenerator-runtime": "^0.13.9",
"webpack-bundle-analyzer": "^4.3.0",
"webpack-notifier": "^1.15.0"
},
"license": "AGPL-3.0-or-later",
"private": true,
@ -24,6 +24,30 @@
"build": "encore production --progress"
},
"dependencies": {
"@ckeditor/ckeditor5-autoformat": "^34.2.0",
"@ckeditor/ckeditor5-basic-styles": "^34.2.0",
"@ckeditor/ckeditor5-block-quote": "^34.2.0",
"@ckeditor/ckeditor5-code-block": "^34.2.0",
"@ckeditor/ckeditor5-dev-utils": "^30.3.1",
"@ckeditor/ckeditor5-dev-webpack-plugin": "^30.3.1",
"@ckeditor/ckeditor5-editor-classic": "^34.2.0",
"@ckeditor/ckeditor5-essentials": "^34.2.0",
"@ckeditor/ckeditor5-find-and-replace": "^34.2.0",
"@ckeditor/ckeditor5-heading": "^34.2.0",
"@ckeditor/ckeditor5-html-support": "^34.2.0",
"@ckeditor/ckeditor5-image": "^34.2.0",
"@ckeditor/ckeditor5-indent": "^34.2.0",
"@ckeditor/ckeditor5-link": "^34.2.0",
"@ckeditor/ckeditor5-list": "^34.2.0",
"@ckeditor/ckeditor5-markdown-gfm": "^34.2.0",
"@ckeditor/ckeditor5-media-embed": "^34.2.0",
"@ckeditor/ckeditor5-paragraph": "^34.2.0",
"@ckeditor/ckeditor5-paste-from-office": "^34.2.0",
"@ckeditor/ckeditor5-source-editing": "^34.2.0",
"@ckeditor/ckeditor5-special-characters": "^34.2.0",
"@ckeditor/ckeditor5-table": "^34.2.0",
"@ckeditor/ckeditor5-theme-lark": "^34.2.0",
"@ckeditor/ckeditor5-typing": "^34.2.0",
"@types/typeahead": "^0.11.32",
"@zxing/library": "^0.19.1",
"bootbox": "^5.4.0",

View file

@ -53,6 +53,7 @@ use App\Entity\PriceInformations\Orderdetail;
use App\Form\AttachmentFormType;
use App\Form\ParameterType;
use App\Form\Type\MasterPictureAttachmentType;
use App\Form\Type\RichTextEditorType;
use App\Form\Type\SIUnitType;
use App\Form\Type\StructuralEntityType;
use App\Form\WorkaroundCollectionType;
@ -63,6 +64,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\ResetType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
@ -106,11 +108,11 @@ class PartBaseType extends AbstractType
],
'disabled' => !$this->security->isGranted('name.edit', $part),
])
->add('description', CKEditorType::class, [
->add('description', RichTextEditorType::class, [
'required' => false,
'empty_data' => '',
'label' => 'part.edit.description',
'config_name' => 'description_config',
'mode' => 'single_line',
'attr' => [
'placeholder' => 'part.edit.description.placeholder',
'rows' => 2,
@ -206,12 +208,13 @@ class PartBaseType extends AbstractType
]);
//Comment section
$builder->add('comment', CKEditorType::class, [
$builder->add('comment', RichTextEditorType::class, [
'required' => false,
'label' => 'part.edit.comment',
'attr' => [
'rows' => 4,
],
'disabled' => !$this->security->isGranted('comment.edit', $part),
'empty_data' => '',
]);

View file

@ -0,0 +1,53 @@
<?php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RichTextEditorType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver); // TODO: Change the autogenerated stub
$resolver->setDefault('mode', 'full');
$resolver->setAllowedValues('mode', ['full', 'single_line']);
$resolver->setDefault('output_format', 'markdown');
$resolver->setAllowedValues('output_format', ['markdown']);
}
public function getBlockPrefix()
{
return 'rich_text_editor';
}
public function finishView(FormView $view, FormInterface $form, array $options)
{
$view->vars['attr'] = array_merge($view->vars['attr'], $this->optionsToAttrArray($options));
parent::finishView($view, $form, $options); // TODO: Change the autogenerated stub
}
protected function optionsToAttrArray(array $options)
{
$tmp = [];
$tmp['data-mode'] = $options['mode'];
$tmp['data-output-format'] = $options['output_format'];
//Add our data-controller element to the textarea
$tmp['data-controller'] = 'elements--ckeditor';
return $tmp;
}
public function getParent()
{
return TextareaType::class;
}
}

View file

@ -123,4 +123,4 @@
{% endif %}
{{- block("choice_widget_collapsed", "bootstrap_base_layout.html.twig") -}}
{%- endblock choice_widget_collapsed -%}
{%- endblock choice_widget_collapsed -%}

View file

@ -25,6 +25,8 @@ const CopyPlugin = require('copy-webpack-plugin');
const zlib = require('zlib');
const CompressionPlugin = require("compression-webpack-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
@ -124,8 +126,43 @@ Encore
// uncomment if you're having problems with a jQuery plugin
.autoProvidejQuery()
.addPlugin( new CKEditorWebpackPlugin( {
// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
language: 'en',
addMainLanguageTranslationsToAllAssets: true,
additionalLanguages: 'all'
} ) )
// Use raw-loader for CKEditor 5 SVG files.
.addRule( {
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
loader: 'raw-loader'
} )
// Configure other image loaders to exclude CKEditor 5 SVG files.
.configureLoaderRule( 'images', loader => {
loader.exclude = /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/;
} )
// Configure PostCSS loader.
.addLoader({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
loader: 'postcss-loader',
options: {
postcssOptions: styles.getPostCssConfig( {
themeImporter: {
themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
},
minify: true
} )
}
} )
;
//Copy bootstrap map if in debug mode
if (Encore.isDev()) {
Encore.addPlugin(new CopyPlugin({

1233
yarn.lock

File diff suppressed because it is too large Load diff