目录

CKEditor自定义插件

​目的:

在编辑器上添加一个按钮,点击后逻辑我自己项目实现,比如:我项目中已经有了图片上传选择框的一套,这里只借用下ckeditor展示一个触发图标

1、克隆官方模板仓库

https://github.com/ckeditor/ckeditor5-build-classic.git

注意:这里是官方,最新更新是2020年,建议从我的仓库中克隆(5、编译指定版本的ckeditor),采用的是40.2.0

这里node必须不低于v20

npm编译没成功,我用的yarn

2、创建插件 CustomButton

src/plugins/customButton.js

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
//import imageIcon from './theme/icons/imageUpload.svg';

export default class CustomButton extends Plugin {
    static get pluginName() {
        return 'CustomButton';
    }

    init() {
        const editor = this.editor;

        // 注册按钮
        editor.ui.componentFactory.add('customButton', locale => {
            const view = new ButtonView(locale);

            view.set({
                label: '自定义按钮',
                tooltip: true,
                withText: true // 是否显示文字
            });
            //图标按钮
            //view.set({
            //    label: '上传图片',
            //    tooltip: true,
            //    withText: false,
            //    icon: imageIcon
            //});

            // 点击按钮时触发事件
            view.on('execute', () => {
                // 这里不写逻辑,第三方可监听 editor 事件
                editor.fire('customButtonClicked');
            });

            return view;
        });
    }
}

3、注册插件

src/ckeditor.js

import CustomButton from './plugins/customButton';

ClassicEditor.builtinPlugins = [
    Essentials,
    Paragraph,
    Bold,
    Italic,
    CustomButton
];

ClassicEditor.defaultConfig = {
    toolbar: [
        'bold', 'italic', 'customButton', 'undo', 'redo'
    ],
    language: 'zh-cn'
};

4、第三方项目使用示例

ClassicEditor
  .create(document.querySelector('#editor'))
  .then(editor => {
      // 监听按钮点击事件
      editor.on('customButtonClicked', () => {
          // 这里写自己的逻辑
          console.log('自定义按钮被点击了!');
      });
  })
  .catch(console.error);

5、编译指定版本的ckeditor

https://github.com/leellun/ckeditor5-build-classic.git

在线编译:https://ckeditor.com/ckeditor-5/online-builder/

这里是我和https://cdn.ckeditor.com/ckeditor5/40.2.0/classic/ckeditor.js 保持版本40.2.0

所以我重新配置了package.json

例如:

    "@ckeditor/ckeditor5-adapter-ckfinder": "40.2.0",
    "@ckeditor/ckeditor5-autoformat": "40.2.0",
    "@ckeditor/ckeditor5-basic-styles": "40.2.0",
    "@ckeditor/ckeditor5-block-quote": "40.2.0",
    "@ckeditor/ckeditor5-ckfinder": "40.2.0",
    "@ckeditor/ckeditor5-core": "40.2.0",
    "@ckeditor/ckeditor5-easy-image": "40.2.0",
    "@ckeditor/ckeditor5-editor-classic": "40.2.0",
    "@ckeditor/ckeditor5-essentials": "40.2.0",
    "@ckeditor/ckeditor5-heading": "40.2.0",
    "@ckeditor/ckeditor5-image": "40.2.0",
    "@ckeditor/ckeditor5-indent": "40.2.0",
    "@ckeditor/ckeditor5-link": "40.2.0",
    "@ckeditor/ckeditor5-list": "40.2.0",
    "@ckeditor/ckeditor5-media-embed": "40.2.0",
    "@ckeditor/ckeditor5-paragraph": "40.2.0",
    "@ckeditor/ckeditor5-paste-from-office": "40.2.0",
    "@ckeditor/ckeditor5-table": "40.2.0",
    "@ckeditor/ckeditor5-typing": "40.2.0",
    "@ckeditor/ckeditor5-theme-lark": "40.2.0",
    "@ckeditor/ckeditor5-code-block": "40.2.0",
    "@ckeditor/ckeditor5-font": "40.2.0",

这里我把官方的v19改成v40

ckeditor5-paste-from-office根据自己需求加载,我复制粘贴就会出现没有内容,我这里没有加入

6、单独编译生成css

npm install --save-dev mini-css-extract-plugin

在顶部引入插件:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

然后在 plugins 数组中添加:

new MiniCssExtractPlugin({ filename: 'ckeditor-content.css'  })

接着,修改 .cssuse 部分:

style-loader 替换为 MiniCssExtractPlugin.loader

					// {
					// 	loader: 'style-loader',
					// 	options: {
					// 		injectType: 'singletonStyleTag',
					// 		attributes: {
					// 			'data-cke': true
					// 		}
					// 	}
					// },
					{
                        loader: MiniCssExtractPlugin.loader // ✅ 代替 style-loader
                    },

完整:

/**
 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */

'use strict';

/* eslint-env node */

const path = require( 'path' );
const webpack = require( 'webpack' );
const { bundler, styles } = require( '@ckeditor/ckeditor5-dev-utils' );
const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
const TerserPlugin = require( 'terser-webpack-plugin' );

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // ✅ 新增 分离css

module.exports = {
	devtool: 'source-map',
	performance: { hints: false },

	entry: path.resolve( __dirname, 'src', 'ckeditor.js' ),

	output: {
		// The name under which the editor will be exported.
		library: 'ClassicEditor',

		path: path.resolve( __dirname, 'build' ),
		filename: 'ckeditor.js',
		libraryTarget: 'umd',
		libraryExport: 'default'
	},

	optimization: {
		minimizer: [
			new TerserPlugin( {
				terserOptions: {
					output: {
						// Preserve CKEditor 5 license comments.
						comments: /^!/
					}
				},
				extractComments: false
			} )
		]
	},

	plugins: [
		new CKEditorWebpackPlugin( {
			// UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
			// When changing the built-in language, remember to also change it in the editor's configuration (src/ckeditor.js).
			language: 'en',
			additionalLanguages: 'all'
		} ),
		new webpack.BannerPlugin( {
			banner: bundler.getLicenseBanner(),
			raw: true
		} ),
		new MiniCssExtractPlugin({
            filename: 'ckeditor-content.css' // ✅ 输出 CKEditor 样式
        })
	],

	module: {
		rules: [
			{
				test: /\.svg$/,
				use: [ 'raw-loader' ]
			},
			{
				test: /\.css$/,
				use: [
					// {
					// 	loader: 'style-loader',
					// 	options: {
					// 		injectType: 'singletonStyleTag',
					// 		attributes: {
					// 			'data-cke': true
					// 		}
					// 	}
					// },
					{
                        loader: MiniCssExtractPlugin.loader // ✅ 代替 style-loader
                    },
					{
						loader: 'css-loader'
					},
					{
						loader: 'postcss-loader',
						options: {
							postcssOptions: styles.getPostCssConfig({
								themeImporter: {
									themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
								},
								minify: true
							})
						}
					}
				]
			}
		]
	}
};