This lays out what remains to be done after #3231364: Add CKEditor 5 module to Drupal core lands in Drupal core.
This plan was originally taken from the IS at #2966864: Add optional support for CKEditor 5 in D9 so we can remove CKE 4 from Drupal 10, and after that from #3201824: Roadmap to core.
Roadmap to Stable
- Ensure that sites can update from using CKE4 to CKE5 safely when using no contributed CKEditor modules
- #3247634: [PP-1] [upstream] [drupalImage] Unlinking linked inline images while GHS is enabled: wrapping <a> is impossible to remove
- #3268306: [upstream] [GHS] Custom/unofficial HTML tags not retained: <drupal-media>, <drupal-entity>, <foobar>
- #3271418: [PP-1] [upstream] [drupalMedia] Linked media wrapped with <div> doesn't upcast correctly
- #3274651: Impossible to enable <ol type> or <ul type> with GHS
- #3276217: [drupalMedia] GHS attributes are not retained in linked media
- #3273983: Do not assume that plugin supporting <tag attr> also supports <tag> in SourceEditingRedundantTags and upgrade path
- ✅ Ensure contrib modules can do everything: translations, automatic upgrade path from CKE4 …
- Currently none
- ✅ Ensure CKE5 equivalent plugins of CKE4 generate/support equivalent markup: #3222801: [META] Ensure CKE5 equivalent plugins of CKE4 generate/support equivalent markup
- Currently none
- Ensure CKE5 functionality matches that of Drupal core's CKE4:
- ✅ Documentation gates:
- Currently none
- ✅ Theming CKEditor 5
- Currently none
- ✅ Accessibility
- Currently none
- Test coverage, reliability and maintainability matching or exceeding CKEditor 4's:
- ✅ Low-hanging fruit major UX improvements over CKEditor 4:
- Currently none
- Superior configuration UX:
- ✅ Performance
- Currently none.
Roadmap after Stable
- Upstream Drupal improvements that would simplify or improve CKEditor 5:
- #3226673: API addition: \Drupal\editor\Plugin\EditorPluginInterface::getDefaultSettings() should accept old Editor + Format to generate smart defaults
- #3230829: editor_form_filter_format_form_alter() does not remove "editor_plugin" from form state when needed
- #3231322: Fix a @todo: move a form alteration to the CKEditor 5 plugin's subform definition
- #3231341: Deprecate EditorLinkDialog and EditorImageDialog in Drupal 9, remove in Drupal 10
- #3231342: Introduce ConfigEntityForm to standardize use of validation constraints for config entities
- #3231347: Add Editor::setFilterformat()
- #3231354: [META] Discuss: merge the Editor config entity into the FilterFormat config entity
- #3246260: [PP-1] Simplify CKEditor5ImageController once #2940383 lands
- #3263668: [PP-1] Re-enable inline form errors in assessActiveTextEditorAfterBuild function→ blocked on Vertical Tabs bug: #2911932: Correct vertical tab does not focus on form validation
- #3269101: [PP-1] Ensure enabled CKEditor 5 plugins remain available by calculating corresponding dependencies→ blocked on Text Editor module bug: #2950795: CKEditor 4+5 plugin module dependency not added to text format configuration
- Obsoleteness of upgrade path in Drupal 11:
- Performance:
- Media improvements
- #3196593: Ease the transition to Media: save image uploads in CKEditor 5 as media entities when media is enabled? (or module specific solution if core issue won't land)
- #3073901: Determine an upgrade path from CKEditor image button to media library (or module specific solution if core issue won't land)
- Low-hanging fruit major UX improvements over CKEditor 4:
- Superior configuration UX:
- Maintainability:
Completed
This section mimics the structure of the above sections.
💯 Roadmap to Alpha
- ✅ Create the ckeditor5 module
- ✅ Create an @Editor PHP plugin with the ID ckeditor5.
- ✅ Create a Drupal.editors JS plugin with the ID ckeditor5.
- ✅ Getting CKE5 (CKEditor 5) to load at all on the /node/add/article form.
- ✅ #3201820: Manually test that CKE 5 can be used in off-canvas
- ✅ Enable a Drupal + CKE5 ecosystem
- ✅ A CKE5 configuration UI
- ✅ Ensure Quick Edit integration works
- ✅ Evaluate CK4 plugins and match features
- ✅ #3201821: Add JavaScript test coverage for CKE 5
- ✅ #3206686: IE11 warning for CKE5 in Drupal 9
💯 Roadmap to Beta
- ✅ #3215506: Plugins should be enableable based on toolbar configuration
- ✅ Ensure filter_html's HTML restrictions are respected inside CKE5 — tackled in #3201637: Figure out how to prevent data loss during upgrade/migration path
- ✅ #3206687: Toolbar UI accessibility review
- ✅ #3201641: Improve the HTML filter configuration UX
- Enable translation features for CKEditor 5
Roadmap to Stable
- Ensure that sites can update from using CKE4 to CKE5 safely when using no contributed CKEditor modules
- Ensure that Arbitrary HTML is not lost: #3216021: Automatically use CKE5's General HTML Support feature on text formats without any TYPE_HTML_RESTRICTOR filter + add `sourceEditing` button
- #3201637: Figure out how to prevent data loss during upgrade/migration path
- #3216015: Generate CKEditor 5 configuration based on pre-existing text format configuration
- #3245079: Automatic upgrade path always enables all <h*> tags when only >=1 was enabled before
- #3245320: Automatic upgrade path always disables image uploads — in the UI
- #3228464: API for contrib projects to load CKEditor translations
- #3227822: [GHS] Ensure GHS works with our custom plugins, to allow adding additional attributes
- #3268174: Bug in CKE 4 → 5 upgrade path "format" does not always map to "heading", it could map to "codeBlock" too, or both, or neither
- #3269868: [drupalImage] Some Image attributes are lost in edge cases where image upcasts into inline image
- #3273527: Upgrade path never configures the ckeditor5_heading plugin to allow <h1>
- #3273312: Upgrading from CKEditor 4 for a text format that has FilterInterface::TYPE_MARKUP_LANGUAGE filters enabled
- #3268318: [drupalMedia] <a> with GHS allowed attributes downcast wraps data-caption with <a>
- #3230230: Enable table captions; override CKE5's default downcast to generate <table><caption></table> instead of <figure><table><figcaption></figure>
- #3268311: [upstream] [drupalMedia] GHS-enabled markup in data-caption crashes CKEditor 5
- #3272516: Deprecate FilterInterface::getHTMLRestrictions()' forbidden_tags functionality
- #3273510: CKEditor 5 crash when multiple alignment buttons are activated due to duplicate configuration thanks to #3259593: Alignment being available as separate buttons AND in dropdown is confusing
- Ensure contrib modules can do everything: translations, automatic upgrade path from CKE4 …
- #3226335: Follow-up for #3216015: allow contrib & custom Drupal modules providing CKEditor 4 plugins to specify their CKEditor 5 equivalents + settings to be migrated
- #3228778: Drupal-specific CKEditor 5 plugins should be able to use Drupal's JS translation API: Drupal.t()
- #3245723: Follow-up for #3201637: omitting PrimitiveTypeConstraint violations for filter settings is implemented too broadly
- #3245807: DX: allow contrib modules to subclass \Drupal\Tests\ckeditor5\Kernel\ValidatorsTest
- #3274278: Migrate "codetag" contrib CKEditor 4 plugin to built-in equivalent in core's CKEditor 5
- #3273325: CKE5 and contrib: better "next action" description on upgrade path messages
- Ensure CKE5 equivalent plugins of CKE4 generate/support equivalent markup: #3222801: [META] Ensure CKE5 equivalent plugins of CKE4 generate/support equivalent markup
- Infra: #3215466: Attribute values not accounted for in CKEditor5PluginManager::getProvidedElements
- Infra: #3207660: Allow using a subset of the tags supported by the enabled CKEditor 5 plugins
- #3222851: <cite>
- #3222847: <img width height>
- #3222838: Configure basicStyles.Italic to output <em> instead of <i>
- #3222842: <a hreflang> + <blockquote cite>
- #3222847: <img width height>
- #3220293: Make all supported heading types visible in the UI
- #3222840: <ol start>
- #3222852: <dl> <dt> <dd> by introducing "Manually editable HTML tags" configuration on Source Editing
- #3224256: <h* id> (or more generically: <$block id>)
- #3222808: Follow-up for #3201646: markup in image captions is lost
- #3228346: Follow-up for #3222852: revert ineditable attributes (<blockquote cite> and <a hreflang>) now that Source Editing plugin can handle arbitrary elements & attributes
- #3246168: Images are not linkable through UI; already linked images are unlinked (data loss!)
- #3246169: Embedded media are not linkable through UI; already linked embedded media are unlinked (data loss!)
- #3259493: [GHS] Unable to limit attribute values: ::allowedElementsStringToHtmlSupportConfig() does not generate configuration that CKEditor 5 expects
- #3246365: [drupalMedia] Show the Image Media's default alt text that is being overridden
- #3260853: [GHS] Partial wildcard attributes (<foo data-*>, <foo *-bar-*>, <foo *-bar>) and attribute values (<h2 id="jump-*">) not yet supported
- #3260869: Resolve mismatch between <$block> interpretation by CKEditor 5 and Drupal
- #3268860: Elements wrapping <drupal-media> are not retained
- #3268307: $block wildcard resolves into a superset of the actual $block tags
- Ensure CKE5 functionality matches that of Drupal core's CKE4:
- #3201646: Add support for image caption (<img data-caption>)
- #3211050: Add "Alignment" plugin
- #3211125: Add "Block Indentation" plugin, but only allow list indentation
- #3211282: Add plugins which are provided as a part of essential plugin: Undo/Redo
- #3211610: Add "Horizontal line" plugin.
- #3227871: Add ckeditor5-paste-from-office to allow pasting from Microsoft Office & Google Docs
- #3227875: Add ckeditor5-remove-format to allow removing formatting from pasted content
- #3227890: Add ckeditor5-special-characters to allow inserting special characters for users that do not know the native picker
- #3247246: Attribute value encoding not compatible with Xss::filter()
- #3248448: Dialog loading text is unstyled
- #3260554: [drupalMedia] Support alignment on <drupal-media>
- #3246380: [drupalMedia] Media previews do not update after alt text was modified
- #3224652: [drupalImage] Add ckeditor5-image's imageresize plugin to allow image resizing
- #3246385: [drupalMedia] Support captions on <drupal-media>
- #3264775: [drupalMedia] Toolbar should be visible when element inside <drupalMedia> is focused
- #3264727: [drupalMedia|drupalImage] Allow removing data-align in the UI, and making an image inline
- #3245950: [upstream] <script> tag support in GHS
- #3256566: [upstream] <style> tag support in GHS
- #3263384: Add ckeditor5-code-block package and CodeBlock plugin
- #3245720: [drupalMedia] Support choosing a view mode for <drupal-media>
- #3276974: [drupalMedia] Media View Modes don't work if alignment not enabled
- #3269657: [drupalMedia] The CKEditor 4 → 5 upgrade path for the media_embed filter should not forcefully allow the `data-view-mode` attribute on `<drupal-media>`
- ✅ Documentation gates:
- #3205654: ckeditor5_hook_help()
- #3201186: Create ckeditor5.api.php (the core equivalent of README.md) + CKEditor5PluginDefinition::toArray()
- #3243850: hook_ckeditor5_plugin_info_alter()'s example sets ['drupal']['config'], but that's not one of the documented definition properties
- #3248430: Improve Drupal.ckeditor5 documentation
- #3248425: Ensure that all classes and functions in Drupal-specific CKEditor 5 plugins are documented
- Theming CKEditor 5
- Accessibility
- #1872206: Improve CKEditor toolbar configuration accessibility
- #3218252: Toolbar configuration fieldset aria cleanup
- #3218260: Safari focus outline on buttons leaves artifacts after blur
- #3207451: Toolbar UI Button size accessibility
- #3238257: Fragment link pointing to <textarea> should be redirected to CKEditor 5 instance when CKEditor 5 replaced that textarea
- #3245735: Follow-up for #3222852: validation errors are not associated with the correct form element
- #3258030: Text fields using CKEditor 5 do not get visual error indicator
- #3258668: Extraneous closing parentheses and curly brace in visually-hidden button description text
- #3231321: Improve keyboard accessibility in a particular edge case
- #3261942: Compatibility issues with inline form errors
- #3218297: Voiceover + Safari reads aria-describedby twice when focusing toolbar button
- #3248440: [drupalMedia] Media embed attributes are rendered in container div in editing view
- #3239423: Toolbar UI accessibility review: round 2
- #3270112: Excessive aria-live announcing from ckeditor5-admin-help-message live region
- #3270110: Toolbar config items missing "press arrow to do {x}" instructions for screenreaders
- #3270108: Editor does not load when using Edge + WHCM
- #3222757: [drupalImage] Make image alt text required or strongly encouraged
- Test coverage, reliability and maintainability matching or exceeding CKEditor 4's:
- #3206522: Add FunctionalJavascript test coverage for media library
- #3201641: Improve the HTML filter configuration UX
- #3228920: Improve internal consistency: consistent variable names and return type syntax
- #3231327: Plugin definition DX: validate ckeditor5.drupal.elements items
- #3231362: Refactor ImageUpload's ::validateImageUploadSettings() into the proper validate and submit methods
- #3228505: Plugin definition DX: automatically check for plugin definitions whether their ::getDefaultSettings() matches the config schema
- #3243867: ckeditor5_module_implements_alter() looks like it has incorrect logic
- #3245400: Add an @throws PHPDoc everywhere exceptions are thrown
- #3246280: Defense in depth: add anti-CSRF token to this module's routes
- #3246521: Make plugin.manager.ckeditor4to5upgrade.plugin a private service
- #3246524: Make more (all?) classes @internal
- #3247711: Simplify and accelerate builds: update our use of the CKEditor 5 DLL manifest
- #3248188: Plugin definition DX: validate drupal.conditions
- #3248423: Decide how CKEditor 5-provided types should be referenced
- #3259174: Add missing CKE5 SmartDefaultSettings test coverage (wildcard tag with unsupported attribute)
- #3228334: Refactor HTMLRestrictionsUtilities to a HtmlRestrictions value object
- #3206523: Add FunctionalJavascript test coverage for image upload
- #3267721: Add DrupalCI step for ensuring that CKEditor 5 build files are build correctly
- #3231337: [drupalMedia] Remove manual dataDowncast from DrupalMediaEditing
- #3231328: SmartDefaultSettings should select the CKE5 plugin that minimizes creation of HTML restriction supersets
- #3228580: Follow-up for #3222852: additional test coverage for real-time validation race conditions
- #3265626: Changes to "Manually editable HTML tags" lost if form is submitted without triggering AJAX
- #3231334: Global attributes (<* lang> and <* dir="ltr rtl">): validation + support (fix data loss)
- #3229078: Unit tests for all @CKEditor5Plugin plugin classes
- Low-hanging fruit major UX improvements over CKEditor 4:
- Superior configuration UX:
- #3201641: Improve the HTML filter configuration UX
- #3216015: Generate CKEditor 5 configuration based on pre-existing text format configuration
- #3226694: Follow-up for #3216015: refactor SmartDefaultSettings to return messages rather than sending them
- #3248177: Language toolbar item cannot be removed from the toolbar
- #3259443: Plugin settings do not appear when a configurable plugin is added AFTER removing all buttons
- #3261585: Remove IE11 warning for CKEditor 5 in Drupal 10, since Drupal 10 does not support IE anyway
- #3260857: Expand SourceEditingRedundantTagsConstraintValidator to also check attributes and attribute values
- #3261943: Confusing behavior after pressing "Apply changes to allowed tags" with invalid value
- #3228691: Restrict allowed additional attributes to prevent self XSS
- Performance
- ✅ Moving things into core that can only happen once it is in core: