Problem/Motivation
In #2994696: Render embedded media items in CKEditor, we added the ability for media items embedded in formatted text to be previewable in CKEditor. The previews are fully rendered media entities. The problem, though, is that if those media entities have attached asset libraries, those libraries are NOT included as part of the rendered preview.
This is totally intentional, for reasons that can be summed up as "overwhelming, unjustified complexity". As Wim Leers stated in #2994696-214: Render embedded media items in CKEditor:
We specifically do not want to load asset libraries associated with a rendered entity because A) that would also load JS, and we don't want previews to become interactive, they're just previews, B) a rendered media entity's hypothetical attached CSS (because there isn't any in Drupal core) would be written with the assumption that basic theme CSS is already present, which is not true in CKEditor iframe instances.
[...] Media entities rendered by Drupal don't have asset libraries attached by default. I explained above why we don't want this. I can expand on it more if you like. Loading attached CSS and JS — problematic as it is for the reasons I've outlined already — would require us to use the AJAX system. This would mean that requests would use the back-end theme instead of the front-end theme, thus loading both the wrong template (that of the admin theme) and the wrong asset libraries (those of the admin theme). It would also make the responses uncacheable (AJAX responses are uncacheable). If you want the nitty gritty background, see #2844822: The preview in CKEditor does not use the same Twig template as the one on the front end (default theme). Specifically, see #2844822-41: The preview in CKEditor does not use the same Twig template as the one on the front end (default theme), where I anticipated this would come up 🙉. Entity Embed prior to 1.0 was using the AJAX system. One early user with a super advanced use case needed it. They acknowledged it would not work for everyone always. Many people ran into the problem of the wrong Twig template being used. By now 23% of all Drupal 8 Entity Embed installs is using 8.x-1.0 where no AJAX request is used, and hence no CSS or JS is loaded. There have been no complaints. (I just triaged the Entity Embed issue queue again to make sure.)
We agreed to open this issue as a place to further discuss this, if it's requested by enough people.
Proposed resolution
TBD
Remaining tasks
TBD
User interface changes
TBD
API changes
TBD
Data model changes
TBD
Release notes snippet
TBD
Comments
Comment #3
dave reidI am needing this. I am adding an embeddable render element widget, that lets the user pick which render element to use. The attached CSS and JS is dependent on what the user picks, and I cannot determine this ahead of time, aside from including *all possible CSS*. I am using the Embed module to run the returned preview HTML but the attached CSS and JS is being attached to the root document head, and not the head inside the CKEditor iframe instance.
Comment #4
maximpodorov commentedI also need the ability to render media entity on the client side using attached JS and drupalSettings.
Comment #5
maximpodorov commentedI have solved the problem of inability to preview JS-based media entities by invoking an additional AJAX request to /embed/preview/rich_text (embed module) - the response is processed in the usual Drupal way.
Comment #7
johnnybgoode commentedI could also use this, I need to embed an entity that relies on CSS and JS from a library for proper display. I agree 100% that embedded entities should not be interactive, but their attached libraries should load so that they can be displayed correctly without workarounds.
@maximpodorov can you give more details on how that additional AJAX request is invoked to work around the current problem?
Comment #8
maximpodorov commentedSomething like this:
Comment #9
phenaproximaComment #11
scotwith1tThis is also critical for our project. The editors need to see exactly what the rendered embedded entity will look like when saved/published while they are editing; not including the js and css attached in the template for the view mode completely changes the way the embedded entity behaves in WYSIWYG and makes us have to create some hacks or alternate (superfluous and less effective "previews") view modes to approximate the behavior in the back end theme/CKeditor. We may eventually come up with a contributable solution for this, but for now wanted to at least voice support for somehow including attached assets without being disruptive or overly complex.
Comment #12
seanbJust had a quick chat with phenaproxima about this. Allowing libraries to be attached to CkEditor is apparently not an easy thing to do (see the IS). As a workaround though, it might already help if the media templates can somehow determine they are being used as a "preview", and the attached libraries will not work.
We can discuss how the template can determine that it is being used in CkEditor, and if the Media entity itself should be aware of that (through something like a
isPreviewing/setPreviewContextmethod). Not sure if the workaround should be implemented in this issue or if we should create a new one for it, but to be honest I think providing some variable/context to the media template is the only way we can get anything close to an improvement for this in the short term.Any thoughts?
Comment #13
bkosborneI'm a big proponent of letting media entities know they're in a "preview" state. +1 to that approach.
It's just too tricky to get some media entities rendering correctly in the editor. I'd rather just know they're in that state and render some kind of placeholder instead.
Have to make sure it's not cached though.
Comment #18
karlsheaIt is actually insane that there's literally no way to tell if the media item is being rendered inside CKEditor.
This does not work:
This is the ridiculous thing I had to do in order to allow clicking on a media item so you can adjust display mode etc:
I can't imagine what other media embeds will need to go through to suppress behavior.
Comment #20
mably commentedIn our special use case we add to load some JS after a custom web component was displayed as a media.
We wrote a Javascript MutationObserver to detect the addition to the page of our custom element and load the related javascript library.
Here is an quick and dirty piece of code for those interested:
We used Asset Injector for our test, script was activated only on
node/*/editpages.Comment #21
s_leu commented+1 for this feature. It's a WYSIWYG editor after all, so at least CSS should be rendered when previewing.
Comment #22
loze commentedI also need this. +1