I’m trying to render a TinyMCE iframe through a JS hook with Phoenix LiveView. Because dom patching removes the iframe node from the dom on every render, I have to set phx-update="ignore"
on the parent node of the hook. It works well until another unrelated node is added to the dom via an :if={@show}
attribute, then the content of the iframe’s inner body tag is removed, even though my guess is that it should not.
# EditorHook.js
const EditorHook = {
content() {
return this.el.dataset.content;
},
mounted() {
const scope = this;
tinymce.init({
selector: `#${this.el.id}`,
setup: editor => {
editor.on('init', () => {
editor.setContent(scope.content());
})
}
)
}
}
}
# index.html.heex
<.modal
:if={@show}
id="exit-confirmation-modal"
show={@show}
on_cancel={JS.push("show_exit_confirmation_modal", value: %{show: false})}
>
...
</.modal>
...
<div id={"editor-#{@id}-container"} phx-update="ignore">
<div
id={"editor-#{@id}"}
phx-hook="EditorHook"
data-content="<span>Hello, World.</span>"
/>
</div>
Here’s the rendered HTML before assign(socket, show: true)
:
<div id="editor-2-container" class="pt-5" phx-update="ignore">
<div id="editor-2" phx-hook="EditorHook" data-content="<span>Hello, World.</span>" style="display: none;" aria-hidden="true"></div>
<div role="application" class="tox tox-tinymce" aria-disabled="false" style="visibility: hidden; height: 650px;">
<div class="tox-editor-container">
<div class="tox-edit-area">
<iframe id="editor-2_ifr" frameborder="0" allowtransparency="true" title="Zone de Texte Riche" class="tox-edit-area__iframe" srcdoc="<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body id="tinymce" class="mce-content-body " data-id="editor-2" aria-label="Zone de Texte Riche. Appuyez sur ALT-0 pour l'aide."><br></body></html>">
#document
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" id="mce-u0" href="http://localhost:4000/assets/skins/ui/oxide/content.min.css">
<link rel="stylesheet" type="text/css" id="mce-u1" href="http://localhost:4000/assets/skins/content/default/content.css">
</head>
<body id="tinymce" class="mce-content-body " data-id="editor-2" aria-label="Zone de Texte Riche. Appuyez sur ALT-0 pour l'aide." contenteditable="true" spellcheck="false">
<p>Hello, World.</p>
</body>
</html>
</iframe>
</div>
</div>
</div>
</div>
And after:
<div id="editor-2-container" class="pt-5" phx-update="ignore">
<div id="editor-2" phx-hook="EditorHook" data-content="<span>Hello, World.</span>" style="display: none;" aria-hidden="true"></div>
<div role="application" class="tox tox-tinymce" aria-disabled="false" style="visibility: hidden; height: 650px;">
<div class="tox-editor-container">
<div class="tox-edit-area">
<iframe id="editor-2_ifr" frameborder="0" allowtransparency="true" title="Zone de Texte Riche" class="tox-edit-area__iframe" srcdoc="<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body id="tinymce" class="mce-content-body " data-id="editor-2" aria-label="Zone de Texte Riche. Appuyez sur ALT-0 pour l'aide."><br></body></html>">
#document
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body id="tinymce" class="mce-content-body " data-id="editor-2" aria-label="Zone de Texte Riche. Appuyez sur ALT-0 pour l'aide." contenteditable="true" spellcheck="false">
<br>
</body>
</html>
</iframe>
</div>
</div>
</div>
</div>
The content of the iframe after the update is the value of the srcdoc
attribute. When setting the editor to inline_mode: true
which renders it without an iframe, dom patching doesn’t have any effect.
Thanks in advance for your help!