Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Problems spotted:
- ✅
\Drupal\ckeditor5\Plugin\CKEditor5PluginInterface::getDynamicPluginConfig()
does not specify a return type hint - ✅
\Drupal\ckeditor5\Plugin\CKEditor5PluginInterface::getDynamicPluginConfig()
's docs for the first parameter were not updated in #3215600: Unclear relationship between "plugin_config" in *.ckeditor5.yml and Drupal plugin settings to generate that configuration as they should've been - ✅
\Drupal\ckeditor5\Plugin\CKEditor5PluginDefault
needs an@see \Drupal\ckeditor5\Annotation\DrupalAspectsOfCKEditor5Plugin::$class
- ❌
We should make the variable names and patterns used in all the current PHP CKEditor 5 plugin classes consistent, to make it easier to review and to make it easier for plugin developers to look at examples.→ #3228920: Improve internal consistency: consistent variable names and return type syntax - ❌
Consistently use→ #3228920: Improve internal consistency: consistent variable names and return type syntaxfunction foo(): TYPE
as return type hint code style, notfunction foo() : TYPE
— per @tim.plunkett, this is the vast majority in Drupal core, even if there is no coding standard yet. - ❌
We should probably remove the→ spun off into #3228477: CKEditor5PluginConfigurableInterface should extend PluginFormInterface and ConfigurableInterface instead of adding ::settingsForm().settingsForm()
method from\Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface
and instead makeCKEditor5PluginConfigurableInterface
also extend\Drupal\Core\Plugin\PluginFormInterface
. It's not because CKEditor 4 had that in\Drupal\ckeditor\CKEditorPluginConfigurableInterface
that we need to repeat that pattern for CKEditor 5. (That interface was committed in February 2013, andPluginFormInterface
was committed in August 2013, which explains this.) - ✅
\Drupal\ckeditor5\Plugin\CKEditor5PluginInterface::getDynamicPluginConfig()
receivesEditor
, this should beEditorInterface
. Same forCKEditor5PluginConfigurableInterface::settingsForm()
. - ✅
TextEditorObjectDependentValidatorTrait
is a trait with clear responsibility/intent.CKEditor5ConstraintValidatorTrait
is not. It forces a particular interface and injects the CKEditor 5 plugin manager. So it should be renamed toPluginManagerDependentValidatorTrait
. - ✅ Docs in
CKEditor5ConstraintValidatorTrait
refer toToolbarItemConstraintValidator
— copy/paste leftover. - ✅
CKEditor5PluginManager
needs an interface - ❌
Removing→ I cannot reproduce this.SourceEditor
from toolbar did not remove config fromeditor.editor
entity... - ❌
One thing I did not like from #3228477: CKEditor5PluginConfigurableInterface should extend PluginFormInterface and ConfigurableInterface instead of adding ::settingsForm():→ #3228945: CKEditor 5 plugin instances shenanigans: text editor plugin is statefully coupled + plugin instance methods on managerpublic function getPlugin()
on\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getPlugin()
. If we must have it, why not just add an optional parameter to::createInstance()
? That's okay to comply with the interface, and there's precedent in core:\Drupal\Core\Plugin\PluginFormFactory::createInstance()
does it too. - ✅
CKE5PMI
's (CKEditor5PluginManagerInterface
)::getEnabledDefinitions()
,::getEnabledLibraries()
andgetCKEditorPluginSettings()
typehint toEditor
instead ofEditorInterface
- ✅
CKE5PMI::getReadableElements()
really belongs onHTMLRestrictionsUtilities
- ✅
CKE5PMI::getWildcardTags()
,\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::WILDCARD_ELEMENT_METHODS
and\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getBlockElementList()
do too, but are a bit trickier to move - ✅
CKE5PMI::getCKEditorPluginSettings
is an oddly named method for at least two reason: 1) it says "CKEditor", not "CKEditor5", 2) it returns much more than the plugin settings: it also returns the toolbar configuration and which plugins to load. It was introduced very early in the life of this module: in #3195965: Register CKEditor 5 plugins via YAML definitions instead of class annotations — which was the 4th commit that actually had an issue number associated with it. It was a fine name back then. I think we can stay true to the current name though: just omit the "CKEditor" part in the method name, and move the toolbar pieces out of the plugin manager and into\Drupal\ckeditor5\Plugin\Editor\CKEditor5::getJSSettings()
, which is the only place where this method gets called. Then the plugin manager again is doing what it's doing: managing plugins. Nothing else. Also, it should be "config", not "settings", because that's what it's called in the annotation, the YAML, the optional dynamic config method and in https://ckeditor.com/docs/ckeditor5/latest/api/module_editor-classic_cla.... - ✅
\Drupal\ckeditor5\AdminUi
needs to be marked as@internal
! As does\Drupal\ckeditor5\HTMLRestrictionsUtilities
. - ✅
CKE5PMI
's::getToolbarItems()
,::getAdminLibraries()
,::getEnabledLibraries()
and::getEnabledDefinitions()
do not have a return type.
Steps to reproduce
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork ckeditor5-3228465
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
Wim LeersComment #3
Wim LeersComment #4
Wim LeersComment #6
Wim LeersTwo additions from @tim.plunkett:
CKEditor5PluginManager
needs an interfaceSourceEditor
from toolbar did not remove config fromeditor.editor
entity...Comment #7
Wim LeersAdded
public function getPlugin()
on\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getPlugin()
. If we must have it, why not just add an optional parameter to::createInstance()
? That's okay to comply with the interface, and there's precedent in core:\Drupal\Core\Plugin\PluginFormFactory::createInstance()
does it too.Comment #9
Wim LeersPoints 2, 3 and 7 have been fixed in the merge request. Marking them.
Comment #10
Wim LeersI meant: 1, 2, 3 and 7.
Comment #11
Wim LeersPoints 8 & 9 have been fixed in the MR too. Marking them.
Comment #12
Wim LeersFixed point 10.
Comment #13
Wim LeersDescoping points four and five, because it would lead to a very hard to understand diff. Plus, neither of them actually affect the public API. Created the minor task #3228920: Improve internal consistency: consistent variable names and return type syntax for those two.
Comment #14
Wim LeersFix HTML.
Comment #15
Wim LeersI cannot reproduce
.Comment #16
Wim LeersIn having done #10, I noticed a few more problems in
CKE5PMI
(CKEditor5PluginManagerInterface
):CKE5PMI
's (CKEditor5PluginManagerInterface
)::getEnabledDefinitions()
,::getEnabledLibraries()
andgetCKEditorPluginSettings()
typehint toEditor
instead ofEditorInterface
CKE5PMI::getReadableElements()
really belongs onHTMLRestrictionsUtilities
CKE5PMI::getWildcardTags()
,\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::WILDCARD_ELEMENT_METHODS
and\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getBlockElementList()
do too, but are a bit trickier to moveCKE5PMI::getCKEditorPluginSettings
is an oddly named method for at least two reason: 1) it says "CKEditor", not "CKEditor5", 2) it returns much more than the plugin settings: it also returns the toolbar configuration and which plugins to load. It was introduced very early in the life of this module: in #3195965: Register CKEditor 5 plugins via YAML definitions instead of class annotations — which was the 4th commit that actually had an issue number associated with it. It was a fine name back then. I think we can stay true to the current name though: just omit the "CKEditor" part in the method name, and move the toolbar pieces out of the plugin manager and into\Drupal\ckeditor5\Plugin\Editor\CKEditor5::getJSSettings()
, which is the only place where this method gets called. Then the plugin manager again is doing what it's doing: managing plugins. Nothing else. Also, it should be "config", not "settings", because that's what it's called in the annotation, the YAML, the optional dynamic config method and in https://ckeditor.com/docs/ckeditor5/latest/api/module_editor-classic_cla....Comment #17
Wim LeersFixed point 13.
Comment #18
Wim LeersFixed point 14.
In having worked on point 14 … adding:
\Drupal\ckeditor5\AdminUi
needs to be marked as@internal
! As does\Drupal\ckeditor5\HTMLRestrictionsUtilities
.Comment #19
Wim LeersFixed point 15.
Comment #20
Wim LeersFixed point 16.
Comment #21
Wim LeersWhile working on point 16, I noticed something else:
CKE5PMI
's::getToolbarItems()
,::getAdminLibraries()
,::getEnabledLibraries()
and::getEnabledDefinitions()
do not have a return type.Comment #22
Wim LeersFixed points 17 & 18.
Comment #23
Wim LeersSolving point 12 here is much more contentious than all the other changes here. Everything else so far is trivial/uncontentious/obvious.
So descoping that to #3228945: CKEditor 5 plugin instances shenanigans: text editor plugin is statefully coupled + plugin instance methods on manager.
Comment #24
Wim LeersIn scanning
*Interface.php
in the CKEditor 5 module, I can't find any more problems (other than typos).I'm going to be bold here and self-RTBC and merge.
Several of the things here were actually raised by @tim.plunkett, not by me. More contentious changes were descoped (#3228477: CKEditor5PluginConfigurableInterface should extend PluginFormInterface and ConfigurableInterface instead of adding ::settingsForm() + #3228945: CKEditor 5 plugin instances shenanigans: text editor plugin is statefully coupled + plugin instance methods on manager), non-critical changes too (#3228920: Improve internal consistency: consistent variable names and return type syntax).
All of these changes are very important for the core merge request: doing them later will cause more toil. They make the public API more concise, consistent and core-worthy.
Comment #26
Wim Leers