OK, I've done some test and apparently `notify::title` is queue so even if you change title twice in a row in WebKit/JS land, GJS will receive all changes.
This made me able to create a simple JSONChannel class: https://gist.github.com/WebReflection/7ab0addec037508cc8380a9c37d285f2 I have that class and the following code in a browser.js file ```js const PageChannel = new JSONChannel('super-secret'); PageChannel .on('message', (err, data) => { if (err) console.error(err); else console.log(data); }) .send('ping'); ``` The index page is nothing more than just this: ```html <!doctype html> <script src="browser.js"></script> ``` The GJS part, simplified for demo purpose, is basically just this ```js 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); } ); } }); ``` You will see ping followed by pong in the console once you load that index.html Please note that document.title changes could be intercepted via MutationObserver or DOMSubtreeModified on a document with a title element and/or hacking the title accessor itself or the document, meaning the "secret" is not really secret but it's a way to setup a unique channel. There could be a convention to setup a channel automatically adding some extra logic on both sides (and I'll giv it a try in few minutes) but I hope you got the proof of concept and it works for your needs. It's simpler to implement than my hack on location and it works better/faster. Regards On Wed, Nov 1, 2017 at 1:17 PM, Andrea Giammarchi < andrea.giammar...@gmail.com> wrote: > 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.jan...@starleaf.com> > wrote: > >> >> >> On 1 November 2017 at 15:23, Andrea Giammarchi < >> andrea.giammar...@gmail.com> wrote: >> >>> so ... it looks really like the exposed API is completely useless as it >>> is >>> >>> ```js >>> webkit.messageHandlers.gjs.postMessage('hello'); >>> ``` >>> >>> Returns a >>> >>> [boxed instance proxy GIName:WebKit2.JavascriptResult >>> 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 JavaScriptCore.Value >>> >>> >>> What'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/sa >> ifulbkhan/wkjscore-result >> >> 7 import * as WkJsCore from '../../gjs/WkJsCore' >> ... >> 85 let contentManager = this.webkit.get_user_content_manager(); >> 86 if (!contentManager.register_scri >> pt_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 JavaScriptCore 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.giammar...@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 >>>> ...) >>>> >>>> Regards >>>> >>>> On Wed, Nov 1, 2017 at 10:50 AM, Sam Jansen <sam.jan...@starleaf.com> >>>> wrote: >>>> >>>>> >>>>> >>>>> On 1 November 2017 at 11:55, Andrea Giammarchi < >>>>> andrea.giammar...@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 response >>>>>> new MutationObserver(m => { >>>>>> if (/^secret:response=/.test(document.title)) { >>>>>> const data = JSON.parse(document.title.slic >>>>>> e(RegExp['$&'].length)); >>>>>> document.title = ''; >>>>>> console.log(data); >>>>>> } >>>>>> }).observe( >>>>>> document.querySelector('title'), >>>>>> {childList: true} >>>>>> ); >>>>>> >>>>>> // send info using client or simulate server sending in responses >>>>>> document.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 info >>>>>> >>>>>> >>>>> I'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.jan...@starleaf.com> >>>>>> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On 1 November 2017 at 05:43, <philip.chime...@gmail.com> wrote: >>>>>>> >>>>>>>> On Thu, Oct 12, 2017 at 5:23 AM Andrea Giammarchi < >>>>>>>> andrea.giammar...@gmail.com> wrote: >>>>>>>> >>>>>>>>> FWIW I've used the location with a private channel as protocol to >>>>>>>>> intercept calls to/from the page and GJS. >>>>>>>>> >>>>>>>>> https://github.com/WebReflection/jsgtk-twitter/blob/master/a >>>>>>>>> pp#L162-L175 >>>>>>>>> >>>>>>>>> The channel is a random string: https://github.com/Web >>>>>>>>> Reflection/jsgtk-twitter/blob/master/app#L59 >>>>>>>>> >>>>>>>>> From the page, which is aware of the "secret" channel, I call GJS >>>>>>>>> actions via location.href = `secret1234:method(${encodeURI >>>>>>>>> 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.runJavaScript https://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": >>>>>>>> http://devdocs.baznga.org/webkit240~4.0_api/webkit2.usercont >>>>>>>> entmanager#method-register_script_message_handler >>>>>>>> >>>>>>>> To send a message to the page, use the same thing that Andrea uses: >>>>>>>> http://devdocs.baznga.org/webkit240~4.0_api/webkit2.webview# >>>>>>>> method-run_javascript >>>>>>>> >>>>>>>> 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: >>>>>>>> http://devdocs.baznga.org/webkit240~4.0_api/webkit2.usercont >>>>>>>> entmanager#signal-script-message-received >>>>>>>> >>>>>>>> >>>>>>> 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 >>>>>>>> JavaScriptCore 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: >>>>>>> >>>>>>> https://github.com/saifulbkhan/wkjscore-result >>>>>>> >>>>>>> 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.patri...@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 >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >
_______________________________________________ javascript-list mailing list javascript-list@gnome.org https://mail.gnome.org/mailman/listinfo/javascript-list