In QT 5, does javascript's window.postMessage work in a QWebView ?
-
wrote on 23 Jun 2015, 16:32 last edited by
Same code trying to send a message between browser's Window, see doc/example
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
works in Chrome/Firefox/IE but not in a QT application with a main QWebView with childs' QWebView.Thanks,
Arfy -
Same code trying to send a message between browser's Window, see doc/example
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
works in Chrome/Firefox/IE but not in a QT application with a main QWebView with childs' QWebView.Thanks,
Arfywrote on 20 Nov 2015, 05:59 last edited by@Arfy said:
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
I got this working. You have to include the
<!DOCTYPE html>
in your HTML to trigger the HTML5 handler, because this is an HTML5 feature only. I also used Qt 5.5's QWebView widget in a widget app and didn't do this the QML route. I found the tech preview of QtWebView quite flaky and documented this here:http://forum.qt.io/topic/60798/applestore-and-qtwebview-webkit-qt5-5/10
So, using the stable QWebView widget approach, I used an IFRAME inside my web page and could communicate between the IFRAME child and its parent by using postMessage().
In the parent document, you have to do this:
$(document).ready(function(){ $('#myIFRAME').load(function(){ $(this)[0].contentWindow.postMessage('setEvent();','*'); }); });
In the IFRAME child document, you need to add this:
var goLastEvent = null; //respond to events window.addEventListener('message',function(event) { goLastEvent = event; // add code here to parse event.data, which is your message. });
Then, when the iframe needs to talk back to the parent document, it can do it like so:
goLastEvent.source.postMessage('runFoo();','*');
Of course, the parent document then needs this code to receive that message:
var goLastEvent = null; //respond to events window.addEventListener('message',function(event) { goLastEvent = event; // add code here to parse event.data, which is your message. });
That said, you may be surprised to find out that window.parent.foo() is possible, in other words, direct function calls, instead of having to do message passing between IFRAME and parent. However, this is only when run inside a Qt widget application -- it won't work if you try to load your HTML pages in your browser. (Well, note that I'm using file::// URLs instead of remote URLs -- your experience may vary on remote URLs.)
And then, once you learn this, you can read up on the QWebView bridge so that you can inject a C++ class into your DOM so that the Javascript can call C++ object methods directly without having to do message passing. However, my tests showed that this bridge only works with the parent document. So, if you need it in an IFRAME child, you'll have to get the IFRAME child to either do the window.parent.foo() technique, or use the postMessage API, in order to tell the parent to do some task with the DOM-injected C++ object.
Last but not least -- this is all going to change when QtWebEngine comes out in the next version of Qt after 5.5. I talk a little about what I know about it here:
http://forum.qt.io/topic/60798/applestore-and-qtwebview-webkit-qt5-5/10