Problem/Motivation
If the top offset of the page changes (e.g. the website has a header that changes size when scrolling), the sticky panel of the CKEditor5 does not register the change and gets stuck 'midair' because of the previous value.
Even if on scroll Drupal.displace() is called to correctly calculate the new value for the top offset, and the CKEditor instance value for ui.viewportOffset
is updated, the StickyPanel class does not track this change (even though it is bound to this value).
Code in core/assets/vendor/ckeditor5/editor-classic/editor-classic.js that binds the value:
e.stickyPanel.bind("viewportTopOffset").to(this,"viewportOffset",(({top:e})=>e||0))
CKEditor is integrated with Drupal's displace api by updating the value of editor.ui.viewportOffset
:
$(document).on(
`drupalViewportOffsetChange.ckeditor5.${id}`,
(event, offsets) => {
editor.ui.viewportOffset = offsets;
},
);
Steps to reproduce
- Create a page header with the 'data-offset-top' attribute;
- Update the height of the header (for example on scroll) and recalculate the top offset value with Drupal.displace();
- Focus on a CKEditor5 instance;
- Scroll down while maintaining the focus on editor and observe weird behaviour of the panel.
Proposed resolution
For whatever reason, creating a clone object of the displace offsets works properly:
$(document).on(
`drupalViewportOffsetChange.ckeditor5.${id}`,
(event, offsets) => {
editor.ui.viewportOffset = Object.assign({}, offsets);
},
);
I think this is because Drupal never changes the offsets
object, just updates the values; so editor.ui.viewportOffset
always references the same object and the StickyPanel bind does not trigger at all.
See the patch below.
Remaining tasks
-
User interface changes
-
Introduced terminology
-
API changes
-
Data model changes
-
Release notes snippet
-