4

I'm porting a TinyMCE 3 installation to version 5. I set up a toolbar button that opens a dialog that contains a custom page and is therefore loaded using the new windowManager.openUrl method. I have some footer buttons, too, and, of course, an onAction( dialogApi, details ) handler that is invoked when a button is clicked. details.name contains the name of the button that was clicked so I can react on every click individually.

It seems, when a regular dialog is used, I configure every input field in my plugin.js file and retrieve its value through the getData method of first param that in passed into my onAction handler. This method does not exist in my dialogApi for the URL dialog.

My iframe/dialog contains a dropdown and I want to insert the selected value into the editor instance when a dialog footer button is clicked. I understand I can use postMessage to send information from the iframe to the plugin but that's not what I want.

How can I access input fields in the dialog, when a button is clicked and my dialog was opened through openUrl? How do I access the document in the dialog's iframe? this seems to be the JavaScript object I passed into openUrl. document is the page where the editor is embedded.

Bernhard Döbler
  • 1,960
  • 2
  • 25
  • 39

1 Answers1

7

I've made a demo that shows two different ways of getting the data from user inputs in an iframe dialog: https://codesandbox.io/embed/tinymce-dialog-openurl-demo-fpfew

This blog post is also an excellent resource for working with iframe dialogs in TinyMCE: https://www.martyfriedel.com/blog/tinymce-5-url-dialog-component-and-window-messaging

The first method in my demo uses a button in the HTML of the iframe itself. That button collects user data and uses postMessage to send that data back to the TinyMCE editor.

As you can see, the process is a little more complex using the footer buttons as opposed to the "in iframe" button. Essentially, the footer button sends a message to the iframe in the dialog asking the iframe to collect and insert user data into TinyMCE.

When using an iframe, you have to respect the browser security policy, so most times you can't interact with an iframe directly (the exception being if the iframe uses the same domain). Here's some more information about iframe security policy:

https://security.stackexchange.com/questions/67889/why-do-browsers-enforce-the-same-origin-security-policy-on-iframes

This also means that TinyMCE has no way of knowing what's inside the iframe like it does with a TinyMCE dialog, so the data needs to be fetched "manually". With that in mind, if it's a cross origin request (different domain) there's no way to access the iframe content without using postMessage.

The getData method mentioned works with TinyMCE dialogs because everything in the dialog is a TinyMCE component. TinyMCE components have a custom concept of values/states that getData can access to return data.

When you use a URL dialog, the dialog no longer uses TinyMCE components so it isn't able to collect the data for getData, hence it the method doesn't exist. That's why you have to manually get the data needed from whatever elements are in the URL dialog, and send them back to TinyMCE using postMessage.

Tiny Lincoln
  • 1,037
  • 5
  • 7
  • Thanks alot for your answer and the sample. I saw the github repo before posting https://github.com/martyf/tinymce-5-plugin-playground and had the idea it may work sending postMessage to the dialog and as a response call sendMessage on the editor. – Bernhard Döbler Jul 31 '19 at 20:44