ckeditor5:实现一个块级组件

编辑器中有块级组件,内联组件之分,常用的 heading/p 就是块级组件
更新于: 2021-12-19 12:57:29

安装依赖

npm install --save \
    postcss-loader@3 \
    raw-loader@3 \
    style-loader@1 \
    webpack@4 \
    webpack-cli@3 \
    @ckeditor/ckeditor5-dev-utils \
    @ckeditor/ckeditor5-editor-classic \
    @ckeditor/ckeditor5-essentials \
    @ckeditor/ckeditor5-paragraph \
    @ckeditor/ckeditor5-heading \
    @ckeditor/ckeditor5-list \
    @ckeditor/ckeditor5-basic-styles \
    @ckeditor/ckeditor5-theme-lark

webpack.config.js

// webpack.config.js

'use strict';

const path = require('path');
const { styles } = require('@ckeditor/ckeditor5-dev-utils');

module.exports = {
  // https://webpack.js.org/configuration/entry-context/
  entry: './app.js',

  // https://webpack.js.org/configuration/output/
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },

  module: {
    rules: [
      {
        test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,

        use: ['raw-loader']
      },
      {
        test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,

        use: [
          {
            loader: 'style-loader',
            options: {
              injectType: 'singletonStyleTag',
              attributes: {
                'data-cke': true
              }
            }
          },
          {
            loader: 'postcss-loader',
            options: styles.getPostCssConfig({
              themeImporter: {
                themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
              },
              minify: true
            })
          }
        ]
      }
    ]
  },

  // Useful for debugging.
  devtool: 'source-map',

  // By default webpack logs warnings if the bundle is bigger than 200kb.
  performance: { hints: false }
};

代码结构

.
├── app.js
├── dist
│   ├── bundle.js
│   └── bundle.js.map
├── index.html
├── package-lock.json
├── package.json
├── simplebox
│   ├── cmd.js
│   ├── editing.js
│   ├── index.js
│   ├── style.css
│   └── ui.js
└── webpack.config.js

插件入口

.
├── cmd.js
├── editing.js
├── index.js
├── style.css
└── ui.js

simplebox/index.js

// simplebox/index.js

import SimpleBoxEditing from './editing';
import SimpleBoxUI from './ui';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';

export default class SimpleBox extends Plugin {
  static get requires () {
    return [SimpleBoxEditing, SimpleBoxUI];
  }
}

定义一个可识别的 model schema

const schema = this.editor.model.schema;

schema.register("simpleBox", {
  // Behaves like a self-contained object (e.g. an image).
  isObject: true,
  // Allow in places where other blocks are allowed (e.g. directly in the root).
  allowWhere: "$block",
});

添加ui,并触发事件

const editor = this.editor;
const t = editor.t;

// The "simpleBox" button must be registered among the UI components of the editor
// to be displayed in the toolbar.
editor.ui.componentFactory.add("simpleBox", (locale) => {
  // The state of the button will be bound to the widget command.
  const command = editor.commands.get("insertSimpleBox");

  // The button will be an instance of ButtonView.
  const view = new view(locale);

  view.set({
    // The t() function helps localize the editor. All strings enclosed in t() can be
    // translated and change when the language of the editor changes.
    label: t("Simple Box"),
    withText: true,
    tooltip: false,
  });

  // Bind the state of the button to the command.
  view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');

  // Execute the command when the button is clicked (executed).
  this.listenTo(view, "execute", () => editor.execute("insertSimpleBox"));

  return view;
});

定义conversion,转换器(这块内容比较多,风官方文档)

  1. SimpleBox 转成 HTML
  2. HTML 转成 simpleBox 等内置 model
关于ckeditor5的conversion

参考