Skip to content

[BUG] Safari: TinyMCE dialogs render inside 2sxc editor container and become unusable #3753

Description

@spronu

Describe the bug

On Safari/WebKit browsers, TinyMCE dialogs in the 2sxc WYSIWYG editor do not render as proper modal overlays.

Instead, the dialog appears to stay constrained inside the editor container / Shadow DOM context, so it does not escape the text editor area correctly. As a result, the dialog is clipped, not fully visible, and difficult or impossible to use.

This affects dialogs such as:

  • Insert/Edit Link
  • Insert/Edit Image
  • Insert/Edit Media

In some cases, the URL-related control is also not usable or not visible, but the larger issue is that the dialog itself is rendered incorrectly on Safari.

To Reproduce

  1. Open a 2sxc edit form containing a WYSIWYG field in Safari
  2. Focus the TinyMCE editor
  3. Open a dialog such as:
    • Insert/Edit Link
    • Insert/Edit Image
    • Insert/Edit Media
  4. Observe that the dialog does not behave like a normal modal overlay and remains visually constrained inside the editor area

Expected behavior

The TinyMCE dialog should render as a proper overlay/modal above the page UI, fully visible and usable.

Actual behavior

On Safari, the dialog appears trapped inside the editor container / Shadow DOM rendering context, causing clipping/layout problems and making it unusable.

Root cause analysis

2sxc wraps TinyMCE inside a Shadow DOM for CSS isolation.

TinyMCE 6.x does not officially support Shadow DOM. In 2sxc, TinyMCE is initialized with:

  • inline: true
  • fixed_toolbar_container pointing to an element inside the Shadow DOM

When fixed_toolbar_container is present, TinyMCE renders UI in fixed container mode rather than split UI mode. This means dialogs are rendered inside the Shadow DOM/editor context instead of being rendered on document.body.

On Safari/WebKit, this causes the dialog to remain visually constrained inside the editor area instead of appearing as a normal modal overlay. Controls using TinyMCE/Alloy urlinput may also fail in this context.

Why ui_mode: "split" alone does not fix it

TinyMCE only uses split UI mode if no fixed container is active.

Relevant logic:

isSplitUiMode = (editor) =>
  !useFixedContainer(editor) && "split" === editor.options.get("ui_mode");

So if fixed_toolbar_container is present, ui_mode: "split" is ignored. That means the fixed toolbar container must be removed for split mode to take effect.

Working workaround

A Safari-only workaround was tested successfully by intercepting tinymce.init() and:

  1. removing fixed_toolbar_container
  2. setting ui_mode: "split"
  3. injecting the TinyMCE skin CSS globally into <head>

This causes dialogs to render outside the Shadow DOM on document.body, where they behave like proper overlays and become usable again.

Side effects

On Safari only, the toolbar switches from fixed-container behavior to TinyMCE’s normal floating inline toolbar behavior.

Other chromium browsers remain unaffected.

Tested with

  • 2sxc: 19.03.03
  • TinyMCE: 6.8.5
  • TinyMCE skin: 2sxc-tinymce-skin
  • Safari on macOS and iOS
  • Chromium Browsers unaffected

Suggested fix

Consider a Safari-specific fallback in 2sxc’s TinyMCE integration:

  • disable fixed_toolbar_container on Safari
  • force ui_mode: "split"
  • ensure TinyMCE dialog skin CSS is available globally when dialogs render outside the Shadow DOM

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions