How to get JS results in webkit2gtk-4.0 in Vala? - javascript

I am using webkit2gtk-4.0 in my Vala appication to display Google Maps. And I need to get marker coordinates on button click. How can I manage it?
I figured out how to run javascript using run_javascript(), but I can't understand hot to get the results of it.

Ordinarily you would need to use Vala's async functions to do this, I believe like so:
var result = yield webview.run_javascript(...);
This is equivalent to the C function webkit_web_view_run_javascript_finish().
Unfortunately you can't take the next step shown at that link in Vala, as you need to use the JavaScriptCore API to get at the return value and that API isn't available in Vala.
There are a couple of dirty tricks that you can resort to in this case. One such trick is setting the window title at the end of your Javascript script, and watching for notifications on the webview's title property in Vala.
However, you may be better off writing a small bit of code in C that you compile into your Vala application.

Related

How can I debug which script is trying to use the Geolocation API?

On my site, I have a bunch of trackers loaded via Google Tag Manager, including Google Analytics and Chartbeat, along with a bunch of DoubleClick For Publishers (DFP) ads.
On mobile only, when someone visits my site they get the "example.com would like to use your location" notification, but I can't determine what is trying to access that information.
How can I debug which script is trying to use the Geolocation API, using Firefox or Chrome?
The Geolocation API has a function called getCurrentPosition, which is what is getting called.
If you don't know where that call is happening because you have a large code base, or it's happening in a client library, it can be pretty difficult to find.
One option would be to search the solution in the Sources panel. You can do this using the shortcut Cmd + Opt + F (Mac) or Ctrl + Shift + F (Windows), and search for "geolocation" or part of the API call. You should see a list of results in the panel.
Another useful solution is a method I like to call Debugging JavaScript by Redefining Functions. The idea is to store a copy of the original function, override it and inject your debugging logic, and then call the original function from the current context.
Using this, we can inject a debugger statement into the getCurrentPosition function, so that whenever it gets called, the debugger will break and you will have a call stack in DevTools.
var oldGetCurrentPosition = navigator.geolocation.getCurrentPosition;
navigator.geolocation.getCurrentPosition = function() {
debugger;
return oldGetCurrentPosition.apply(this, arguments);
}
I would run this in the Console, using a Snippet preferably, so as to avoid this debugging code appearing in production. The good thing is the logic doesn't break the original code if it did.

Chrome console - breakpoint over whole file

