Problem/Motivation
The captioning experience of Entity Embed should match that of the drupalimage CKEditor plugin in Drupal core for uploading images.
Proposed resolution
Remaining tasks
Test coverage:
- 👍 Triggering "Source" button does not trigger a
blurevent on thecaptioneditable, which results in the source being inaccurate. Theblurevent should be triggered. - 👍 Bold, italics etc work in the
captioneditable *and* are properly HTML-encoded. - 👍 Inserting a link in the
captioneditable fails in thedrupallinkplugin on this line:var range = selection.getRanges(1)[0]; - 👍 Bold, italics etc work in the caption editable *and* are properly HTML-encoded *and* are displayed properly in the
EntityEmbedDialog*but* upon saving that dialog they're escaped. - 👍 Not specifying a caption in
EntityEmbedDialogcauses nodata-captionvalue to be sent to the client; the client should not fail, and automatically update the preview to be captionless.
User interface changes
Much better UX.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #28 | 2282957-28.patch | 3.19 KB | wim leers |
| #28 | interdiff.txt | 1.11 KB | wim leers |
| #27 | 2282957-26_plus_2544020-40.patch | 12.15 KB | wim leers |
| #26 | 2282957-26-do-not-test.patch | 3.48 KB | wim leers |
| #26 | interdiff.txt | 1.95 KB | wim leers |
Comments
Comment #1
dave reidComment #2
cs_shadow commentedPostponed until it's clear whether we can modify the plugin in core or we'll have to write our own caption plugin.
Comment #3
dave reidComment #4
dave reidComment #5
slashrsm commentedComment #6
slashrsm commentedComment #7
bkosborneWhat's nice about the core-provided image button is that you can use the CKEditor buttons to add bold, italic, and links. It seems like we can still manually write out the HTML for that using the entity embed caption textfield, but not ideal.
Does anyone have any insight as to why we have the caption textfield like we do instead of the checkbox that the image plugin provides?
Comment #8
bkosborneThe editable-in-widget functionality of CKEditor widgets relies on having a simple property on the embed widget definition called "editables". This property defines the DOM elements of our widget that can be edited inline the editor.
I tried setting this property just to see if it would do anything, and it does not. I think this is because we're using AJAX to replace the embed code with the DOM structure we want:
I can't say for sure, but it seems like since we're using AJAX like this, the editables feature of CKEditor may just not ever work. I'll spend a bit more time checking that out to be sure.
Comment #9
wim leers#2544020 should happen first, see #2544020-8: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin.
Comment #10
wim leersComment #11
wim leersComment #12
wim leersIf we can make this work, then #2990624: Cannot insert valid HTML tags in captions + test coverage for interaction with core's FilterCaption will be unnecessary.
Comment #13
wim leersThanks to the work I did on #2511404-73: Image entities/fields embedded using Entity Embed cannot be linked in CKEditor, I ended up with #2544020-18: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin. Which made doing what @bkosborne alluded to more than 2.5 years ago actually pretty simple.
This is not yet fully operational, because data is not yet being persisted. But this shows it can be made editable after all, and based on the work in #2544020-18: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin, I am fairly confident I can make this work completely tomorrow.
This is what it looks like:

Comment #14
wim leersForgot the patch without the blocker — that shows how few lines were required to at least make it look like it's working :)
Comment #15
wim leersPer #2544020-22: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin, two lines that should've been in this patch snuck into that patch.
Comment #16
wim leersActually,
parts.captiondoesn't make a lot of sense. Removing it, and documenting why.Comment #17
wim leersThis makes what you see in #13's screenshot actually work 🥳
Applies on top of #2544020-22: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin.
Edge cases to test:
blurevent on thecaptioneditable, which results in the source being inaccurate. Theblurevent should be triggered.captioneditable *and* are properly HTML-encoded.captioneditable fails in thedrupallinkplugin on this line:var range = selection.getRanges(1)[0];Comment #18
wim leersAs of #2544020-25: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin, changing the caption is no longer triggering re-fetching of server-side previews! Rebased on top of that patch.
Comment #19
wim leersSo … do we keep this in

EntityEmbedDialog? We should for now at least; removing it is out of scope for this issue. Some people may be relying on it. Tagging for that.In any case, if you created for example a caption with some emphasized or bold text in CKEditor, it'd show up correctly in the dialog, but upon saving it'd be escaped. This fixes that.
Edge cases to test:
EntityEmbedDialog*but* upon saving that dialog they're escaped.Comment #20
wim leersScreenshot to make #19 more clear what I'm referring to.
Comment #21
wim leersWRT having the
captioneditable and making it editable while making the captioned content (such as a Youtube video) unavailable for interaction: see #2544020-28: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin.Comment #22
wim leersEdge cases to test:
EntityEmbedDialogcauses nodata-captionvalue to be sent to the client; the client should not fail, and automatically update the preview to be captionless.This patch fixes that.
Comment #23
wim leersI asked Krzysztof yesterday (see #2544020-27: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin) about this.
He confirmed that
.on('change'is not available. He suggested.on('keyup'. That ensured this edge case was solved:… but it doesn't yet solve the case of the user selecting part of the caption and clicking the "Bold" button, then clicking the "Source" button. Even listening to more events (such as
clickandpaste) won't fix this.He had two suggestions for fixing this:
changeevents and then check if something has changed in the caption editable. This will result in many unnecessary function calls.downcast()event handler that #2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin introduced (and which he was both surprised by but also very supportive of) and force it to inspect the DOM for changes. He indicated that this is an unfortunate weakness in CKEditor 4, and there isn't much that can be done about it. This would mean moving the currentdowncast()logic to a_dataToHtml()helper method, and introducing a_updateDataBasedOnDomChangesForEditables()helper method, so that we'd end up with:After I wrote that, I realized that there actually now is something we could use: https://caniuse.com/mutationobserver. It has sufficient browser support. It doesn't require such hacks. Let's do it! 🤓
Comment #24
wim leersThese changes were accidental. Brought it back.
But thanks to the changes in #23, a clearer pattern now emerges.
Comment #25
wim leersFollowing the lead of #2544020-34: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin, doing the same for captions. That means that instead of showing
figcaption, it'll now showCaption.Comment #26
wim leersThe above patches don't work well yet in the scenario where no caption is turned on: in that case, this patch results in a JS error. Easily remedied.
Comment #27
wim leersLet's test this together with #2544020-40: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin.
Comment #28
wim leersTime for a final round of clean-up, then let's land this 🥳
We were only using
parts(which is optional: it exists merely for convenient access to DOM elements if a particular widget implementation needs a lot of DOM access) for link integration (#2511404: Image entities/fields embedded using Entity Embed cannot be linked in CKEditor) anymore. And as of #2511404-77: Image entities/fields embedded using Entity Embed cannot be linked in CKEditor, that's no longer using it anymore.So: time to drop
partsaltogether!Also this was using a copy/pasted
allowedContentfrom the CKEditor core codebase, now using the sameallowedContentas thedrupalimagecaptionplugin for consistency.Comment #29
wim leers#2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin just landed, let's test this.
Comment #30
wim leersThat passed :)
And
now also works.
For : created #3060396: Add CKEditor Widget JS test coverage.
For : created #3060397: [PP-1] Caption in both dialog and CKEditor widget is weird, should we remove the one in the dialog, to match core?.
Comment #32
wim leers🚢