ckeditor / ckeditor5

Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.
https://ckeditor.com/ckeditor-5
Other
9.37k stars 3.68k forks source link

Allow adding plugins to a CKEditor 5 build #667

Closed pjasiun closed 3 years ago

pjasiun commented 6 years ago

Right now there is no easy way to add a real plugin to the CKEditor 5 build. Even if it is theoretically possible, you will not be able to create a position or fire an event.

The problem is that build has all classes build in and expose only editors API. If a custom plugin imports Position from the ckeditor5-engine and use it in the plugin it will not be the same instance as the one used in the engine in the build. Because of it, this position will return false when position instanceof Position will be called, so the user will get an ugly bug.

There is a simmilar problem with symbols, which are used in the events system.

Note that it is even worse because the same issue will appear when a custom plugin will have a different version of the engine on the list of dependencies. We could say that in such case semantic versioning will save us, but it still means that with every major engine release all 3rd party plugins will stop working immediately, even if changes in the engine breaks nothing important for them. The version of the dependency will not match anymore and 2 separate engines will be included with not matching classes.

This very ticky problem, but there are some improvements we could think about.

Since editor usually needs all engine features, we could expose them as document property, have something like document.createPosition. Then all plugins will use instances of the same class and the problem disappears. In fact, when all engine utiles will be exposed on the document model (or controller), plugins will not need to depends on the engine and only use engine exposed by the editor.

Unfortunately, it looks fine only in the theory. Only for position we have:

Position.constructor( root, path )
Position.createAt( itemOrPosition, offset )
Position.createAfter( item )
Position.createBefore( item )
Position.createFromParentAndOffset( parent, offset )
Position.createFromPosition( position )

Then there is range:

Range.constructor( start, end )
Range.createFromPositionAndShift( position, shift )
Range.createFromParentsAndOffsets( startElement, startOffset, endElement, endOffset )
Range.createFromRange( range )
Range.createIn( element )
Range.createOn( item )
Range.createCollapsedAt( itemOrPosition, offset )
Range.createFromRanges( ranges )

Then, treeWalker... But hey! It's only the model. We have also all conversion utils to be exposed because one will need them for sure. And working with converters one will need to be able to use view API, so multiple constructors in the view need to be exposed too. It means a lot of factories and a lot of ugly APIs. And I'm talking here only about the engine, but note that there is the same problem with utils and UI. The additional problem with utils is that we can not expose all of them because we don't know which are really needed.

Another solution would be to stop using instanceof and symbols since they are problematic. We would have to have is method in each class or use duck typing. Symbols could be replaced with unique strings. It would not solve the problem of duplicated dependencies, the build will be bigger but the editor will work fine.

I think that we should end up with something in between. We may accept that some utils will be duplicated as long as they don't break the editor, but we should ensure that only one engine will be loaded.

jodator commented 3 years ago

Thanks for all the input on the matter. The majority of work to allow adding plugins to the build will be tracked in #8395. A rough summary of the above conversation is available here: https://github.com/ckeditor/ckeditor5/issues/8395#issuecomment-720504984.

As we have to restart the work on this problem I'm closing this issue as there's no need to track this in two issues.

Please follow #8395 to track progres.