4

I am trying to add a custom plugin to add to the ckeditor5-build-decoupled-document editor. When I add my custom plugin to the ckeditor5-build-decoupled-document build code and then running npm run build. But I get the error TypeError: Cannot read property '0' of undefined when I add the ckeditor.js build file to my angular project.

enter image description here

The editor toolbar is no longer displayed on the screen and I cannot edit the text, however, the plugin seems to be performing its purpose of allowing inline style in the editor.

I have 2 questions:

  1. Have I created the plugin correctly?
  2. Is there something missing from my configuration within my Angular project?

These are the steps I followed and the code used

Created Plugin

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';


export default class Extension extends Plugin {
    constructor( editor ) {
        super( editor );
    }

    init() {
        const editor = this.editor;

        let allowedAttributes = [
            'width', 'height', 'style', 'stylex', 'target', 'class', 'id', 'name', 'title', 'type', 'olddisplay', 'text-align', 'align',
            'border', 'cellspacing','padding', 'cellpadding', 'color', 'valign', 'clear', 'src',  'shapes', '&amp',
            'prefix', 'tagtype', 'datetime', 'cite',  'cols', 'colspan', 'noshade', 'text-decoration',
            'shape', 'start',  'alt', 'strong', 'files', 'hr', 'font-size',
            'com',  'background-color', 'rowspan', 'span', 'page', 'content',
            'action', 'value', 'autofocus', 'maxlength', 'rows', 'for', 'aria-label', 'checked', 'selected',
            'rel', 'scope', 'location', 'cellpacing', 'block-id', 'lang',
            'original-style', 'datatype', 'property', 'controls', 'controlslist', 'data-attr', 'poster', 'preload',
            'tabindex', 'role', 'aria-describedby', 'aria-disabled','aria-haspopup', 
            'href', 'col', 'doc', 'attach', 'pls', 'vspace', 'hspace', 'slatepath'];

         //creates a new schema to to keep preexisting styles
         editor.model.schema.extend('$root', { allowAttributes: allowedAttributes });
         editor.model.schema.extend('$block', { allowAttributes: allowedAttributes });
         editor.model.schema.extend('$text', { allowAttributes: allowedAttributes });

         for (var i = 0; i < allowedAttributes.length; i++) {
             editor.conversion.attributeToAttribute({ model: this.allowedAttributes[i], view: this.allowedAttributes[i] });
         }

         editor.model.schema.extend('paragraph', { allowAttributes: '__style' });

         editor.conversion.for('upcast').attributeToAttribute({
             model: {
                 key: '__style',
                 name: 'paragraph'
             },
             view: 'style'
         });

         editor.conversion.for('downcast').add(dispatcher => {
             dispatcher.on('attribute:__style:paragraph', (evt, data, conversionApi) => {
                 conversionApi.consumable.consume(data.item, evt.name);

                 const viewElement = conversionApi.mapper.toViewElement(data.item);

                 conversionApi.writer.setAttribute('style', data.attributeNewValue, viewElement);
             });
         });
    } 
}

I then added the plugin to the ckeditor.js file

import Extension from "../ckeditor5-extension/src/extension.js";

DecoupledEditor.builtinPlugins = [
    *
    *
    PasteFromOffice,
    Table,
    TableToolbar,
    Extension
];

Following this, I run npm run build which generates the ckeditor.js in the build folder. Next, I copied the ckeditor.js (and corresponding translation files )from the build folder into the assets folder of my angular project.

Then add my custom editor to my file.

import * as CustomEditor from 'src/assets/ckeditor.js';
public Editor = CustomEditor;

In the tsconfig.json

"compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowJs": true,
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }

In the console when I print out the plugins for the editor my custom plugin is showing undefined.

["Essentials", "Alignment", "FontSize", "FontFamily", "Highlight", "CKFinderUploadAdapter", "Autoformat", "Bold", "Italic", "Strikethrough", "Underline", "BlockQuote", "CKFinder", "EasyImage", "Heading", "Image", "ImageCaption", "ImageStyle", "ImageToolbar", "ImageUpload", "Link", "List", "MediaEmbed", "Paragraph", "PasteFromOffice", "Table", "TableToolbar", undefined]

2 Answers 2

2

So the issue was caused not by any angular / Ckeditor5 integrations but rather a simple mistake in the code.

I originally built the code in Angular when I was familiarizing myself with the process of creating a PLUGIN and transferred the code from my angular app to the cloned repo to create my custom plugin.

The error was a simple reference error.

The line

editor.conversion.attributeToAttribute({ model: this.allowedAttributes[i], view: this.allowedAttributes[i] });

Should have been

editor.conversion.attributeToAttribute({ model: allowedAttributes[i], view: allowedAttributes[i] });

Minus this. reference.

For anyone creating a custom plugin, when you build the plugin there is a sample editor in the repo, that will allow you to test your code with the latest changes. You can make sure the code works before transferring to the Angular app, allowing you to rule out any integration issues with your custom plugin and the Angular app.

Sign up to request clarification or add additional context in comments.

Comments

-1

I think you need to add pluginName:

export default class Extension extends Plugin {
    constructor( editor ) {
        super( editor );
    }

    static get pluginName() {
        return 'Extension';
    }

    init() { ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.