How to find out where specific variables come from? - javascript

I'm trying to learn WebGL and JavaScript at the moment as I want to use my graphical programming skills to create 3D web applications. I'm used to OpenGL programming in C++.
Now, doing some tutorials I come across of variables which are neither declared anywhere nor included from some other scripts as far as I can see. Here are two examples:
The khronos wiki tutorial is constantly using a variable g, for example:
g.program = simpleSetup( /* ... */ );
g was never declared in this scope. How to find out what it stands for? Google does not yield much searching for 'g' or 'javascript g' of course.
Another example is the voxolent beginners guide which is using mat4, starting with something like:
mat4.identity(mvMatrix);
Due to knowing OpenGL I understand this line of code: getting identity matrix from modelview, but where does the mat4 come from? Using this line of code in my own project breaks my script. Google yields for 'mat4' this documentation but it also says simply use:
mat4.create();
... which is obviously not working without further steps.
What is it I'm missing here? Do I always have to guess/digg around when I see unknown variables in examples/tutorials/documentations? How to include mat4 in my script? What is g?
Please, explain this for me.

Regarding your question about the variable "g", it's just a globally accessible variable that contains a lot of other useful variables.
At the global scope, you declare var g = {}; and then later, you can add members to g by doing g.myGlProgram = simpleSetup(...) or g.myVertexBuffer = ctx.createBuffer(...)
It's just a nice JavaScript trick

I found mat4 comes from js/math/gl-matrix-min.js
Here's how I did it using Google Chrome:
Load page http://voxelent.com/html/beginners-guide/1727_04/ch4_ModelView_Rotation.html
Press F12
Switch to Console tab and type mat4, the result looks like it's not a built in object for I could see the compact source code
Switch to Sources tab and switch to Source tab, see the tree
Just expanded js folder and saw math folder and expand
Saw a lot of mat4.set mat4.transpose ...
Oh, and the first line suggest the source code comes from https://github.com/toji/gl-matrix/

Related

Dependency tracking modules from a concatenated library

What I've got
A large (proprietary unfortunately) JS library, the many small modules that get rolled up into it during the build process, the accompanying source map, and over 300 examples that use the built version of the library.
The goal
A form of dependency tracking, I guess? I need to be able to modify one of the small modules, rebuild the large file, and then only re-verify the examples that were affected by this change. Note: I don't care whether this requires static analysis or if I have to run all examples thru a headless browser to extract something or so - I'm fine as long as it can be automated.
What I've tried so far
I've read answers to questions like this and tried pre-existing tools like
Madge, but none of them seem to work for my case. Madge in particular is great for telling me which of the modules depend on which modules, but that's not what I'm looking for. Most solutions online are based on the assumption that you're already using something like require.js or similar on which they can piggy-back, but in my case the library is simply just a giant blob.
My current approach is instrumenting the built version of the library by simply appending every line with something like neededModules["the_file_this_line_comes_from.module.js"] = true similar to how code coverage tools do it. However, that fails because of several parts like this:
Points.prototype = Object.assign( Object.create( Info.prototype ), {
plot: ( function () {
var static = new Background();
return function plot( line, physics ) {
<code>
};
}() ),
copy: function () {
return new this.constructor( this.info, this.history ).copy( this );
}
} );
The copy function is tracked/skipped just fine, but because the plot function is an IIFE(right?), the line var static = new Background(); always gets executed, even if there is absolutely no connection to the Points module.
What I'm looking for
Either some help with my current approach and its problems with IIFE or a different solution altogether. I've seen Facebook's Jest does offer dependency tracking, maybe someone has experience with that one, or there's some way to incorporate the source map?
Again, as long as it's automatable and finishes in let's say < 5 min, I'm totally fine with it no matter if it's static analysis or just some hacky script or whatever :)
Thanks!

Unminify / Decompress JavaScript

