Show Javascript function filename programmatically - javascript

I need to know if there is a way to extract the script name when calling a variable or a function in javascript. The scenario is running chrome through webdriver or node and when calling for example window.jQuery.Animation I would like to get the filename (i.e., jquery.js) where this function is defined. I know in chrome you can click on 'show function code' and jump to the file, however I am looking to do the same in a programmatic way.
Thanks

Maybe an Error object can help here:
var e = new Error;
console.log(e.stack);
The first two lines of the stack:
Error
at Object.<anonymous> (/home/joost/src/test/testfile.js:3:9)

You have no such way of doing that in pure JavaScript.
The different javascript engines (spiderMonkey, V8, ...) will often compile the javascript code in some way, so you will lose such information in the process.
To know where a function comes from, you will require this function's source map. If you don't know them, source maps will map a script to it's originating filename / line number.
The mozilla sourceMap library will help you with that.
Though, you will have to generate a source map for your file that uses jQuery as well.
if your script.js is like
var a = jQuery.method // this is line 10
^ col 9
You will have to execute
var sourceMap = require('source-map');
consumer = new SourceMapConsumer('script.map');
consumer.originalPositionFor({ line: 10, column: 9 })
// { source: 'jQuery.js',
// line: 12971,
// column: 222,
// name: 'whatever' }
You'll be then able to query the original position and filename where that object is declared.

Related

Clojurescript Extern for Nested Function

I am developing a Single Page Application in Clojurescript, and I want to use TinyMCE as a WYSIWYG editor for certain fields. For space efficiency, I want to eventually minify the project using the google clojure compiler in advanced mode. Since the tinymce dev javascript files seems to be unsuitable for use as an extern file, I'm forced to write my own.
There is one particular function call that I can't get to work. In clojurescript, I call:
(.setContent (.get js/tinymce id) cont)
which I'd imagine would compile to something like:
tinymce.get(id).setContent(cont);
I have tried many different function definitions in my externs, yet I keep getting an error:
TypeError: tinymce.get(...).Tl is not a function
Which tells me setContent gets obscured away by the compiler. My current extern file looks like this:
//all seems to be well here...
var tinymce;
tinymce.get = function(name){};
tinymce.remove = function(node){};
tinymce.init = function(editor){};
tinymce.on = function(name, callback, prepend, extra){};
//tinymce setContent attempts
var tinymce.Editor;
tinymce.Editor.prototype.setContent = function(content){};
tinymce.Editor.setContent = function(content){};
tinymce.get(name).setContent = function(content){};
tinymce.get(name).prototype.setContent = function(content){};
var Editor;
Editor.prototype.setContent = function(content){};
Editor.setContent = function(content){};
Which currently is kind of a throw-everything-against-the-wall-and-see-what-sticks attempt. The object get(name) returns should be in the namespace tinymce.Editor.
Is there a proper way of writing an externs to catch these chained function calls? Or is there a way to rewrite the first code snippet so my externs properly preserve the function names? Thanks in advanced.
This line:
var tinymce.Editor;
is not syntactically correct in JS:
SyntaxError: missing ; before statement
Remove it and leave this line:
tinymce.Editor.prototype.setContent = function(content){};
This should work fine.
Also you may always fall back to accessing properties via string literals which will never be renamed:
(require '[goog.object :as gobj])
(gobj/get your-object "i-wont-be-renamed")

ArcGIS API - Execute QueryTask unsupported

So, I am using the ArcGIS API (javascript) in order to get some information from objects in a featurelayer. The first step here should be detecting which object the user clicked. I am using queries for this. For some reason though, I cannot seem to execute my queries. Every time the execute method is called, the console replies that "Object doesn't support property or method 'execute'". The relevant part of the code is as follows:
thema_4_Verblijf = new FeatureLayer("https://services.arcgisonline.nl/arcgis/rest/services/Basisregistraties/BAG/MapServer/4");
map_Thema_4.addLayer(thema_4_Verblijf);
thema_4_Verblijf.on("click", thema_4_Verblijf_Click);
function thema_4_Verblijf_Click(evt){
var query = new Query();
query.returnGeometry = true;
query.outFields = ["*"];
query.geometry = evt.mapPoint;
var queryTask = new QueryTask("https://services.arcgisonline.nl/arcgis/rest/services/Basisregistraties/BAG/MapServer/4");
queryTask.execute(query,showResults);
};
function showResults(featureSet){
//will show results
}
At first, I thought this had to do with me not defining the requirements correctly at the start of the script. This cannot be possible though as execute is a method of QueryTask, and 'new QueryTask' itself completes without any errors. Nonetheless, my requirements as defined are:
require([...
"esri/geometry",
"esri/tasks/query",
"esri/tasks/QueryTask",
"esri/tasks/FeatureSet"
],
function startMap(
...
Query,
QueryTask,
...
Any thoughts on what could be wrong here...?
Alright, so this has been answered..
I tried defining querytask with the legacy module and for some reason that worked.
var queryTask = new esri.tasks.QueryTask(...);
I have experienced this before during my current project, somewhere legacy and AMD modules must be mixed up, even though all my requires have been defined using the AMD way.
So yes, this particular question has been fixed (as in: I can continue) but if someone could explain how the two modules can get mixed up, that would be appreciated.

An object disappears after packing a JavaScript library

I have created a JavaScript library and packed it with these options selected : Shrink Variables and Base62 Encoded at this url: http://dean.edwards.name/packer/. In this library I have declared an object ax, but when I use the packed version in my web page I get an error saying Uncaught ReferenceError: ax is not defined.
The original code of this library looks like below.
var ax = {
scaleUp:function(win) {
//code omitted
},
downGrade:function(win) {
//code omitted
}
}
In my web page in which I am using this library, I have code like below. This code works, if instead of packing, I minify it using Microsoft's Minifier or just use the original JavaScript library without minification or packing.
var result = ax.downGrade(w);
Question :
Why is the variable ax not accessible with packed version? Do I need to add something else when using the packed version?
UPDATE 1:
I could not get the packed file to work but packing my code through another compression utility at following url worked in my case: http://jsutility.pjoneil.net/. It provided an equally good compression.
I am still not sure why the utility at original url failed to produce a working version of my library, even though my original code works without any errors on any web page.
Check your console for errors before trying to call ax. Explicitly place semi-colons where they belong.Example at the end of the definition for ax you should put a semi-colon, even though in standard code it's good as is. Remove the explicit var declarations. When I did these things:
ax = {
scaleUp:function(win) {
alert("up");
},
downGrade:function(win) {
alert("down");
}
};
result = ax.downGrade();
Ran without issue in jsFiddle and console: http://jsfiddle.net/7kdnw65n/. I suspect it has to do with how the algorithm "shrinks" the variables. The resulting pack was:
eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('0={5:1(2){3("6")},4:1(2){3("7")}};8=0.4();',9,9,'ax|function|a|alert|downGrade|scaleUp|up|down|result'.split('|'),0,{}))

Moving created files with JXA

I'm new to JXA scripting, but I'm attempting to troubleshoot some older scripts currently in place here at work. They loop through an InDesign document and create several PDFs based on it. Previously, they would be stored in a folder called "~/PDFExports". However, this doesn't work with 10.10.
If I change the code to just place the PDFs in "~/", it works fine. From there, I'd like to move the files to "~/PDFExports", but I can't seem to find an answer on how to do that. I've seen things about making calls to ObjC, or to call Application('Finder'), but neither work - they both return undefined.
Am I just missing something basic here, or is it really this hard to simply move a file with JXA?
EDIT: Some syntax for how I'm creating the folder in question and how I'm attempting to work with Finder.
//This is called in the Main function of the script, on first run.
var exportFolder = new Folder(exportPath);
if(!exportFolder.exists) {
exportFolder.create();
}
//This is called right after the PDF is created. file is a reference to the
actual PDF file, and destination is a file path string.
function MoveFile(file,destination){
var Finder = Application("Finder");
Application('Finder').move(sourceFile, { to: destinationFolder });
alert("File moved");
}
Adobe apps have long included their own embedded JS interpreter, JS API, and .jsx filename extension. It has nothing to do with JXA, and is not compatible with it.
InDesign's JSX documentation:
http://www.adobe.com/devnet/indesign/documentation.html#idscripting
(BTW, I'd also strongly advise against using JXA for Adobe app automation as it has a lot of missing/broken features and application compatibility problems, and really isn't fit for production work.)
Here's the link to Adobe's InDesign Scripting forum, which is the best place to get help with JSX:
https://forums.adobe.com/community/indesign/indesign_scripting
You could use Cocoa to create the folder
var exportFolder = $.NSHomeDirectory().stringByAppendingPathComponent("PDFExports")
var fileManager = $.NSFileManager.defaultManager
var folderExists = fileManager.fileExistsAtPath(exportFolder)
if (!folderExists) {
fileManager.createDirectoryAtPathWithIntermediateDirectoriesAttributesError(exportFolder, false, $(), $())
}
and to move a file
var success = fileManager.moveItemAtPathToPathError(sourceFile, destinationLocation, $());
if (success) alert("File moved");
Consider that destinationLocation must be the full path including the file name
and both sourceFile and destinationLocation must be NSString objects like exportFolder
Could it be that the folder is missing ? Could be your reference to the folder object not valid ? Any syntax to show ?
I will share some of what I learned about JXA move and duplicate methods. I am not a professional programmer just an attorney that is passionate about automation. My comments come from much trial and error, reading whatever I could find online, and A LOT of struggle. The move method does not work well with Finder. Use the System Events move method instead. The duplicate method in Finder works just fine. The duplicate method does not work well in system events. This is a modified snippet from a script I wrote showing move() using System Events.
(() => {
const strPathTargetFile = '/Users/bretfarve/Documents/MyFolderA/myFile.txt';
const strPathFolder = '/Users/bretfarve/Documents/MyFolderB/';
/* System Events Objects */
const SysEvents = Application('System Events');
const objPathFolder = SysEvents.aliases[strPathFolder];
SysEvents.move(SysEvents.aliases.byName(strPathTargetFile), {to: objPathFolder});
})();

getting cocos2d-html5 to work with visual studio

<rant> I swear dealing with IDE problems are the worse. Its like all I want to do is get my hands dirty with some code but can't. </rant>
As the title suggest I am trying to get Cocos2d-HTML5 working in Visual Studio 2012. I have coppied the Cocos2d-HTML5 files to my web directory and followed a few of the tutorials but am having a problem with jsloader.js.
Prior to the change below it was not finding the jsloader.js :
FROM: `engineDir: '../cocos2d/',`
TO: `engineDir: '../GridWars/cocos2d/'`
Gridwars is the name of the project
Now it finds jsloader.js but has an error.
Unhandled exception at line 117, column 5 in http://localhost:51244/GridWars/cocos2d/platform/jsloader.js
0x800a138f - JavaScript runtime error: Unable to get property 'loadExtension' of undefined or null reference
for these lines of code:
var d = document;
var c = d.ccConfig;
if (c.loadExtension != null && c.loadExtension == true) {
Which version of Cocos2d-html5 did you used?
It is required to configure your settings in the cocos2d.js file. You may find this file in the template folder.
For example:
var c = {
COCOS2D_DEBUG:2, //0 to turn debug off, 1 for basic debug, and 2 for full debug
box2d:false,
chipmunk:false,
showFPS:true,
loadExtension:false, //**Hey, here is the loadExtension.....**
frameRate:60,
tag:'gameCanvas', //the dom element to run cocos2d on
engineDir:'../cocos2d/',
//SingleEngineFile:'',
appFiles:[
'src/resource.js',
'src/myApp.js'//add your own files in order here
]
};
v2.2 has a similar error. I found that moving a line around in your cocos2d.js file helps.
window.addEventListener('DOMContentLoaded', function () {
...
d.body.appendChild(s);
document.ccConfig = c;
s.id = 'cocos2d-html5';
//else if single file specified, load singlefile
});
Remove the line: document.ccConfig = c; and move it before the window.addEventListener
eg:
document.ccConfig = c;
window.addEventListener('DOMContentLoaded', function () {
// etc
});
The answer was posted on their release notes. I was following one of their tutorials and ended up finding my answer at the bottom of the post.
ANSWER:
in cocos2d.js
look for "s.c = c",
change it to "document.ccConfig = c"
in main.js
look for "config:document.querySelector('#cocos2d-html5')['c'],"
change it to "config:document.ccConfig,"

Categories

Resources