How to expose native code to javascript in webkit2gtk - javascript

I want to expose a native object or function to javascript so that i can have a callback function in C when the particular function is called in browser.
From this example, it seems it is possible in WebKitGTK1 using the signal "window-object-cleared".
How can i achieve the same in WebKitGTK2, i hope it has something to do with WebKitWebExtension. But i am not sure and also there is not clear guidelines or examples for implementing WebKitWebExtension. Can anyone help me with a solution for my request ?

Yes, WebKitWebExtension is the way to do this. Currently the best documentation on how to write one of those, is this blog post. There is a window-object-cleared signal similar to WebKit1 that you can connect to in your web extension and there use the JavaScriptCore API to define Javascript functions that are visible to your web page.

Related

Calling JS function multiple times from node addon

Edit: apparently it's not clear, guess I'll make it more concise.
Node application is built, uses a native addon. I need to pass in a Javascript function from this project through node-addon-api into my C++ addon. Then, I need to be able to call that function from C++ multiple times. The issue arose when I found out I am unable to save the reference to the Javascript function due to the napi_env (required for calling the function) being protected from caching.
Could not find any clear answers or examples on the internet regarding how to do this, looking for tips.
Original:
as the title describes, I need to figure out a way to call a JS function multiple times in my addon. Generic use case is that my addon does some long running commands and needs to periodically push a status update back to the javascript.
I thought the best approach would be to have the user pass in a function (which just appends to a text block) for my addon to call (so it can write the updates), this way the javascript side can decide where it gets displayed.
I have experimented to get this working. Found out that my original way of saving the function in a persistent napi_value doesn't work since you cannot save napi_env as well.
I found this thread, which I think is the closest to what I need, but I can't manage to translate the Nan to napi_ so it would work with what I'm using. Callback NodeJS Javascript function from multithreaded C++ addon
Also attempted passing in an EventEmitter, but similar problem as above.
Can anyone give some pointers on if I am heading in the right direction? Perhaps help me dig up a few examples on how to accomplish this?
Your question is not clear. Assuming you are using Javascript in Node, have a look at FFI which allows one to loading and calling dynamic libraries using Javascript.
Alternatively one can just execute a function as follows from the command line:
/usr/bin/node yourjsfunctionfilehere.js
You can also pass command line parameters to the called JS function.

Is JavaScript compatible with strict Page Object Pattern?

I have built various Test Automation frameworks using the Page Object Pattern with Java (https://code.google.com/p/selenium/wiki/PageObjects).
Two of the big benefits I have found are:
1) You can see what methods are available when you have an instance of a page (e.g. typing homepage. will show me all the actions/methods you can call from the homepage)
2) Because navigation methods (e.g. goToHomepage()) return an instance of the subsequent page (e.g. homepage), you can navigate through your tests simply by writing the code and seeing where it takes you.
e.g.
WelcomePage welcomePage = loginPage.loginWithValidUser(validUser);
PaymentsPage paymentsPage = welcomePage.goToPaymentsPage();
These benefits work perfectly with Java since the type of object (or page in this case) is known by the IDE.
However, with JavaScript (dynamically typed language), the object type is not fixed at any point and is often ambiguous to the IDE. Therefore, I cannot see how you can realise these benefits on an automation suite built using JavaScript (e.g. by using Cucumber).
Can anyone show me how you would use JavaScript with the Page Object Pattern to gain these benefits?
From Gerrit0's comment above and investigating it further, it seems a great way to achieve this is to use TypeScript (which is a statically typed version of JavaScript):
https://en.wikipedia.org/wiki/TypeScript
I am not much about this patterns.but i will give some details maybe it helps to you.
http://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html
http://www.assertselenium.com/automation-design-practices/page-object-pattern/
It seems a great way to achieve this is to use TypeScript (which is a statically typed version of JavaScript):
https://en.wikipedia.org/wiki/TypeScript
If you use Jetbrains products like IntelliJ IDEA it will do a code completion and ther proper navigation for you. In javascript world page object is a known pattern too. AngularJs offers it too in it's own e2e test framework (http://www.protractortest.org/#/page-objects). Personally I use IIFE for page objects and IntelliJ does the rest. If it doesn't fit to your needs you can still choose typescript and transpile it to javascript.

Is there a way to call Python functions from JS, when using WebKitGtk+ in a Python app?

I'm coming from the Windows Forms world, where they have this ObjectForScripting property that makes it trivial to expose C# objects to the JavaScript running inside your WebViews. I'm hoping to do something similar in Python, and WebKitGtk+ seems like a natural choice for the WebView. But there doesn't seem to be an easy way to bind a Python object into JS. Is there an easy way that I'm missing, or maybe an alternative to WebKitGtk+ that would work better for doing this? Thanks for any suggestions.
Here is a workaround: intercept URLs with a custom scheme.
Handle the resource-request-starting signal and check if the URL starts with python:
If it does, parse the URL somehow (eval? dictionary of allowed functions? Up to you) and call the appropriate function.
Replace the URL requested with data:text/plain,<result of function call>.
In JavaScript, make an Ajax request to python:my_function().
This is very limited but works, in my case, with Haskell bindings.
I ended up going with PyQt for this instead, since it has strong support for exposing native objects to JS. Here are some great starting examples:
http://pysnippet.blogspot.com/2010/01/calling-python-from-javascript-in-pyqts.html
http://pysnippet.blogspot.com/2010/01/more-fun-with-qwebkit.html

Can I control Unity3D with external JavaScript?

Is it possible to control the scene in the Unity3D Plugin by using JavaScript? The JavaScript-Code should run in the context of the browser and not in the context of the Unity3D Plugin?
I have to transform, delete and add objects in the scene.
Perhaps do you have an example.
Thanks for any advice.
Yes, it's possible - at least, I know I've done it, but it was quite some time ago.
Here's the demo page I put together back then.
Feel free to look in the page's source code. Most of it comes from Unity's docs and examples. I just made a simple wrapper for the sending and receiving of messages to/from the Unity web player, and adapted the code a little.
My code is based on Prototype.js, so you'll have to do some minor rewrites if you're using jQuery (like most people these days), but it shouldn't be too bad. Or you can just use Unity's pre-made stuff.
I'm not usually a Unity coder so I can't tell you exactly how to set up the Unity-side of things (I did make the simple shader-based demo you see, but I've lost the source files, I think), but as I recall, it was simply a matter of creating a game object with a set of public methods. Those methods can then be called via JavaScript. Simple as that.
Basically, from the JS-side, all you have to do is this:
var player = document.getElementById("UnityObject");
player.sendMessage("name of game object", "name of method", "argument");
You can also send messages from the a GameObject back to JavaScript, if you want. It doesn't happen in the demo, but it should work. Check the source for details.

How Can I Modify/"Spoof" Standard Browser JS DOM Objects (Window.location) at Runtime?

I'd like to dynamically change some of the standard JS DOM objects from within a web browser.
For instance, when I execute:
var site = location;
I want to specify a new value for my browser's "window.location" object other than the "correct" one (the URL used to access the requested page) at run time, either through a debugger-like interface or even programmatically if need be.
Although Firebug advertises the capability to do something similar via its "DOM Inspector," whenever I try to modify any of the DOM values while I've paused the Javascript via its debugger, it simply ignores the new value I enter. After doing some research, it seems that this is a known issue according to this bug report: http://code.google.com/p/fbug/issues/detail?id=1707 .
Theoretically, I could write a program to simply open up an HTTP socket and emulate a browser "user agent," but this seems like a lot of trouble for my purposes. While I'm asking, does anyone know a good Java/C# library with functions/objects that emulate HTTP headers and parse the received HTML/JS? I've long dreamt about the existence of such a library but most of the ones I've tried (Java's Apache HttpClient, C#'s System.Net.HttpWebRequest) are far too low-level to make anything worthwhile with minimal planning and a short period of time.
Thanks in advance for recommendations and advice you can provide!
Not sure if I understand you correctly, but if you want to change the loaded URL you can do that by setting window.location.href.
If your intent is to replace DOM buildins then you will be sad to hear, that most build-in objects (host objects) aren't regular JavaScript objects and their behaviour is not clearly defined. Some browsers may allow you to replace and/or extend some objects while in other browsers they won't be replaceable/extendable at all.
If you want to "script a browser" using JavaScript, you should definitly have a look at node.js and it's http module. There's also a thirdparty module called html5 that simulates the DOM in node.js and even allows the usage of jQuery.

Categories