Request: add message API to support smooth iframe integration

In my product I integrate node-red in <iframe> inside a bigger admin dashboard which is written in Angular. Also I put a list of node-red flows to the left-side menu of my dashboard as it is more convenient for me from UI perspective.

CURRENT STATE: when I select flow on my left-side menu I have to reload content of iframe as there is no possibility to communicate with node-red inside and instruct it to switch to different flow smoothly. Result: refresh of node-red inside iframe.

PROPOSAL: include in index.mst following script:


...

<!-- PATCH: BEGIN -->
<script>
    function displayMessage (evt) {
        const selector =  `red-ui-tab-${evt.data}`
        const el = document.getElementById(selector);
        const elTrigger = el.querySelector('a');
        if (elTrigger.onclick) {
        elTrigger.onclick();
        } else if (elTrigger.click) {
        elTrigger.click();
        }
    }

    if (window.addEventListener) {
        // For standards-compliant web browsers
        window.addEventListener("message", displayMessage, false);
    } else {
        window.attachEvent("onmessage", displayMessage);
    }
</script>
<!-- PATCH: END -->

</body>
</html>

with such script in place it would be possible to have implementation on Angular front-end similar as below and have smooth switch between flows inside iframe:

HTML:

<iframe #noderedframe id="noderedframe" class="editor__frame" src="http://localhost:8000/red/" width="100%" height="768"></iframe>

Angular + TypeScript:

  @ViewChild('noderedframe') nodered: ElementRef<HTMLIFrameElement>;
...
  postMessageSelectedFlow(flowId: string) {
    this.nodered.nativeElement.contentWindow.postMessage(flowId.replace('.', '-'), 'http://localhost:8000');
  }

ADDITIONAL PROPOSAL (OPTIONAL): extend node-red front-end with richer API in order to control its behavior inside iframe, for example: hide native tab-bar with flow names if it is implemented outside as in above scenario.

Using the editorTheme setting you can add whatever custom scripts you want to the editor page. There is no need for us to build this security vulnerability into the default editor.

https://nodered.org/docs/user-guide/runtime/configuration#editor-themes

1 Like

Sorry, don't see in editorTheme possibility for script injection. Which property should I use?
Should I provide after that editorTheme as follow?

        const settings = {
            httpAdminRoot: '/red',
            httpNodeRoot: '/api',
            userDir: CONST_CONFIGURATION.node_red_user_dir,
            functionGlobalContext: {}, 
            editorTheme {
              // some property ?? for script injection
            },
        };

        // Initialise the runtime with a server and settings
        RED.init(server, settings);

Thank you in advance for your help.

Sorry, didn't spot the example in the docs wasn't complete.

You want editorTheme.page.scripts

Ah, ok, make sense. Does this property support array with stings or should I provide its value as a comma separated string as "/abs_path/script1, /abs_path/script2"?

Array of strings should do it

Ok, I have managed to inject my script and achieve desired behavior. What should we do with this request/discussion now? How to close it?

We stop replying to it and let it fade away into the mists of time.

5 Likes