Original Question
This maybe a stupid question but is there a way in VS 2013 to unminify JavaScript?
Just making sure we are all on the same page here.
Minify:
var flashVer=-1;if(navigator.plugins!=null&&navigator.plugins.length>0){if(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]){var swVer2=navigator.plugins["Shockwave Flash 2.0"]?"
That's just an example to make sure we all know what I'm on about. As far as I can tell there is no way to be able to do this. I have only been using VS 2013 for around 3 weeks so there is probably still stuff that is hidden to me.
If there is no way to do this within the program what is the next best thing for this?
I did see on another similar post that recommends the site http://jsbeautifier.org/ , so may have to give that ago but would make life easier if it was built into VS 2013
Thanks in advance as I know someone will be able to help me out here.
Update:
I have looked around VS 2013 and found nothing that can help me with this problem, like I said before they maybe some things I have missed (certain settings) so I guess if it cannot be done in VS what's the next best thing for the job? I seem to run into a fair amount of JS that is minifed and would like the quickest and best way to get the job done. I couple sites I have tried seem to have problems with it, is there a program I could install that would just allow me to short cut it with a hot-key or something. That would be pretty handy.
Update 2:
So I think its safe to say this cannot be done within VS2013, or for that matter at all due to missing var names and so on. So I have seen a few links and programs that allow you to format the code. Is there a way to do with within VS2013? And again if not what is the most reliable website/program that I can use to do this. Like I said I can see there have been answers and I appreciate all of them. I will be leaving this question open for a while to get more people to look at it and possibly give a better answer. Keep it up guys!
Update 3:
If anyone has any more information on this please do share. I am still looking around now and then waiting for someone to come up with something amazing for this. One day people.... One day!
The thing is that you cannot really "unminify" your code since some data was already lost - e.g. variable names. You can reformat it to more readable form though.
According to this question, since VisualStudio 2012 you can just use Ctrl+E, D keyboard shortcut
If the above is not right, there is this extension for VS 2010: http://visualstudiogallery.msdn.microsoft.com/41a0cc2f-eefd-4342-9fa9-3626855ca22a but I am not sure if it works with VS 2013
There is an extension to VisualStudio called ReSharper which can reformat javascript in a few different manners.
Also there are online formatters already mentioned in other answers (if your code is confidential, I would advise some paranoia manifested by downloading sources and using them locally).
Also you may always try to find unminified version of desired library on the interwebs
Also, there is the WebStorm IDE from JetBrains that is able to reformat JS - you may download a trial for the sole purpose of reformatting your minified scripts :)
If that's just to make debugging easier, you may want to use source maps
Also, here is a bunch of related questions:
How to automatically indent source code? <-- this is for VS2010, but it looks promising, maybe it will help you if it supports JavaScript (and it does since VS2012 according to MS support):
Ctrl+E, D - Format whole doc
Ctrl+K, Ctrl+F - Format selection
reindent(reformat) minimized jquery/javascript file in visual studio
Visual Studio 2010 can't format complex JavaScript documents
Visual Studio code formatter
how to make visual studio javascript formatting work?
I am not sure if they figured out a working way to reformat JS, but I've seen a few answers which might be helpful - I am just pasting this in here just FYI.
Added 03.06.2014:
http://www.jsnice.org/
This tool could be useful too, it even tries to infer minified names. As stated on their website:
We will rename variables and parameters to names that we learn from thousands of open source projects.
Personally I can't think of a reason to ever unminify code^:
If you're using a compiled js file (a-la google closure) and want more readable code to debug, use source maps available for well-supported libraries (speaking of jQuery, if it is served from a google CDN it already maps to the correct source)
If you're using a whitespace-only minified js file and want more readable code to debug, you could just toggle pretty print in-browser. This seems to best fit your question.
If you're using either of the above and want to modify the source code for a third-party js file, don't. Any future release will cancel out your change - instead consider one of the many patterns to extend a framework (or, perhaps, do some duck punching depending on the exact scenario.)
The other answers seem to cover the "unminification" process (maxification?) well, but it's worth making sure it's a necessary step first.
^ - Except when version control falls over, there are no backups and the only version of the file left is a minified copy in browser cache. Don't ask.
Its just a one way transformation .... sorry in normal cases you will not get something understandable back from minified JavaScript !
Make just a quick look at JQuery source for a second:
(function( window, undefined ) {
// Can't do this because several apps including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
//"use strict";
var
// The deferred used on DOM ready
readyList,
// A central reference to the root jQuery(document)
rootjQuery,
// Support: IE<10
// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
core_strundefined = typeof undefined,
// Use the correct document accordingly with window argument (sandbox)
location = window.location,
document = window.document,
docElem = document.documentElement,
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
// [[Class]] -> type pairs
class2type = {},
// List of deleted data cache ids, so we can reuse them
core_deletedIds = [],
core_version = "1.10.2",
------
And now at the minify source:
(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,
l=e.jQuery,u=e.$,c={},p=[],f="1.10.2", ....
I think now you see it =>
window => e
undefined => t
readyList => n
rootjQuery => r
core_strundefined => i
location => o
document => a
So its mapped somehow to make it more shorter look here to minify something
People normally use this so there is no way back
you can just format it look here
If the code has only been minified then the best you can do automatically is reformat to make it more readable. One way of doing this is using an online formatter/beautifier. E.g. Copy and paste the line of code you posted into http://jsbeautifier.org/ or http://www.jspretty.com/ and it'll produce something like this:
var flashVer = -1;
if (navigator.plugins != null && navigator.plugins.length > 0) {
if (navigator.plugins["Shockwave Flash 2.0"]
|| navigator.plugins["Shockwave Flash"]) {
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? ""
But of course what these don't do is put any comments that have been removed by the minifier back in. And if the code has also been obfuscated then it will be a lot less readable since the variable names will have changed (e.g. var a instead of var flashVer). See here for further details.
As you can see from the other answers, there is no way to reconstitute minified Javascript back into its original form, it is a lossy compression. The best you can do is make it readable by reformatting it.
If the code is open source, then it is likely that the code will exists in a raw state on some form of version control site or as a zip. Why not just download the raw version if available?
There is an online tool to unminify Javascripts
http://jsbeautifier.org/
And also for CSS
http://mrcoles.com/blog/css-unminify/

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.

How would I solve a coding puzzle with Javascript?

There is a website called Gild.com that has different coding puzzles/challenges for users to do. They can be completed in wide array of languages including Javascript. I am interested in solving these puzzles in Javascript, but I am unsure of the following:
How am I supposed to access the input file which is supposed to be passed as an argument?
How am I supposed to output the result?
My understanding of Javascript is that it is run from within an HTML page and that output really is only in the form of placing values in the HTML, modifying the DOM, etc. For that reason it is not clear to me how Javascript can be used for solving these types of problems. Can someone who has used Gild before or has some insights into my question suggest how to proceed?
An example of a problem would be: the given input file contains a positive integer, find the sum of all prime numbers smaller than that integer and output it.
EDIT: Some of the solutions below involve using external resources, but on Gild, I am supposed to put my solution in their editor and then submit it that way, like the following picture shows:
In other words, I don't think my solution can have access to Node.js or other external resources.
Edit: Here are some interesting articles that I have found that I think are the answer to my question:
http://www.phpied.com/installing-rhino-on-mac/
http://www.phpied.com/javascript-shell-scripting/
I haven't spent much time on Gild, but I do a lot of similar types of problems on Project Euler. I think the best way to go is probably Node.js.
If you're not familiar, Node is basically server-side JavaScript that runs in Google's V8 engine. Installing it on your own Mac/Windows machine takes about 2 minutes. It's also really fast (considering it's JavaScript).
And you'd use it like this:
var fs = require('fs'); // the filesystem module
var contents = fs.readFileSync('theFile.txt', 'utf-8');
// Do stuff with the file contents...
Everything after those first two lines can be done with the same JS you'd write in the browser, right down to calling console.log() to spit out the answer.
So, if you wrote your script in a file on your desktop called getprimes.js, you'd open up your terminal and enter node ~/Desktop/getprimes.js (assuming you're on a Mac)
If you're:
on a Mac,
planning to do a lot of these puzzles, and
willing to pay $10, then
I highly recommend CodeRunner. It encapsulates runtimes for a variety of languages — from C to JavaScript — and lets you quickly build and run any sort of one-off code. Just hack together your code, ⌘R, and the results are printed right there in the same window.
I haven't used any file-based JavaScript in CodeRunner, but I imagine kennis's suggestions would apply. To output your results:
console.log(...)
Easy as pie!

Changing the main environment in Node

Some of you may or may not (probably not) know about my framework. It's name is Ally, and I absolutely love using it.
Lately I've been doing a little bit of stuff in Node.js. Today I decided I was going to use it as my HTTP server, so that I could do server-side JS (in a PHP kind of way).
To do this, I started a project I'm calling Trailer . While working on it, I found myself needing one of Ally's functions, Object:deploy. What it does is pretty much this:
var a = { a: 'a' };
a.deploy({ b: 'b' });
a.a; // 'a'
a.b; // 'b'
So I loaded it in..
var Ally = require('./Ally.js');
..but when I tried using it, it said it was undefined.
After a bit of digging I discovered that Object:deploy is defined in the Ally.js file, but the changes it makes to the global constructors don't stay.
How do I make the changes to global variables in the Ally.js file apply to the global variables in the file that required it?
Note: Ally is linked to above if looking through the source could help, and Trailer is linked to in case anyone wants to use it when I get a usable version out.
Is this discussion relevant? The key points here seem to be:
require won't extend global objects if you're working in the shell
It also won't work when NODE_MODULE_CONTEXTS = 1, though this doesn't seem to be the default for a script.
So if you're trying to run this in an interactive shell, that might be the issue. See also this SO question.

Categories