-
-
Save DorkForce/34eb9a1ebf14cc5b0ba7 to your computer and use it in GitHub Desktop.
console.log("Usage Syntax: scanScope(objectToScan, 'scanFor', ['whatToIgnore']); %c(whatToIgnore is optional and can be a string, or an array of strings) (scanScope can be shortened to ss)", 'color: red'); | |
var abortAtLevel = 20, | |
callStack = 0, | |
errArray = [], | |
funArray = [], | |
scanLoop = function (whatToScan, scanValue, whatToIgnore, parentTree) { | |
scanValue = scanValue.toLowerCase(); | |
if (Array.isArray(whatToIgnore)) { | |
whatToIgnore.forEach(function (ignoreVal) { | |
ignoreVal = lowerCase(ignoreVal); | |
}); | |
} else { | |
whatToIgnore = lowerCase(whatToIgnore); | |
} | |
var yesCheck = false, | |
insertString = ''; | |
if (parentTree === undefined) { | |
callStack = 0; | |
} | |
callStack ++; | |
if (callStack > 1500) { | |
return; | |
} | |
for (var key in whatToScan) { | |
try { | |
yesCheck = (exists(whatToScan[key]) && (whatToScan[key].toString().indexOf !== undefined) && whatToScan[key].toString().toLowerCase !== undefined) | |
if ((yesCheck && whatToScan[key].toString().toLowerCase().indexOf(scanValue) > -1) || key.toLowerCase().indexOf(scanValue) >= 0) { // if we DO find a match... | |
if (dontIgnoreThis(whatToScan[key].toString().toLowerCase(), key.toLowerCase(), whatToIgnore)) { // check to see if we should ignore this match | |
if (exists(parentTree)) { | |
insertString = parentTree + '.'; | |
} else { | |
insertString = ''; | |
} | |
if (!isAutoVar(key) && !isAutoVar(insertString)) { // by default just ignore anything starting with typical auto-values | |
if (exists(whatToScan[key]) && whatToScan[key].toString().indexOf('function') > -1) { | |
funArray.push(insertString + key + ' = ' + whatToScan[key]); // we found a function so add it to the funArray | |
} else { | |
console.log(insertString + key + ' = ' + whatToScan[key]); // we found an actual variable match | |
} | |
} | |
} | |
} else { // no match found, so... | |
if( (typeof whatToScan[key] === 'object') && (key !== null) ) { // ... if this is an object, jump into it and continue scanning | |
if (exists(whatToScan[key]) && exists(whatToScan[key].toString()) && whatToScan[key].toString().indexOf('$$') < 0) { | |
if (exists(parentTree)) { | |
insertString = parentTree + '.' + key; | |
} else { | |
insertString = '' + key; | |
} | |
if (dontIgnoreThis(whatToScan[key].toString().toLowerCase(), insertString.toLowerCase(), whatToIgnore) && !tooManyLevelsDeep(insertString) ) { | |
scanLoop(whatToScan[key], scanValue, whatToIgnore, insertString); | |
} | |
} | |
} | |
} | |
} catch (err) { | |
errArray.push('>> ' + err + ' while scanning ' + key); | |
} | |
} | |
}, | |
ss=scanScope = function (whatToScan, scanValue, whatToIgnore, parentTree) { | |
console.log('%c------------------------- Beginning scan', 'color: gold'); | |
scanLoop(whatToScan, scanValue, whatToIgnore, parentTree); | |
if (funArray.length > 0 || errArray.length > 0) { | |
console.log('-------------------------'); | |
} | |
if (funArray.length > 0) { | |
console.groupCollapsed('Functions found while scanning'); | |
funArray.forEach(function(entry) { | |
console.log(entry); | |
}); | |
console.groupEnd(); | |
} | |
if (errArray.length > 0) { | |
console.groupCollapsed('Errors found while scanning'); | |
errArray.forEach(function(entry) { | |
console.log(entry); | |
}); | |
console.groupEnd(); | |
} | |
console.log('%c------------------------- Scan complete', 'color: gold'); | |
}, | |
exists = function (whatToCheck) { | |
if (whatToCheck !== null & whatToCheck !== undefined) { | |
return true; | |
} | |
return false; | |
}, | |
lowerCase = function (whatToLower) { | |
whatToLower = whatToLower !== undefined ? whatToLower.toLowerCase() : undefined; | |
return whatToLower | |
}, | |
dontIgnoreThis = function (valToCheck1, valToCheck2, valToIgnore) { | |
if (!exists(valToIgnore)) { | |
return true; | |
} | |
var foundIgnoreInArrayCount = 0; | |
if (Array.isArray(valToIgnore)) { | |
valToIgnore.forEach(function (thisIgnoreVal) { | |
if (valToCheck1.indexOf(thisIgnoreVal) > -1 || valToCheck2.indexOf(thisIgnoreVal) > -1) { | |
foundIgnoreInArrayCount++; | |
} | |
}); | |
if (foundIgnoreInArrayCount > 0) { | |
return false; | |
} | |
} else { | |
if (valToCheck1.indexOf(valToIgnore) > -1 || valToCheck2.indexOf(valToIgnore) > -1) { | |
return false; | |
} | |
} | |
return true; | |
}, | |
tooManyLevelsDeep = function(valToCheck) { | |
if (valToCheck.length - valToCheck.replace(/\./g, '').length > abortAtLevel) { | |
return true; | |
} | |
return false; | |
}, | |
isAutoVar = function(varToCheck) { | |
var prefixList = ['__', '$$']; | |
for (let prefix of prefixList) { | |
if (varToCheck.indexOf('.'+prefix) >= 0) return true; | |
if (varToCheck.substr(0,prefix.length) === prefix) return true; | |
} | |
return false; | |
}; |
Added maximum callStack of 1500 calls, filtering out angular variables starting with '$$'. This allows you to just scan your $scope for whatever you'd like. You could also increase this; I've gone 15000 calls, even, but you probably don't need that. Increasing the calls will allow it to crawl through all respecting $parent variables.
Added a try/catch in there that it shouldn't really need... hmph.
Updated; apparently previously not searching for non-string values in the pairs
Updated; better ongoing search indication to user. Any functions or errors found while search are now sorted into collapsed groups.
Updated; surprisingly, it was logging null- or undefined- values as errors. Fixed!
added spaces to the console.log line that outputs the sample syntax call. Makes it easier to select and copy after it's displayed in the console.
Added optional ignore string. Later, planning on changing that to an array.
Ignore value now accepts either a string OR an array of strings
Redefined functions as variable declarations; certain circumstances in the developer console require this.
Added "ss=scanScope" so that I can be even lazier in the console. :)
Reworked the way "callStack" was implemented, renamed as abortAtLevel
nope, keeping both "callStack" and "abortAtLevel" in there, because they do both matter.
Added "$$" to list of variables to exclude, and changed the way it searches for properties that begin with the "automatic" indicators __ and $$. Note that at this time, I see that if a certain-formatted object is a property on the object being searched, it's still possible that scanScope can decide to quit entirely before deciding to quit that object. Or something. Refinements, refinements.
This is GREAT! thanks!
It errors in IE though because of the for...of.
I changed it to a foreach and that works.
Thanks for this! Absolutely very nice
I tried to use it with "window". Is it possible to avoid scanning nested window.window.window....?
Ah crap, I realize I do not seem to get notifications about comments... my apologies for the lack of responses here... I hope/presume, @mgutt , that you were able to get around the nested window issue?
This is intended to be pasted into the console while investigating a breakpoint.
When run, it will search a complex model defined on the scope (submitted as 'whatToScan') for either a property that partially matches the desired search term ('scanValue'), or a property whose name partially matches the search term (also 'scanValue').