目的:
在编辑器上添加一个按钮,点击后逻辑我自己项目实现,比如:我项目中已经有了图片上传选择框的一套,这里只借用下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' })
接着,修改 .css 的 use 部分:
把 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
})
}
}
]
}
]
}
};