Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

spotlight

Package Overview
Dependencies
Maintainers
2
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

spotlight - npm Package Compare versions

Comparing version 0.1.338 to 1.0.0

4

LICENSE.txt

@@ -1,3 +0,3 @@

Copyright 2011 Angus Croll <http://javascriptweblog.wordpress.com/>
And John-David Dalton <http://allyoucanleet.com/>
Copyright 2011-2014 John-David Dalton <http://allyoucanleet.com/>
And Angus Croll <http://javascriptweblog.wordpress.com/>

@@ -4,0 +4,0 @@ Permission is hereby granted, free of charge, to any person obtaining

{
"name": "spotlight",
"version": "0.1.338",
"version": "1.0.0",
"description": "An object crawler/property search library that works on nearly all JavaScript platforms.",
"homepage": "https://github.com/bestiejs/spotlight.js",
"main": "spotlight",
"keywords": [
"crawl",
"find",
"search",
"utility"
"license": "MIT",
"main": "spotlight.js",
"keywords": ["crawl", "find", "search", "utility"],
"author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"contributors": [
"John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"Benjamin Tan <demoneaux@gmail.com> (http://d10.github.io/)"
],
"licenses": [
{
"type": "MIT",
"url": "http://mths.be/mit"
}
],
"author": {
"name": "John-David Dalton",
"email": "john@fusejs.com",
"web": "http://allyoucanleet.com/"
"bugs": "https://github.com/bestiejs/spotlight.js/issues",
"repository": "bestiejs/spotlight.js",
"scripts": { "test": "echo \"See the repository CONTRIBUTING.md for testing instructions.\"" },
"dependencies": {
"lodash": "~2.4.1"
},
"bugs": {
"url": "https://github.com/bestiejs/spotlight.js/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/bestiejs/spotlight.js.git"
},
"engines": [

@@ -35,6 +24,6 @@ "node",

],
"directories": {
"doc": "docs",
"test": "tests"
}
}
"files": [
"LICENSE.txt",
"spotlight.js"
]
}

@@ -1,2 +0,2 @@

# Spotlight.js
# Spotlight.js <sup>v1.0.0</sup>

@@ -7,7 +7,7 @@ An object crawler/property search library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>.

Spotlight.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
Spotlight.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5+ precedents, unit testing, and plenty of documentation.
## Documentation
The documentation for Spotlight.js can be viewed here: [/docs/README.md](https://github.com/bestiejs/spotlight.js/blob/master/docs/README.md#readme)
The documentation for Spotlight.js can be viewed here: [/doc/README.md](https://github.com/bestiejs/spotlight.js/blob/master/doc/README.md#readme)

@@ -18,32 +18,36 @@ For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/spotlight.js/wiki/Roadmap).

Spotlight.js’ only hard dependency is [Lo-Dash](http://lodash.com/).
In a browser:
~~~ html
```html
<script src="lodash.js"></script>
<script src="spotlight.js"></script>
~~~
```
Via [npm](http://npmjs.org/):
~~~ bash
```bash
npm install spotlight
~~~
```
In [Narwhal](http://narwhaljs.org/), [Node.js](http://nodejs.org/), and [RingoJS](http://ringojs.org/):
In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/):
~~~ js
```js
var spotlight = require('spotlight');
~~~
```
In [Rhino](http://www.mozilla.org/rhino/):
~~~ js
```js
load('spotlight.js');
~~~
```
In [RequireJS](http://requirejs.org/):
In an AMD loader like [RequireJS](http://requirejs.org/):
~~~ js
```js
require({
'paths': {
'spotlight': 'path/to/spotlight'
'spotlight': 'path/to/spotlight',
'lodash': 'path/to/lodash'
}

@@ -54,7 +58,7 @@ },

});
~~~
```
Usage example:
~~~ js
```js
// find all "length" properties

@@ -89,26 +93,7 @@ spotlight.byName('length');

spotlight.custom(function(value) { return !value; });
~~~
```
## Cloning this repo
To clone this repository including all submodules, using Git 1.6.5 or later:
~~~ bash
git clone --recursive https://github.com/bestiejs/spotlight.js.git
cd spotlight.js
~~~
For older Git versions, just use:
~~~ bash
git clone https://github.com/bestiejs/spotlight.js.git
cd spotlight.js
git submodule update --init
~~~
Feel free to fork if you see possible improvements!
## Footnotes
1. Spotlight.js has been tested in at least Chrome 5/8/12/14, Firefox 1.5-4, IE 6-10, Opera 9.25-12, Safari 2-5, Node.js 0.4.2, Narwhal 0.3.2, Ringo 0.7, and Rhino 1.7RC3.
1. Spotlight.js has been tested in at least Chrome 33-34, Firefox 27-28, IE 6-11, Opera 19-20, Safari 5-7, Node.js 0.6.21~0.10.26, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, and Rhino 1.7RC5.
<a name="fn1" title="Jump back to footnote 1 in the text." href="#fnref1">&#8617;</a>

@@ -118,3 +103,10 @@

* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](http://twitter.com/jdalton "Follow @jdalton on Twitter") |
|---|
| [John-David Dalton](http://allyoucanleet.com/) |
## Contributors
| [![twitter/demoneaux](http://gravatar.com/avatar/029b19dba521584d83398ada3ecf6131?s=70)](https://twitter.com/demoneaux "Follow @demoneaux on Twitter") |
|---|
| [Benjamin Tan](http://d10.github.io/) |
/*!
* Spotlight.js <http://github.com/bestiejs/spotlight.js/>
* Copyright 2011 John-David Dalton <http://allyoucanleet.com/>
* Based on Waldo <http://github.com/angus-c/waldo/>,
* Copyright 2011 Angus Croll <http://javascriptweblog.wordpress.com/>
* Spotlight.js v1.0.0 <https://github.com/bestiejs/spotlight.js/>
* Copyright 2011-2014 John-David Dalton <http://allyoucanleet.com/>
* Based on Waldo <https://github.com/angus-c/waldo/>,
* Copyright 2011-2014 Angus Croll <http://javascriptweblog.wordpress.com/>
* Both available under MIT license <http://mths.be/mit>
*/
;(function(window, undefined) {
;(function() {
'use strict';
/* Used as the starting point(s) for the object crawler */
var defaultRoots = [{ 'object': window, 'path': 'window' }],
/** Used as a safe reference for `undefined` in pre ES5 environments */
var undefined;
/** Detect free variable `exports` */
freeExports = typeof exports == 'object' && exports,
/** Used to determine if values are of the language type `Object` */
var objectTypes = {
'boolean': false,
'function': true,
'object': true,
'number': false,
'string': false,
'undefined': false
};
/** Detect free variable `global` */
freeGlobal = typeof global == 'object' && global && (global == global.global ? (window = global) : global),
/** Used as a reference to the global object */
var root = (objectTypes[typeof window] && window) || this;
/** Used to get __iterator__ descriptors */
getDescriptor = Object.getOwnPropertyDescriptor,
/** Detect free variable `define` */
var freeDefine = typeof define == 'function' && typeof define.amd == 'object' && define.amd && define;
/** Used in case an object doesn't have its own method */
hasOwnProperty = {}.hasOwnProperty,
/** Detect free variable `exports` */
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
/** Used to set __iterator__ descriptors */
setDescriptor = Object.defineProperty,
/** Detect free variable `module` */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Used to resolve a value's internal [[Class]] */
toString = {}.toString,
/** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
root = freeGlobal;
}
/** Filter functions used by `crawl()` */
filters = {
'custom': function(value, key, object) {
// the `this` binding is set by `crawl()`
return value.call(this, object[key], key, object);
},
'kind': function(value, key, object) {
var kind = [value, value = object[key]][0];
return isFunction(kind) ? value instanceof kind :
typeof value == kind || getKindOf(value).toLowerCase() == kind.toLowerCase();
},
'name': function(value, key, object) {
return value == key;
},
'value': function(value, key, object) {
return object[key] === value;
}
},
/** Detect free variable `require` */
var freeRequire = typeof require == 'function' && require;
/** Used to flag features */
has = {
/** Detect ES5+ property descriptor API */
'descriptors' : !!(function() {
try {
var o = {};
return (setDescriptor(o, o, o), 'value' in getDescriptor(o, o));
} catch(e) { }
}()),
/**
* Detect JavaScript 1.7 iterators
* https://developer.mozilla.org/en/new_in_javascript_1.7#Iterators
*/
'iterators': !!(function() {
try {
var o = Iterator({ '': 1 });
for (o in o) { }
return toString.call(o) == '[object Array]';
} catch(e) { }
}())
};
/*--------------------------------------------------------------------------*/
/**
* Returns the first array value for which `callback` returns true.
* A wrapper around `require()` to suppress `module missing` errors.
*
* @private
* @param {Array} array The array to search.
* @param {Function} callback A function executed per array value .
* @returns {Mixed} The filtered value.
* @param {string} id The module id.
* @returns {*} The exported module or `null`.
*/
function filterOne(array, callback) {
var length = array.length;
while (length--) {
if (callback(array[length])) {
return array[length];
}
}
function req(id) {
try {
var result = freeExports && freeRequire(id);
} catch(e) { }
return result || null;
}
/*--------------------------------------------------------------------------*/
/**
* Iterates over an object's own properties, executing the `callback` for each.
* @private
* @param {Object} object The object to iterate over.
* @param {Function} callback A function executed per own property.
* @param {Mixed} [owner=null] The owner of the `object`.
* Create a new `spotlight` object using the given `context` object.
*
* @memberOf spotlight
* @param {Object} [context=root] The context object.
* @returns {Object} Returns a new `spotlight` object.
*/
function forOwn() {
// list of possible shadowed properties of Object.prototype
var shadowed = [
'constructor', 'hasOwnProperty', 'isPrototypeOf',
'propertyIsEnumerable', 'toLocaleString',
'toString', 'valueOf'
];
function runInContext(context) {
// exit early if unable to acquire Lo-Dash
var _ = context && context._ || req('lodash') || root._;
if (!_) {
return { 'runInContext': runInContext };
}
context || (context = root);
// flag for..in bugs
var flag = (function() {
function Klass() { this.valueOf = 0; };
var count = Klass.prototype.valueOf = 0;
for (var key in new Klass) { count++; }
return count;
}());
/** Native constructor references */
var Function = context.Function,
Object = context.Object,
RegExp = context.RegExp,
String = context.String;
// Safari 2 iterates over shadowed properties twice
// http://replay.waybackmachine.org/20090428222941/http://tobielangel.com/2007/1/29/for-in-loop-broken-in-safari/
var hasSeen = flag == 2 &&
function(seen, key) {
return hasKey(seen, key) || !(seen[key] = true);
};
/** Used to indicate that methods will execute in debug mode */
var isDebug = false;
// IE < 9 skips enumerable properties shadowing non-enumerable ones
var forOwnShadowed = flag == 0 &&
function(object, callback, owner) {
// because IE < 9 can't set the [[Enumerable]] attribute of an existing
// property and the `constructor` property of a prototype defaults to
// non-enumerable, we manually skip the `constructor` property when
// iterating over a `prototype` object.
var skipCtor = isFunction(owner) && isObject(object);
for (var key, i = 0; key = shadowed[i]; i++) {
if (hasKey(object, key) &&
!(skipCtor && key == shadowed[0]) &&
callback(object[key], key, object) === false) {
break;
}
}
};
/** Used to resolve a value's internal `[[Class]]` */
var toString = Object.prototype.toString;
// lazy define
forOwn = function(object, callback, owner) {
var done,
iterator,
key,
value,
seen = {},
skipProto = isFunction(object);
/** Used to detect if a method is native */
var reNative = RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/** Native method shortcuts */
var fnToString = Function.prototype.toString,
getDescriptor = isNative(getDescriptor = Object.getOwnPropertyDescriptor) && getDescriptor,
setDescriptor = isNative(setDescriptor = Object.defineProperty) && setDescriptor;
/** Filter functions used by `crawl` */
var filters = {
'custom': function(value, key, object) {
// the `this` binding is set by `crawl()`
return value.call(this, object[key], key, object);
},
'kind': function(value, key, object) {
var kind = [value, value = object[key]][0];
return kind == '*' || (_.isFunction(kind)
? value instanceof kind
: typeof value == kind || getKindOf(value).toLowerCase() == kind.toLowerCase()
);
},
'name': function(value, key, object) {
return value == key;
},
'value': function(value, key, object) {
return object[key] === value;
}
};
/** Used to flag environments features */
var support = {
/** Detect ES5 property descriptor API */
'descriptors' : (function() {
// IE 8 only accepts DOM elements
try {
var o = {};
setDescriptor(o, o, o);
var result = 'value' in getDescriptor(o, o);
} catch(e) { };
return !!result;
}()),
/**
* Detect JavaScript 1.7 iterators
* https://developer.mozilla.org/en/new_in_javascript_1.7#Iterators
*/
'iterators': (function() {
try {
var o = Iterator({ '': 1 });
for (o in o) { }
} catch(e) { }
return _.isArray(o);
}())
};
/** Used as the starting point(s) for the object crawler */
var defaultRoots = [{ 'object': context, 'path': 'window' }];
// set `defaultRoots` for CLI environments like Narwhal, Node.js, or RingoJS
if (freeGlobal) {
defaultRoots = [{ 'object': freeGlobal, 'path': 'global' }];
// for the Narwhal REPL
if (context != freeGlobal) {
defaultRoots.unshift({ 'object': context, 'path': '<module scope>' });
}
// avoid explicitly crawling `exports` if it's crawled indirectly
if (!(freeGlobal.exports == freeExports || context.exports == freeExports)) {
defaultRoots.unshift({ 'object': freeExports, 'path': 'exports' });
}
}
// for Rhino
else if (isHostType(context, 'environment') && isHostType(context, 'java')) {
defaultRoots[0].path = '<global object>';
}
/*------------------------------------------------------------------------*/
/**
* Iterates over an object's own properties, executing the `callback` for each.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} callback A function executed per own property.
*/
function forOwn(object, callback) {
object = Object(object);

@@ -153,4 +185,4 @@

// https://github.com/ringo/ringojs/issues/157
if (has.iterators && isFunction(object.__iterator__)) {
iterator = has.descriptors
if (support.iterators && _.isFunction(object.__iterator__)) {
var iterator = support.descriptors
? getDescriptor(object, '__iterator__')

@@ -161,9 +193,12 @@ : object.__iterator__;

delete object.__iterator__;
if (object.__iterator__) {
throw 1;
}
object = [new Iterator(object), has.descriptors
? setDescriptor(object, '__iterator__', iterator)
: object.__iterator__ = iterator
][0];
object = new Iterator(object);
if (support.descriptors) {
setDescriptor(object, '__iterator__', iterator);
} else {
object.__iterator__ = iterator;
}
}

@@ -173,3 +208,3 @@ // some objects like Firefox 3's `XPCSafeJSObjectWrapper.prototype` may

else {
for (key in object) {
for (var key in object) {
break;

@@ -181,472 +216,424 @@ }

}
if (iterator) {
for (key in object) {
// iterators will assign an array to `key`
callback(key[1], key[0], object);
}
}
else {
var index = -1,
props = _.keys(object),
length = props.length;
for (key in object) {
// iterators will assign an array to `key`
if (iterator) {
value = key[1];
key = key[0];
}
else {
while (++index < length) {
// some properties like Firefox's `console.constructor` or IE's
// `element.offsetParent` may throw errors when accessed
try {
value = object[key];
key = props[index];
var value = object[key];
} catch(e) {
continue;
}
callback(value, key, object);
}
// Opera and Safari incorrectly set a function's `prototype` property
// [[Enumerable]] value to true by default. Because of this we standardize
// on skipping the the `prototype` property of functions regardless of
// their [[Enumerable]] value.
if (done =
!(hasSeen && hasSeen(seen, key)) &&
(iterator || hasKey(object, key)) &&
!(skipProto && key == 'prototype') &&
callback(value, key, object) === false) {
break;
}
}
if (!done && forOwnShadowed) {
forOwnShadowed(object, callback, owner);
}
/**
* Gets the internal `[[Class]]` of a given `value`.
*
* @private
* @param {*} value The value to inspect.
* @returns {string} Returns the value's internal `[[Class]]`.
*/
function getClass(value) {
if (value == null) {
return value === null ? 'Null' : 'Undefined';
}
};
forOwn.apply(null, arguments);
}
try {
var result = _.result(/^\[object (.*?)\]$/.exec(toString.call(value)), 1);
} catch(e) { }
/**
* Mimics ES 5.1's `Object.prototype.toString` behavior by returning the
* value's [[Class]], "Null" or "Undefined" as well as other non-spec'ed results
* like "Constructor" and "Global" .
* @private
* @param {Mixed} value The value to check.
* @returns {String} Returns the value's [[Class]] or "Null" or "Undefined".
*/
function getKindOf(value) {
var result;
if (value == null) {
result = value === null ? 'Null' : 'Undefined';
return result || '';
}
else if (value == window) {
result = 'Global';
}
else if (isFunction(value) && isHostType(value, 'prototype')) {
// a function is assumed of kind "Constructor" if it has its own
// enumerable prototype properties or doesn't have a [[Class]] of Object
if (toString.call(value.prototype) == '[object Object]') {
forOwn(value.prototype, function() { return !(result = 'Constructor'); }, value);
} else {
result = 'Constructor';
/**
* Mimics ES 5.1's `Object.prototype.toString` behavior by returning the
* value's `[[Class]]`, "Null" or "Undefined" as well as other non-spec'ed results
* like "Constructor" and "Global" .
*
* @private
* @param {*} value The value to check.
* @returns {string} Returns a string representing the kind of `value`.
*/
function getKindOf(value) {
var result;
if (value == null) {
result = value === null ? 'Null' : 'Undefined';
}
else if (value == context) {
result = 'Global';
}
else if (_.isFunction(value) && isHostType(value, 'prototype')) {
// a function is assumed of kind "Constructor" if it has its own
// enumerable prototype properties or doesn't have a `[[Class]]` of Object
try {
if (getClass(value.prototype) == 'Object') {
for (var key in value.prototype) {
result = 'Constructor';
break;
}
} else {
result = 'Constructor';
}
} catch(e) { }
}
return result || getClass(value) ||
(result = typeof value, result.charAt(0).toUpperCase() + result.slice(1))
}
return result || (toString.call(value).match(/^\[object (.*?)\]$/) || 0)[1] ||
(result = typeof value, result.charAt(0).toUpperCase() + result.slice(1))
}
/**
* Checks if an object has the specified key as a direct property.
* @private
* @param {Object} object The object to check.
* @param {String} key The key to check for.
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
*/
function hasKey() {
// lazy define for modern browsers
if (isFunction(hasOwnProperty)) {
hasKey = function(object, key) {
return hasOwnProperty.call(Object(object), key);
};
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of "object", "function", or "unknown".
*
* @private
* @param {mixed} object The owner of the property.
* @param {string} property The property to check.
* @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/
function isHostType(object, property) {
var type = object != null ? typeof object[property] : 'number';
return objectTypes[type] && (type == 'object' ? !!object[property] : true);
}
// or for Safari 2
else if ({}.__proto__ == Object.prototype) {
hasKey = function(object, key) {
var result;
object = Object(object);
object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
return result;
};
/**
* Checks if `value` is a native function.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
*/
function isNative(value) {
return typeof value == 'function' && reNative.test(fnToString.call(value));
}
// or for others (not as accurate)
else {
hasKey = function(object, key) {
object = Object(object);
var parent = (object.constructor || Object).prototype;
return key in object && !(key in parent && object[key] === parent[key]);
};
}
// or for an Opera < 10.53 bug, found by Garrett Smith, that occurs with
// window objects and not the global `this`
if (window.window == window && !hasKey(window.window, 'Object')) {
var __hasKey = hasKey;
hasKey = function(object, key) {
return object == window
? key in object && object[key] !== {}[key]
: __hasKey(object, key);
};
}
return hasKey.apply(null, arguments);
}
/**
* Checks if the specified `value` is a function.
* @private
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if `value` is a function, else `false`.
*/
function isFunction(value) {
return toString.call(value) == '[object Function]';
}
/*------------------------------------------------------------------------*/
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of object, function, or unknown.
* @private
* @param {Mixed} object The owner of the property.
* @param {String} property The property to check.
* @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/
function isHostType(object, property) {
var type = object != null ? typeof object[property] : 'number';
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
(type == 'object' ? !!object[property] : true);
}
/**
* Performs argument type checks and calls `crawl()` with specified arguments.
*
* @private
* @param {string} name The name of the filter function passed.
* @param {string} expected The data type expected of the given value.
* @param {*} value A generic argument passed to the callback.
* @param {Object} [options={}] The options object passed.
* @returns {Array|null} If in debug mode return the value of the invoked function or `null` if errored.
*/
function checkCall(name, expected, value, options) {
var result = (!expected || RegExp('^(?:' + expected + ')$', 'i').test(getKindOf(value)))
? crawl(name, value, options)
: (log('error', '`' + value + '` must be a ' + expected.split('|').join(' or ')), null);
/**
* Checks if the specified `value` is an Object object.
* @private
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if `value` is an object, else `false`.
*/
function isObject(value) {
var constructor,
result = toString.call(value) == '[object Object]';
// some objects like `window.java` may kill script execution when checking
// for their constructor, so we filter by [[Class]] first
if (result) {
// some properties throw errors when accessed
try {
constructor = value && value.constructor;
} catch(e) { }
// IE < 9 presents nodes like Object objects:
// IE < 8 are missing the node's constructor property
// IE 8 node constructors are typeof "object"
result = constructor && typeof constructor != 'object';
return isDebug ? result : undefined;
}
return result;
}
/*--------------------------------------------------------------------------*/
/**
* Crawls environment objects logging all properties that pass the callback filter.
*
* @private
* @param {Function|string} callback A function executed per object encountered.
* @param {*} callbackArg An argument passed to the callback.
* @param {Object} [options={}] The options object.
* @returns {Array} An array of arguments passed to each `console.log()` call.
*/
function crawl(callback, callbackArg, options) {
callback = filters[callback] || callback;
options || (options = {});
/**
* Performs argument type checks and calls `crawl()` with specified arguments.
* @private
* @param {String} name The name of the filter function passed.
* @param {String} expected The data type expected of the given value.
* @param {Mixed} value A generic argument passed to the callback.
* @param {Object} [options={}] The options object passed.
* @returns {Array|Null} If in debug mode return the value of the invoked function or `null` if errored.
*/
function checkCall(name, expected, value, options) {
var result = (!expected || RegExp('^(?:' + expected + ')$', 'i').test(getKindOf(value)))
? crawl(name, value, options)
: (log('error', '`' + value + '` must be a ' + expected.split('|').join(' or ')), null);
var data,
index,
pool,
pooled,
queue,
separator,
roots = defaultRoots.slice(),
object = options.object || roots[0].object,
path = options.path,
result = [];
return spotlight.debug ? result : undefined;
}
/**
* Crawls environment objects logging all properties that pass the callback filter.
* @private
* @param {Function|String} callback A function executed per object encountered.
* @param {Mixed} callbackArg An argument passed to the callback.
* @param {Object} [options={}] The options object.
* @returns {Array} An array of arguments passed to each `console.log()` call.
*/
function crawl(callback, callbackArg, options) {
callback = filters[callback] || callback;
options || (options = {});
var data,
owner,
pool,
pooled,
queue,
separator,
roots = defaultRoots.slice(),
object = options.object || roots[0].object,
path = options.path,
result = [];
// resolve undefined path
if (path == null) {
path = (
filterOne(roots, function(data) {
return object == data.object;
}) ||
{ 'path': '<object>' }
).path;
}
// resolve object roots
if (options.object) {
roots = [{ 'object': object, 'path': path }];
}
// crawl all root objects
while ((data = roots.pop())) {
object = data.object;
path = data.path;
queue = [{ 'object': object, 'path': path, 'pool': [object] }];
owner = /(?:^|[\W_])prototype[\W_]*$/i.test(path) && callback;
// a non-recursive solution to avoid call stack limits
// http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4
while ((data = queue.pop())) {
// resolve `undefined` path
if (path == null) {
path = _.result(_.find(roots, { 'object': object }), 'path') || '<object>';
}
// resolve object roots
if (options.object) {
roots = [{ 'object': object, 'path': path }];
}
// crawl all root objects
while ((data = roots.pop())) {
index = 0;
object = data.object;
path = data.path;
separator = path ? '.' : '';
data = { 'object': object, 'path': path, 'pool': [object] };
queue = [];
forOwn(object, function(value, key) {
// inspect objects
if (isObject(value)) {
// clone current pool per prop on the current `object` to avoid siblings
// polluting each others object pools
pool = data.pool.slice();
// a non-recursive solution to avoid call stack limits
// http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4
do {
object = data.object;
path = data.path;
separator = path ? '.' : '';
// check if already pooled (prevents circular references)
// console.log('debug:', path, key, data.pool.length, data.pool.slice());
pooled = filterOne(pool, function(data) {
return value == data.object;
});
forOwn(object, function(value, key) {
// (IE may throw errors coercing properties like `window.external` or `window.navigator`)
try {
// inspect objects
if (_.isPlainObject(value)) {
// clone current pool per prop on the current `object` to avoid
// sibling properties from polluting each others object pools
pool = data.pool.slice();
// add to "call" queue
if (!pooled) {
pool.push({ 'object': value, 'path': path + separator + key, 'pool': pool });
queue.push(pool[pool.length - 1]);
}
}
// if filter passed, log it
// (IE may throw errors coercing properties like `window.external` or `window.navigator`)
try {
if (callback.call(data, callbackArg, key, object)) {
result.push([
path + separator + key + ' -> (' +
(true && pooled ? '<' + pooled.path + '>' : getKindOf(value).toLowerCase()) + ')',
value
]);
log('text', result[result.length - 1][0], value);
}
} catch(e) { }
},
// attempt to handle an edge case where a function prototype is provided
// via `options.object` by guesstimating, based on its `options.path` to
// be a function prototype then supply a dummy function to trigger
// `forOwn()`'s `skipCtor` flag.
data.pool.length == 1 && owner);
// check if already pooled (prevents infinite loops when handling circular references)
pooled = _.find(pool, function(data) {
return value == data.object;
});
// add to the "call" queue
if (!pooled) {
pool.push({ 'object': value, 'path': path + separator + key, 'pool': pool });
queue[queue.length] = pool[pool.length - 1];
}
}
// if filter passed, log it
if (callback.call(data, callbackArg, key, object)) {
result.push([
path + separator + key + ' -> (' +
(true && pooled ? '<' + pooled.path + '>' : getKindOf(value).toLowerCase()) + ')',
value
]);
log('text', result[result.length - 1][0], value);
}
} catch(e) { }
});
} while ((data = queue[index++]));
}
return result;
}
return result;
}
/**
* Logs a message to the console.
* @private
* @param {String} type The log type, either "text" or "error".
* @param {String} message The log message.
* @param {Mixed} value An additional value to log.
*/
function log() {
var defaultCount = 2,
console = typeof window.console == 'object' && window.console,
document = typeof window.document == 'object' && window.document,
JSON = typeof window.JSON == 'object' && isFunction(window.JSON && window.JSON.stringify) && window.JSON;
/**
* Logs a message to the console.
*
* @private
* @param {string} type The log type, either "text" or "error".
* @param {string} message The log message.
* @param {*} value An additional value to log.
*/
function log() {
var defaultCount = 2,
console = isHostType(context, 'console') && context.console,
document = isHostType(context, 'document') && context.document,
phantom = isHostType(context, 'phantom') && context.phantom,
JSON = isHostType(context, 'JSON') && _.isFunction(context.JSON && context.JSON.stringify) && context.JSON;
// lazy define
log = function(type, message, value) {
var argCount = defaultCount,
method = 'log';
// lazy define
log = function(type, message, value) {
var argCount = defaultCount,
method = 'log';
if (type == 'error') {
argCount = 1;
if (isHostType(console, type)) {
method = type;
} else {
message = type + ': ' + message;
if (type == 'error') {
argCount = 1;
if (isHostType(console, type)) {
method = type;
} else {
message = type + ': ' + message;
}
}
}
// avoid logging if in debug mode and running from the CLI
if (document || !spotlight.debug) {
// because `console.log` is a host method we don't assume `.apply()` exists
if (argCount < 2) {
value = JSON ? JSON.stringify(value) : value;
console[method](message + (type == 'error' ? '' : ' ' + value));
} else {
console[method](message, value);
// avoid logging if in debug mode and running from the CLI
if (!isDebug || (document && !phantom)) {
// because `console.log` is a host method we don't assume `.apply()` exists
if (argCount < 2) {
if (JSON) {
value = [JSON.stringify(value), value];
value = value[0] == 'null' ? value[1] : value[0];
}
console[method](message + (type == 'error' ? '' : ' ' + value));
} else {
console[method](message, value);
}
}
};
// for Narwhal, Rhino, or RingoJS
if (!console && !document && _.isFunction(context.print)) {
console = { 'log': print };
}
};
// for Narwhal, Rhino, or RingoJS
if (!console && !document && isFunction(window.print)) {
console = { 'log': print };
// use noop for no log support
if (!isHostType(console, 'log')) {
log = function() { };
}
// avoid Safari 2 crash bug when passing more than 1 argument
else if (console.log.length == 1) {
defaultCount = 1;
}
return log.apply(null, arguments);
}
// use noop for no log support
if (!isHostType(console, 'log')) {
log = function() { };
}
// avoid Safari 2 crash bug when passing more than 1 argument
else if (console.log.length == 1) {
defaultCount = 1;
}
return log.apply(null, arguments);
}
/*--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*/
/**
* Crawls environment objects logging all object properties whose values
* are of a specified constructor instance, [[Class]], or type.
* @memberOf spotlight
* @param {Function|String} kind The constructor, [[Class]], or type to check against.
* @param {Object} [options={}] The options object.
* @example
*
* // by constructor
* spotlight.byKind(jQuery);
*
* // or by [[Class]]
* spotlight.byKind('RegExp');
*
* // or by type
* spotlight.byKind('undefined');
*
* // or special kind "constructor"
* spotlight.byKind('constructor');
*/
function byKind(kind, options) {
return checkCall('kind', 'function|string', kind, options);
}
/**
* Crawls environment objects logging all object properties whose values
* are of a specified constructor instance, `[[Class]]`, or type.
*
* @memberOf spotlight
* @param {Function|string} kind The constructor, `[[Class]]`, or type to check against.
* @param {Object} [options={}] The options object.
* @example
*
* // by constructor
* spotlight.byKind(jQuery);
*
* // or by `[[Class]]`
* spotlight.byKind('RegExp');
*
* // or by type
* spotlight.byKind('undefined');
*
* // or special kind "constructor"
* spotlight.byKind('constructor');
*/
function byKind(kind, options) {
return checkCall('kind', 'function|string', kind, options);
}
/**
* Crawls environment objects logging all object properties of the specified name.
* @memberOf spotlight
* @param {String} name The property name to search for.
* @param {Object} [options={}] The options object.
* @example
*
* // basic
* // > window.length -> (number) 0
* spotlight.byName('length');
*
* // or with options
* // (finds all "map" properties on jQuery)
* // > $.map -> (function) function(a,b,c){...}
* // > $.fn.map -> (function) function(a){...}
* spotlight.byName('map', { 'object': jQuery, 'path': '$' });
*/
function byName(name, options) {
return checkCall('name', 'string', name, options);
}
/**
* Crawls environment objects logging all object properties of the specified name.
*
* @memberOf spotlight
* @param {string} name The property name to search for.
* @param {Object} [options={}] The options object.
* @example
*
* // basic
* spotlight.byName('length');
* // => window.length -> (number) 0
*
* // or with options
* // (finds all "map" properties on jQuery)
* spotlight.byName('map', { 'object': jQuery, 'path': '$' });
* // => $.map -> (function) function(a,b,c){...}
* // => $.fn.map -> (function) function(a){...}
*/
function byName(name, options) {
return checkCall('name', 'string', name, options);
}
/**
* Crawls environment objects logging all object properties whose values are
* a strict match for the specified value.
* @memberOf spotlight
* @param {Mixed} value The value to search for.
* @param {Object} [options={}] The options object.
* @example
*
* // basic
* // > window.pageXOffset -> (number) 0
* // > window.screenX -> (number) 0
* // > window.length -> (number) 0
* spotlight.byValue(0);
*/
function byValue(value, options) {
return checkCall('value', null, value, options);
}
/**
* Crawls environment objects logging all object properties whose values are
* a strict match for the specified value.
*
* @memberOf spotlight
* @param {*} value The value to search for.
* @param {Object} [options={}] The options object.
* @example
*
* // basic
* spotlight.byValue(0);
* // => window.pageXOffset -> (number) 0
* // => window.screenX -> (number) 0
* // => window.length -> (number) 0
*/
function byValue(value, options) {
return checkCall('value', null, value, options);
}
/**
* Crawls environment objects executing `callback`, passing the current
* `value`, `key`, and `object` as arguments, against each object encountered
* and logs properties for which `callback` returns true.
* @memberOf spotlight
* @param {Function} callback A function executed per object.
* @param {Object} [options={}] The options object.
* @example
*
* // filter by property names containing "oo"
* spotlight.custom(function(value, key) { return key.indexOf('oo') > -1; });
*
* // or filter by falsey values
* spotlight.custom(function(value) { return !value; });
*/
function custom(callback, options) {
return checkCall('custom', 'function', callback, options);
}
/**
* Crawls environment objects executing `callback`, passing the current
* `value`, `key`, and `object` as arguments, against each object encountered
* and logs properties for which `callback` returns true.
*
* @memberOf spotlight
* @param {Function} callback A function executed per object.
* @param {Object} [options={}] The options object.
* @example
*
* // filter by property names containing "oo"
* spotlight.custom(function(value, key) { return key.indexOf('oo') > -1; });
*
* // or filter by falsey values
* spotlight.custom(function(value) { return !value; });
*/
function custom(callback, options) {
return checkCall('custom', 'function', callback, options);
}
/*--------------------------------------------------------------------------*/
/**
* The primary namespace.
* @type Object
*/
var spotlight = {
/**
* A flag to indicate that methods will execute in debug mode.
* This function enables or disables debug mode for all `spotlight` methods.
*
* @memberOf spotlight
* @type Boolean
* @param {boolean} value The flag value.
* @example
*
* spotlight.debug(true);
* spotlight.byName('length');
* // => [['window.length -> (number)', 0]]
*/
'debug': false,
function debug(value) {
isDebug = !!value;
}
// searches for props by constructor instance, type, or [[Class]]
'byKind': byKind,
/*------------------------------------------------------------------------*/
// searches for props by name
'byName': byName,
/**
* The primary namespace.
*
* @type Object
* @name spotlight
*/
var spotlight = {};
// searches for props by strict value matches
'byValue': byValue,
/**
* The semantic version number.
*
* @static
* @memberOf spotlight
* @type string
*/
spotlight.version = '1.0.0';
// executes a custom function per object
'custom': custom
};
spotlight.byKind = byKind;
spotlight.byName = byName;
spotlight.byValue = byValue;
spotlight.custom = custom;
spotlight.debug = debug;
spotlight.runInContext = runInContext;
/*--------------------------------------------------------------------------*/
// mod `defaultRoots` for server-side environments
// for Narwhal, Node.js, or RingoJS
if (freeExports && freeGlobal) {
defaultRoots = [
{ 'object': freeExports, 'path': 'exports' },
{ 'object': freeGlobal, 'path': 'global' }
];
return spotlight;
}
// for Rhino
else if (getKindOf(window.environment) == 'Environment') {
defaultRoots[0].path = '<global object>';
}
/*--------------------------------------------------------------------------*/
// expose spotlight
// in Narwhal, Node.js, or RingoJS
if (freeExports) {
forOwn(spotlight, function(value, key) {
freeExports[key] = value;
});
// assign `exports` to `spotlight` so we can detect changes to the `debug` flag
spotlight = freeExports;
// export spotlight
var spotlight = runInContext();
// some AMD build optimizers like r.js check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// define as an anonymous module so, through path mapping, it can be aliased
define(spotlight);
}
// via curl.js or RequireJS
else if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
define('spotlight', spotlight);
// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports && freeModule) {
// in Narwhal, Node.js, Rhino -require, or RingoJS
freeExports.byKind = spotlight.byKind;
freeExports.byName = spotlight.byName;
freeExports.byValue = spotlight.byValue;
freeExports.custom = spotlight.custom;
freeExports.debug = spotlight.debug;
freeExports.runInContext = spotlight.runInContext;
freeExports.version = spotlight.version;
}
// in a browser or Rhino
else {
// use square bracket notation so Closure Compiler won't munge `spotlight`
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
window['spotlight'] = spotlight;
// in a browser or Rhino
root.spotlight = spotlight;
}
}(this));
}.call(this));
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc