tinymce-docs icon indicating copy to clipboard operation
tinymce-docs copied to clipboard

The body_class setting has no effect in inline mode

Open adamayres opened this issue 5 years ago • 2 comments

What is the current behavior? Describe the bug

When using inline mode, the body_class setting does not apply to the <div> created by the editor that represents the content body. When inline mode is disabled, the specified body_class is properly applied on the <body> element within the <iframe>. In both cases the class of mce-content-body is applied to the <div> or <body> based on if inline is enabled or not.

Please provide the steps to reproduce and if possible a minimal demo of the problem via fiddle.tiny.cloud or similar.

Reproducible demo: https://fiddle.tiny.cloud/Y1haab/1

What is the expected behavior?

Since the mce-content-body class is being applied to both the <body> element when using the normal mode and to the <div> when using the inline mode, my expectation was that the body_class would also apply in both of these places. Currently, the body_class only applies when inline is disabled.

If body_class was not intended for the <div> created when using inline mode, perhaps you would consider allowing a new setting that can be used for this functionality.

Which versions of TinyMCE, and which browser / OS are affected by this issue? Did this work in previous versions of TinyMCE?

TinyMce: 5.6.2 Chrome: 87.0.4280.88 MacOS: 10.15.7

Additional Info

Code where classes are added in non-inline mode:

/modules/tinymce/src/core/main/ts/init/InitIframe.ts

const bodyClass = Settings.getBodyClass(editor);

...

iframeHTML += '</head><body id="' + bodyId +
  '" class="mce-content-body ' + bodyClass +
  '" data-id="' + editor.id + '"><br></body></html>';

Code where classes are added in inline mode:

/modules/tinymce/src/core/main/ts/init/InitContentBody.ts#L385

if (editor.inline) {
  DOM.addClass(targetElm, 'mce-content-body');
  editor.contentDocument = doc = document;
  editor.contentWindow = window;
  editor.bodyElement = targetElm;
  editor.contentAreaContainer = targetElm;
}

Potential fix

InitContentBody.ts

if (editor.inline) {
  const bodyClass = Settings.getBodyClass(editor);
  DOM.addClass(targetElm, `mce-content-body ${bodyClass}`);
  ...
}

adamayres avatar Jan 04 '21 21:01 adamayres

Hi @adamayres, body_class is designed for iframe mode, as we create the elements that wrap the editor content - namely, the iframe. body_class (and body_id) allow for classes (and IDs) to be added to the body of the iframe that TinyMCE creates. In inline mode, we use the element that the selector setting refers to, and therefore we assume that any required classes or IDs are already on that element. This is because inline mode is designed to visually integrate with the page the editor is in, and therefore tries to make as few visual changes as possible. Adding a class or ID to the editor element may trigger visual changes while editing that may not be reflected in the published content, and therefore we avoid it.

Your question has highlighted that the docs do not specify that these settings only apply to iframe mode, so I'm going to transfer this issue to the docs repo.

However, we have also been discussing the current functionality of these settings and whether we might want to change or add anything. To help us with that, could you please tell us more about your use case? Are you unable to manually add the class to your inline editor element for some reason?

metricjs avatar Jan 13 '21 08:01 metricjs

In our case we needed body_class to set for the scrollbar css customizations (reusable global classname). We're using tinymce-angular and hanks to this issue we found out why body_class doesn't work, so we had to subscribe to editor init event and set classname through it (vanilla js classList). But it would be way easier and less hacky to do that through body_class.

liesahead avatar Mar 03 '21 08:03 liesahead