is there any option to set something like "breakpoint" on a file in chrome console (kindof shortcut to set breakpoint on every line of code in the file)?
Would be extremely useful when trying to understand 3rd party scripts that you know are executed but have no idea which part of code and from where is executed when.
My current example use case: I downloaded a script (form validation) which does not work as expected. The fastest way to solve the problem would be to pause execution anytime JS runtime enters this file and start exploring it from there.
I think this will be of use to you. I've recently been doing some work on the JavaScript Breakpoint Collection Chrome Extension created by Matt Zeunert, which allows you to inject breakpoints into your code at runtime - including breaking on property access/modifications, functions, scrolling events, etc. You can break on any arbitrary objects as well as the predefined ones using the console API.
Check out the project here.
If you can enumerate the functions publicly exposed by your third party script (for example if they are all properties of an object, or is their name has a pattern) you can make another script which dynamically replaces all those functions and force a break point :
thirdpartfunc = (function () {
var oldfunc = thirdpartfunc;
return function () {
debugger;
oldfunc.call(null, arguments);
}());
With the appropriate binding to this (if any applicable).
If you know the function(s) being called, you can use function breakpoints
debug(function);
function(...args);
When you call the function, it will hit the breakpoint. These aren't saved on page reload, but you can set a line breakpoint once you hit the function breakpoint.
This can get kinda tedious though.
If you have a array of functions, you can do
[function0, function1].map(debug)
#Tibos answer in another post would be good if there was some sort of babel transform to insert debugger; at the start of every function, instead of inserting it manually.
The quickest way for me was to do a global replace of the function declarations in the source, adding "debugger;" at the start.
In other words, replace
function [^{]*{
with
$0 debugger;
Your regexp may vary depending on the escapes you need. For example:
function [^{]*\{
You may also need more than one pattern to handle all the function declarations you have.
This has nothing to do with the Chrome console though.
No. You would have to add breakpoints to the various function entry points that file contains to catch everywhere it could enter.
Can't you just place a breakpoint at the first line of every function in the file of interest?

What is the recommended way to persist the data in background task? [UWP/W/WP apps]

The question is quite simple, but I seriously couldn't find any sample that would demonstrate something I'm trying to achieve, maybe it's me who is didn't get the concept of background tasks in uwp applications (or windows / windows phone 8).
I'm creating an application that is polling some data (traffic incidents) and would like to be able to notify the user about the closes ones even if he is not using the application. So I reckon I would use the background task. (I hope I get that part right).
So in the background task, which I've set to run on timer of 15 minutes, under the condition of "InternetAvailable", I fetch the data asynchronously and once it's done, I'm completing the deferral object as it's required. All works ok.
The question is, what object shall I use in order to persist the data so I could read the data once the application is opened?
I've tried the WinJS.Application.sessionState but that gets lost once the application is ready (opened).
I've tried the Windows.Storage.ApplicationData.current.localSettings but it says there is a type mismatch, apparently I'm trying to put in there the object, if String is expected (I reckon)...
So does anyone know what is the best practice here ?
Thank you
You have full acess to the WinRT API, so you can write a file (and read the same file once the application is opened):
function saveData(dataObj) {
var applicationData = Windows.Storage.ApplicationData.current;
var localFolder = applicationData.localFolder;
return localFolder.createFileAsync("dataFile.txt", Windows.Storage.CreationCollisionOption.replaceExisting).then(function (sampleFile) {
return Windows.Storage.FileIO.writeTextAsync(sampleFile, JSON.stringify(dataObj));
});
}

Uncaught SyntaxError: Unexpected token )

*NOTE - This code is from a third party extension. I had no part of it's creation and several years ago when used it was the only extension available at the time. So while I appreciate your opinions, I do hope all comments can be just for suggestions on a resolution. Thanks!
We have many sites running a Google Maps component for a CMS that allows for clients to add markers and outlines (polygons) to their Google Maps.
This has been working for years. To note, it uses Google Maps JS API 2, which has been discontinued rather than API 3. However, Google has noted API 2 will still work well into 2013 so that is not the issue. However, they must have changed something because as of the other day, on all our sites though the Maps appear the markers and polygons do not. They are on different servers.
Before there was no errors but now in Chrome it says:
"Uncaught SyntaxError: Unexpected token )" for line 1669 in a JS File. You can see the file in the following Gist:
https://gist.github.com/2238148
As you can see there is no missing ")" and the code has work unmodified for years on nearly 100 sites, so assume something on Google's end must have changed. But is there something we can adjust to this code to help counter there change? -Update on March 25th when all of this broke Google made an update to their Google Maps API 2.
Searched the web and here is an example site using the same component with the same error: http://goo.gl/GMgOs
This issue appears to be near:
// extract current digraph from overlay function
var digraph = GMap.addOverlay.toString().replace(/\s/g,'').replace(/.push\([^{]+\);a.initialize\([^{]+\);a.redraw\([^{]+\).+$/,'').replace(/^.+\./,'');
// add multiple overlays at once (api hack to improve loading speed)
GMap2.prototype.addOverlays = function(a) {
var b = eval('this.' + digraph);
var i = a.length;
while (i--) {
b.push(a[i]);
a[i].initialize(this);
a[i].redraw(true);
}
}
If that code needs to be alterted could someone post the modified version on a gist or pastie?
Another Update - That code in the pre above I commented out since it supposively is not needed by was a hack to speed things up. Still gets an error however noted in the comments. I did notice however here: https://developers.google.com/maps/documentation/javascript/v2/reference#GMap2.Methods.Overlays that it calls the code, "addOverlay" rather than "addOverlays" so wondering if maybe the s was taken off in the most recent API Google update. Removing the s in all three locations just shoots out a new error which repeats [object] many times.
The code is an abomination, in fact I've not seen a worse add-on in five years of working with and helping users of Version 2. It overwrites GMap (part of the Version 2 API to provide compatibility with Version 1) with no redeclaration. The error you're getting is a direct result of a hack to minified code: this was bound to fail at some point and should never have been implemented.
The best thing you can do is to remove the var digraph line and then redefine the new method GMap2.prototype.addOverlays which follows it. That will allow the code to use the API's addOverlay() function and should eliminate the problem.
GMap2.prototype.addOverlays = function(a) {
var i = a.length;
while (i--) {
this.addOverlay(a[i]);
}
It appears that addOverlays() takes an array of overlays. The existing method attempts to add them directly to the internal array of overlays, which has moved. The suggested method simply uses GMap2's own addOverlay() method to add each member of the array of objects. Thus we use an exposed method and don't try and hijack the minified code of the API — if we did that again, it would almost certainly break again.
GMarker.prototype.openInfoWindowFX and GMarker.prototype.updateInfoWindow are additions to GMarker and unlikely to cause problems (especially if they currently work), although even they use properties of GMarker -- which isn't really recommnded.
Clearly, the GMap.addOverlay function definition has been changed and your RegExp hacking at its source code no longer works.
alert(GMap.addOverlay.toString())
and
alert(digraph)
To see what the new function is and what your regexes are doing to it.
Why exactly do you need to in-place modify their code, anyways? Why didn't you just copy the function definition you wanted, make the changes, and then use that version? (Without needing an eval, either.)
The code you posted relies on internal implementation details for GMap2.prototype.addOverlay which are free to change at any time.
It would be better to rely only on the external interface for GMap2. You can implement an addOverlays method as such:
GMap2.prototype.addOverlays = function(overlays) {
for (var i = 0, I = overlays.length; i < I; ++i) {
this.addOverlay(overlays[i]);
}
};
Can you replace the code snippet from your post with this and see if it works?
That code is ugly. You do GMap.addOverlay.toString(), replace something with regular expressions and execute it then with eval.
Why do you need to replace something in a function's code? What is the code of GMap.addOverlay? If you can answer these questions, you should be able to see why your regexp doesn't work any more and returns invalid code.

initialization of dojo widget

I tried to create custom widget for my site. when I loaded page it says:
mixin #0 is not a callable constructor.
clsInfo.cls.prototype is undefined
I can't find any information about clsInfo, so I don't know what is it. maybe the problem that I use dojo from google:
and my own script is located on localhost. so when my dojo on page initializes something goes wrong with my script. I can't find any good info on dojo, maybe I search in wrong places?
please help me to resolve my problem
I ran into this when I was trying to override a dijit.Dialog so I could bind events to controls within it. We've yet to see if the binding part will work, but if you look at the source, this happens when one of the bases passed in as the second argument fails to resolve to an "[Object function]". In my case, I was passing a String in.
dojo.declare takes 3 arguments:
The name of the custom object "class" you're building
An array of base classes, parents to provide functionality (not the string names of those classes)
A hash of functions and declarations
So if I want to override dijit.Dialog, I have to do:
dojo.declare("myDialogType", [dijit.Dialog], {
function1() {/*Code*/},
function2() {/*Code*/}
}
I had ["dijit.Dialog"] as my second argument and that was the problem.
I strongly recommend using Web Inspector or Firebug with uncompressed local copies of the Dojo library rather than the CDN to figure out what's going on and debug these types of problems. Dojo's documentation is extensive but not complete in some areas and some behaviors have to be figured out by looking at what the code expects. That's not intended as a slight to the authors; once you get it going it's a pretty awesome product, and any documentation for volunteer work is appreciated.
Are you sure Dojo is loading? Did you put your code in a dojo.addOnLoad()? When using a CDN you sometimes run into issues with execution times. dojo.addOnLoad() will not only trigger when the DOM is loaded, it gets called when dojo resources have downloaded, such as dijit._Widget.
I've run into this problem when I screw up the order of my requires which makes _WidgetBase not what _WidgetBase really is. Seems like a simple spot to screw up.

Categories