const PageChannel = new JSONChannel('super-secret'); PageChannel .on('message', (err, data) => { if (err) console.error(err); else console.log(data); }) .send('ping');
<!doctype html> <script src="browser.js"></script>
const secret = 'super-secret'; const re = new RegExp(`^${secret}:js=`); webView.connect('notify::title', (self, params) => { if (re.test(self.title)) { const data = JSON.parse(self.title.slice(RegExp['$&'].length)); print(data); self.run_javascript( `document.dispatchEvent( new CustomEvent( '${secret}:gjs', {detail: ${JSON.stringify('pong')}} ) );`, null, (self, result, error) => { self.run_javascript_finish(result); } ); } });
I'd be OK if WebKitGTK could at least accept strings and pass them along ... wkjscore-result should be part of the core, IMO.On Wed, Nov 1, 2017 at 12:28 PM, Sam Jansen <sam jansen starleaf com> wrote:On 1 November 2017 at 15:23, Andrea Giammarchi <andrea giammarchi gmail com> wrote:so ... it looks really like the exposed API is completely useless as it is```jswebkit.messageHandlers.gjs.postMessage ('hello');```Returns a[boxed instance proxy GIName:WebKit2._javascript_Result jsobj@0x7fa08c2e4160 native@0x7fa052081d80] and if you try to get its value it goes bananas with a message like:Gjs-WARNING **: JS ERROR: Error: Unable to find module implementing foreign type _javascript_Core.ValueWhat's the purpose of register_script_message_handler at all? What am I missing?Andrea, this is the problem Philip raised earlier and I replied to. I use this library to solve the problem: https://github.com/saifulbkhan/wkjscore-result 7 import * as WkJsCore from '../../gjs/WkJsCore'...85 let contentManager = this.webkit.get_user_content_manager(); 86 if (!contentManager.register_script_message_handler('slinternal ')) { 87 throw "register_script_message_handler() failed"; 88 }89 contentManager.connect("script-message-received::foobar", (obj, jsResult) => { 90 let wkResult = WkJsCore.Result.new(jsResult);91 let str = wkResult.process_result_as_string(); Unfortunately _javascript_Core doesn't provide it's own GIR API to access the JS data :(On Wed, Nov 1, 2017 at 11:02 AM, Andrea Giammarchi <andrea giammarchi gmail com> wrote:I've quickly provided a proof of concept but you could have a JSONChannel class singleton on the client side that queue each info and wait for the GJS side to receive one before sending another.I might try a real implementation though and see how it works.however, this is just a work around for the fact you can send messages without any content (... and I wonder how that can be useful in any way ...)RegardsOn Wed, Nov 1, 2017 at 10:50 AM, Sam Jansen <sam jansen starleaf com> wrote:On 1 November 2017 at 11:55, Andrea Giammarchi <andrea giammarchi gmail com> wrote:Actually the `notify::title` with a prefixed "secret-channel" and serialized JSON looks like the best of them all, for the time being, as it makes it straight forward for both client and server to communicate.```js// listen to each responsenew MutationObserver(m => {if (/^secret:response=/.test(document.title)) { const data = "">e(RegExp['$&'].length));document.title = '';console.log(data);}}).observe(document.querySelector('title'), {childList: true});// send info using client or simulate server sending in responsesdocument.title = 'secret:response=' + JSON.stringify({some: 'value'});```with a proper class/wrap to handle events and send data transparently it might be a great way to exchange infoI've just come to the opposite conclusion, though I don't disagree as such...My concern is that setting document.title, and having notify::title called is asynchronous (I believe). So in your JS, if one had:```document.title = '1'document.title = '2'```Then by the time notify::title is called, and you inspect your "webkit.title" property, I'd expect you'd only see the '2' value, and (likely) not the '1'.It's possible to solve this by ensuring the GJS side has picked up a message, and e.g. reset the title, I suppose. This feels like an awkward solution to me though.On Wed, Nov 1, 2017 at 5:53 AM, Sam Jansen <sam jansen starleaf com> wrote:On 1 November 2017 at 05:43, <philip chimento gmail com> wrote:On Thu, Oct 12, 2017 at 5:23 AM Andrea Giammarchi <andrea giammarchi gmail com> wrote:FWIW I've used the location with a private channel as protocol to intercept calls to/from the page and GJS.The channel is a random string: https://github.com/WebReflection/jsgtk-twitter/blob/ master/app#L59 From the page, which is aware of the "secret" channel, I call GJS actions via location.href = "">Component(JSON.stringify(value))})`; The protocol secret1234 is intercepted and the `controller.method(JSON.parse(decodeURIComponent(restOfURI)) )` invoked. To signal the page everything is fine I use this.webView.runJavaScripthttps://github.com/WebReflect ion/jsgtk-twitter/blob/master/ app#L377 The page has a listener for the `secret1234` event on the main window, and such listener is instrumented to react accordingly with the CustomEvent .detail payload/info.This might look a bit convoluted, and it has JSON serialization as limitation for the kind of data you want to pass (i.e. I use base64 encoded images as source from remotely fetched files enabling somehow CORS for whatever I want) but it worked well, circumventing the missing communication channel available in Qt.Maybe today there are better ways for doing a similar thing and if that's the case, please share.Here is another, fairly new, way to do it. Start out by registering a "script message handler":To send a message to the page, use the same thing that Andrea uses:To send a message from the page to the GJS program, use the postMessage() method mentioned in the documentation, and connect to this signal in your GJS program to receive the message:Excellent - I had not noticed this. My first attempt at communicating between WebKit2 and GJS was via setting "document.title" and having GJS connect to the "notify::title" signal! Not a great approach, this looks much better.Although I just realized that unfortunately the values won't be able to be marshalled into GJS since you need to use the _javascript_Core API to get at them. This is a really nice method in C, but in JS you can only use it to send a message without any content. That is annoying. I should probably open up an issue about this.I just hit upon this problem myself. In researching it, I found it is solved (at least well enough for my use-case) with this open source library:It's awkward having another dependency for me, especially one that isn't in a normal Ubuntu/Fedora/etc. package, but otherwise this approach worked fine for me.On Wed, Oct 11, 2017 at 12:57 PM, Adriano Patrizio <adriano patrizio hotmail com> wrote:Thank you for response, this is my problem: have necessity to implement methods into my web application webkit2 based and comunicate with GJS script (example: filesystem functions to read and write files or window managment).Regards,Philip C
_______________________________________________
_javascript_-list mailing list
_javascript_-list gnome org
https://mail.gnome.org/mailman/listinfo/_javascript_-list