Skip to content

Instantly share code, notes, and snippets.

@DorkForce
Last active November 30, 2024 19:20
Show Gist options
  • Select an option

  • Save DorkForce/34eb9a1ebf14cc5b0ba7 to your computer and use it in GitHub Desktop.

Select an option

Save DorkForce/34eb9a1ebf14cc5b0ba7 to your computer and use it in GitHub Desktop.
Console script - Search breakpoint model for value. SYNTAX: scanScope($scope.model, 'Fred');
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;
};
@DorkForce
Copy link
Copy Markdown
Author

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').

@DorkForce
Copy link
Copy Markdown
Author

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.

@DorkForce
Copy link
Copy Markdown
Author

Updated; apparently previously not searching for non-string values in the pairs

@DorkForce
Copy link
Copy Markdown
Author

Updated; better ongoing search indication to user. Any functions or errors found while search are now sorted into collapsed groups.

@DorkForce
Copy link
Copy Markdown
Author

Updated; surprisingly, it was logging null- or undefined- values as errors. Fixed!

@DorkForce
Copy link
Copy Markdown
Author

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.

@DorkForce
Copy link
Copy Markdown
Author

Added optional ignore string. Later, planning on changing that to an array.

@DorkForce
Copy link
Copy Markdown
Author

Ignore value now accepts either a string OR an array of strings

@DorkForce
Copy link
Copy Markdown
Author

Redefined functions as variable declarations; certain circumstances in the developer console require this.

@DorkForce
Copy link
Copy Markdown
Author

Added "ss=scanScope" so that I can be even lazier in the console. :)

@DorkForce
Copy link
Copy Markdown
Author

Reworked the way "callStack" was implemented, renamed as abortAtLevel

@DorkForce
Copy link
Copy Markdown
Author

nope, keeping both "callStack" and "abortAtLevel" in there, because they do both matter.

@DorkForce
Copy link
Copy Markdown
Author

DorkForce commented Feb 23, 2018

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.

@marvhen
Copy link
Copy Markdown

marvhen commented Sep 7, 2018

This is GREAT! thanks!

It errors in IE though because of the for...of.

I changed it to a foreach and that works.

@eioo
Copy link
Copy Markdown

eioo commented Feb 20, 2019

Thanks for this! Absolutely very nice

@mgutt
Copy link
Copy Markdown

mgutt commented Aug 28, 2021

I tried to use it with "window". Is it possible to avoid scanning nested window.window.window....?

@DorkForce
Copy link
Copy Markdown
Author

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment