How to find a JS function declaration in browser sources? - javascript

How do I find a JS function declaration in the sources of FF ?
First I wanted to find declaration of function "copy". I opened console, typed and executed 'copy.toSource()', the output said it is the native code. I looked this question page, followed link, downloaded sources and I thought I'll just search for word 'copy' but search results were colossal, there were about 17k entries, there's no way I can find 'copy' declaration here)
Any ideas how to find 'copy' declaration, in which directory to search?
PS: it would be interesting to look at all other functions too, for example 'console.log'. If you know how to find it's declaration, it will be awesome.

The source of copy (assuming you mean "copy to clipboard") is in ./toolkit/devtools/webconsole/utils.js. It is small, so here it is:
WebConsoleCommands._registerOriginal("copy", function JSTH_copy(aOwner, aValue)
{
let payload;
try {
if (aValue instanceof Ci.nsIDOMElement) {
payload = aValue.outerHTML;
} else if (typeof aValue == "string") {
payload = aValue;
} else {
payload = JSON.stringify(aValue, null, " ");
}
} catch (ex) {
payload = "/* " + ex + " */";
}
aOwner.helperResult = {
type: "copyValueToClipboard",
value: payload,
};
});
The console.*functions get defined in ./dom/base/Console.cpp

Related

Javascript - replace loop with native js code problem for Google Tag Manager

Apologies in advance for my ignorance. I've searched the site, but haven't had any luck.
Rather than manually enter each hostname via GA's Admin Interface, utilize the following JS function in GTM to defines the list of exclusions (var referrals), create/compare incoming {{Referrer}} (.exec, .test methods), and then null the {{Referrer}} if it's on the list, or lets it pass unmodified to GA if no match is found:
function()
{
var referrals = [
'domain_one.com',
'domain_two.com',
'domain_three.refer.com',
'store.domain_three.refer.com'
];
var hname = new RegExp('https?://([^/:]+)').exec({{Referrer}});
if (hname) {
for (var i = referrals.length; i--;) {
if (new RegExp(referrals[i] + '$').test(hname[1])) {
return null;
}
}
}
return {{Referrer}};
}
I sent the code to a developer for feedback, and he suggested replacing the for loop with with this (a direct replacement for the loop):
if (referrals.find(function(referral) { return hname[1].includes(referral); })) { return null; } else { return {{ Referrer }};
I attempted to do so like this:
function()
{
var referrals = [
'domain_one.com',
'domain_two.com',
'domain_three.refer.com',
'store.domain_three.refer.com'
];
var hname = new RegExp('https?://([^/:]+)').exec({{ Referrer }});
if (hname) {
if (referrals.find(function(referral) { return hname[1].includes(referral); })) { return null; } else { return {{ Referrer }};
}
When attempting to publish this in GTM, I'm getting both parsing errors as well as unreferenced variable errors for {{Referrer}}.
If anyone has some feedback, I'd be super super grateful.
Uh... your developer doesn't know GTM's syntax. So now for this to work, it's either the developer needs to know GTM's variable syntax or for you to know JS, so I suggest you to use your old code. It's better to use the code you understand than the code you won't be able to maintain.
If you still wanna use it, try removing spaces from the variable reference.
And you forgot to close the else claus: else { return {{ Referrer }};} And one more time to close the external if... else { return {{ Referrer }};}}
And now it looks like a mess, so here, try this:
function() {
var referrals = [
'domain_one.com',
'domain_two.com',
'domain_three.refer.com',
'store.domain_three.refer.com'
];
if (/https?:\/\/([^\/:]+)/i.test({{Referrer}})) {
if (referrals.find(function (referral) { return hname[1].includes(referral); })) { return null; } else { return {{Referrer}}; }
}
}

Best way to handle parameters when calling functions in functions

I'm writing a function in Javascript that will verify the existence of a particular kind of file and if it does not exist, then it will copy the file from a known location in a git repository to the correct location.
To do this, I'm also using a function I wrote that verifies the existence of any file (only at certain paths that we've pre-defined). Also, file.exists is a function prebuilt in our IDE.
That function looks like this:
function verifyFileExistence(file, path, existState)
{
var result;
var logMessage;
var resultMessage;
if (existState == true)
{
logMessage = "Verify that \"\"" + file + "\"\" exists.";
result = (File.exists(path + file));
if (result)
{
resultMessage = "\"\"" + file + "\"\" exists.";
}
else
{
resultMessage = "\"\"" + file + "\"\" does not exist.";
}
}
else
{
logMessage = "Verify that \"\"" + file + "\"\" does not exist.";
result = (!File.exists(path + file ));
if (result)
{
resultMessage = "\"\"" + file + "\"\" does not exist.";
}
else
{
resultMessage = "\"\"" + file + "\"\" exists.";
}
}
resultVP(logMessage, resultMessage, result)
}
Side Note: Each of these functions will write results to a log file which is why the different result/log/message variables appear. I left them in because I think they help to show make the logic clear.
So far, my function to check for the specific file type looks something like this:
import {copyFile,verifyFileExistence} from 'Path\\to\\FileUtilityLibrary.js';
function verifyLoadFile(file, path, existState, inFile, outFile)
{
var exist;
exist = (verifyFileExistence(file, path, existState));
if (exist != true)
{
copyFile(inFile,outFile)
}
}
I feel like having this many parameters in the function is inefficient and that maybe there's a more efficient way of handling them. Can I somehow simply this or is this the best way to handle parameters when calling functions inside a function?
You can do one object, for example:
const object = {
file,
path,
existState,
inFile,
outFile
}
and handle only one parameter.
I'm going to assume you are using javascript ES6 with your import notation, that means you can use the spread operator to do this
import {copyFile,verifyFileExistence} from 'Path\\to\\FileUtilityLibrary.js';
function verifyLoadFile(inFile, outFile, ...fileParams)
{
var exist;
exist = (verifyFileExistence(...fileParams));
if (exist != true)
{
copyFile(inFile,outFile)
}
}
with fileParams being all the params you need to pass to your child function. With this notation you can have a variable number of parameters passed into this function.
As liskaandar's answer points out, an object would be the best way to reduce the number of parameters.
If you don't want to reference the object each time you use those variables, you can destructure the object to give you workable variables.
For example, if passing an object that looks like this:
const object = {
file,
path,
existsState,
infile,
outfile
}
you can destructure it within your verifyFileExistence(fileObject) function by doing the below:
var {file,
path,
existsState,
infile,
outfile} = fileObject;
You can then reference those objects like normal by calling the normal variable names like file and path again.
I thought in a way to optimize the code and this is what I would use in a scenario like yours:
// verifyLoadFile function only needs three params (repositoryPath, localPath, fileName) and return an object with the log result and message
function verifyLoadFile(repositoryPath, localPath, fileName){
var exists = (!File.exists(localPath+ fileName)); //Check if file exists
var logMessageHeader = "Verify that "; //Header of message log
var messageSuccess = "\"\" exists.";
var messageWarning = "\"\" does not exists.";
var resultMessage = "\"\"" +fileName; //Initialize resultMessage with redundant parth of message
if(exists){
resultMessage = resultMessage + messageSuccess;
} else {
resultMessage = resultMessage + messageWarning;
copyFile(repositoryPath+fileName, localPath+fileName);
}
return {
logMessage: resultMessage
resultMessage: logMessageHeader + resultMessage;
};
};
// This is a function that initialize the sync of repository
function syncRepository(typeOfRepository){
var repositoryConfig = getConfig(typeOfRepository); // In the example I get an array of objects or arrays that contains config needed
repositoryConfig.forEach((obj) => {
const {logMessage,resultMessage} = verifyLoadFile(obj.repositoryPath, obj.localPath, obj.fileName); //Retrieve log values for each file
resultVP(logMessage, resultMessage); //Log the result
});
}
In this way, you only need a 14-line function (verifyLoadFile) that verify if file exist, generate log messages and copy the file if it not exists, then only if needed log the result returned in each iteration
So i think, answering your initial question, that the best way to handle parameters in functions is optimize the code.
I hope it help you.

How to check when a comment is marked as done in Word Online? Javascript API for Word Add-In

I'm trying to manipulate a Word Online documents' comments with an Add-In, and to do that I'm using the getOoxml() function to directly read/modify the xml.
However I noticed that even though I can access the comments and its contents through the given XML, I can't seem to find a tag/attribute that tells me whether the comment has been marked as done or not.
Even though my target platform is Word Online, I unzipped a local Word document(.docx) to see what it does behind-the-scenes, and realized that Word has a separate document for the "done" property called "commentsExtended.xml". This is distinct from the "comments.xml" where the comments are stored.
This is the Add-In code I use to do a simple search in the XML returned as a string by getOoxml() :
Word.run(function (context) {
var properties = context.document.body.getOoxml();
return context.sync().then(function () {
let xmlString = properties.value;
let searchPositions = [];
let curIndex = 0;
let startIndex = 0;
while((curIndex = xmlString.indexOf("done", startIndex)) > -1) {
searchPositions.push(curIndex);
startIndex = curIndex + 1;
}
console.log(searchPositions);
});
})
.catch(function (error) {
console.log('Error: ' + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
This is the content stored in "commentsExtended.xml" that I can't seem to find in getOoxml()'s return value:
<w15:commentsEx mc:Ignorable="w15" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml">
<w15:commentEx w15:done="1" w15:paraId="1930ECCA" />
<w15:commentEx w15:done="0" w15:paraId="0B31B8E3" />
</w15:commentsEx>
The XML returned by getOoxml() in Word Online doesn't seem to include this information. Is there a way to obtain this information about a comment's "done" state within a Word Add-In?
Edit: My target version is 2016.

Node.js print "undefined" in a impossible place

In my code, every place where something is printed, it goes througth this function:
log = function log (LOG, message) {
if (!message) {
message = LOG;
LOG = '\t';
}
console.log('#' + NAME + '\t-\t' + resize(LOG, 12) + '\t:\t' + message);
}
(The why of this function is not the question and is for formatting).
So every new line begin with #, whatever what data is supposed to be printed after this.
But in my log, I have this:
#App - play : [ 'FC4.mp4',
'ME.mp4',
'ME2.mp4',
'MER.mp4',
'PvS.mp4',
'BF3.mp4',
'BF4.mp4',
'BFH.mp4',
'BFH2.mp4',
[length]: 9 ]
undefined
#App - play : at 2015-03-17_16-56
Commenting out line by line just make undefined appear sooner:
#App - update : Done
undefined
#App - play : at 2015-03-17_17-08
There is no use of console.log, process.stdout.write or other write function anywhere in the code, and there is no character \n used anywhere in the code.
How can undefined appear like that? What possible cause can there be? It just freak me out to see this appear in the same place in the log whatever I do.
I ve calmed down too late to prevent posting a stupid question, but the line came from omxdirector, a npm module that I didn't checked completely before use.
Thanks to you.
(The line is in omxdirector/main.js:
var sendAction = function (action) {
if (commands[action] && omxProcess) {
try {
omxProcess.stdin.write(commands[action], function (err) {
console.log(err);
});
} catch (err) {
console.log(err);
}
}
};
Once modified, everything is back to normal)
It looks to me like NAME may be undefined for one call. You can test it by doing this:
if(NAME) {
console.log('#' + NAME + '\t-\t' + resize(LOG, 12) + '\t:\t' + message);
}

How custom logs function print line no# & file name where it was called

I have made a following custom logs function to print all console log messages. Using this function I can control with a single flag variable to either print or not logs throughout the app.
var Utilities = {
showLogs: true,
printLog: function (msg) {
if (this.showLogs) {
console.log(msg);
}
}
};
and I call it as:
Utilities.printLog("a message to print on console");
It works fine as expected. But it has one limitation i.e. its not showing the correct line no# and file name where this was called to print the logs.
One solution is to provide extra parameters to print line no# & file name along with the message.
for instance:
Utilities.printLog("a message to print on console", "10","common.js");
Utilities.printLog("a message to print on console", "310","myLib.js");
I dont want these extra parameters and like to know if there is another option available.
Update:
I tried the V8's Stack Trace API http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi but it only helps in cases when an exception is generated inside try catch block.
First override the Error.prepareStackTrace and create a tracing function like this:
Error.prepareStackTrace = function(error, stack) {
return stack;
};
function getTrace(e) {
var stack = e.stack;
var trace = "";
for (var i = 0; i < stack.length; i++) {
trace += "\r" + stack[i];
}
return trace;
}
and created two sample js files.
libObj.js
var libObj = {
getCube: function(x){
return mathLib.cube( x );
}
};
mathLib.js
var mathLib = {
cube: function(x){
return evilObj * x * x; //see the undefined evilObj --- lets catch trace here
}
};
Now from a third js file (or in my case inside the HTML file) I call the function within the try catch block to see the precise trace of the vulnerable code.
<script type="text/javascript">
try {
var results;
results = libObj.getCube(2);
console.log( results );
} catch (e) {
console.log( getTrace(e));
}
</script>
Now I get below trace of the vulnerable code:
Note:- If you do not override the Error.prepareStackTrace then it gives, I think pretty formatted trace...though both have same info.
Without overriding Error.prepareStackTrace:
Now the question remains open, how I can capture similar trace for my custom logs function as defined above.
You could do this:
var Utilities=
{
showLogs:true,
printLog:function(msg){
if(!this.showLogs) return 0;
var k=new Error().stack.split("\n").slice(2);
k.unshift(msg);
console.log(k.join("\n"));
}
}

Categories