Problem/Motivation
This issue originally surfaced on a Drupal 10.2.4 site with the Media Library embed tool enabled in CKEditor and contrib module
Editor Advanced Link →
installed and configured.
When a site user entered embedded an image media entity with the Media Library tool, then set the media to be a link to be opened in a new tab, but left the link URL empty, the page saved and displayed correct, with the media being wrapped in an <a href="">
tag. However, when going back to edit that content, the content becomes empty in the editor, and a JS error shows up in the console:
ckeditor5.js?schaem:468 TypeError: Cannot read properties of null (reading 'getAttribute')
at or (ckeditor5-dll.js?v=41.2.0:5:420624)
at er.setAttribute (ckeditor5-dll.js?v=41.2.0:5:412304)
at e.on.priority (drupalMedia.js?schaem:1:20214)
at Es.fire (ckeditor5-dll.js?v=41.2.0:5:634006)
at Es._convertItem (ckeditor5-dll.js?v=41.2.0:5:336068)
at Es._convertChildren (ckeditor5-dll.js?v=41.2.0:5:336528)
at Object.convertChildren (ckeditor5-dll.js?v=41.2.0:5:334642)
at Ms.upcastDispatcher.on.priority (ckeditor5-dll.js?v=41.2.0:5:340669)
at Es.fire (ckeditor5-dll.js?v=41.2.0:5:634006)
at Es._convertItem (ckeditor5-dll.js?v=41.2.0:5:336173)
(anonymous) @ ckeditor5.js?schaem:468
Investigating further, if the content is entered similarly, with the link URL being left empty, but not set to open in a new tab, again the content displays correctly on view, but on edit, the media in the editor is removed. In this case, there is no JS error.
In either case, while entering links with empty links is likely user error, it would be ideal for the editor to handle this more gracefully and allow editors to more easily correct the issue.
After
📌
Update CKEditor 5 to 41.2.0
Fixed
, this issue becomes harder to reproduce in Drupal 11.x or 10.3.x because the update to CKEditor5 41.0.0 prevents the entry of empty links by default, but it is still possible to reproduce with an implementation of hook_ckeditor5_plugin_info_alter()
that changes the configuration to allow empty links to be created (and adds the ability to set links to open in a new window).
Steps to reproduce
In Drupal 10.2.x:
- Install Drupal with standard profile
- Enable Media Library
- Configure Basic HTML text format and add Drupal Media to Active toolbar
- Enable the Embed media filter on Basic HTML text format and save the format
- Enable CKEditor functionality for the Link tool to allow users to set to open links in new tab/window. Either:
- Install
Editor Advanced Link. →
Configure Basic HTML format and Enable all attributes for Advanced links. OR
- Create and enable a custom module (e.g. mymodule) that implements
hook_ckeditor5_plugin_info_alter()
:
/**
* Implements hook_ckeditor5_plugin_info_alter().
*/
function mymodule_ckeditor5_ckeditor5_plugin_info_alter(array &$plugin_definitions) {
assert($plugin_definitions['ckeditor5_link'] instanceof CKEditor5PluginDefinition);
$link_plugin_definition = $plugin_definitions['ckeditor5_link']
->toArray();
$link_plugin_definition['ckeditor5']['config']['link']['decorators'][] = [
'mode' => 'manual',
'label' => t('Open in new window'),
'attributes' => [
'target' => '_blank',
],
];
$plugin_definitions['ckeditor5_link'] = new CKEditor5PluginDefinition($link_plugin_definition);
}
For Drupal 10.3+, the additional step needed is to enable creating empty links. So in hook_ckeditor5_plugin_info_alter()
:
/**
* Implements hook_ckeditor5_plugin_info_alter().
*/
function mymodule_ckeditor5_plugin_info_alter(array &$plugin_definitions) {
assert($plugin_definitions['ckeditor5_link'] instanceof CKEditor5PluginDefinition);
$link_plugin_definition = $plugin_definitions['ckeditor5_link']
->toArray();
$link_plugin_definition['ckeditor5']['config']['link']['allowCreatingEmptyLinks'] = TRUE;
$plugin_definitions['ckeditor5_link'] = new CKEditor5PluginDefinition($link_plugin_definition);
}
Proposed resolution
In core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaediting.js
, there is code that checks whether the href attribute is missing:
const linkHref = viewLink.getAttribute('href');
// Missing the `href` attribute.
if (!linkHref) {
return;
}
Changing the condition to a null check addresses the error:
const linkHref = viewLink.getAttribute('href');
// Missing the `href` attribute.
if (linkHref === null) {
return;
}
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet