86 lines
1.4 KiB
JavaScript
86 lines
1.4 KiB
JavaScript
/**
|
|
* Global Names
|
|
*/
|
|
|
|
var globals = /\b(Array|Date|Object|Math|JSON)\b/g;
|
|
|
|
/**
|
|
* Return immediate identifiers parsed from `str`.
|
|
*
|
|
* @param {String} str
|
|
* @param {String|Function} map function or prefix
|
|
* @return {Array}
|
|
* @api public
|
|
*/
|
|
|
|
module.exports = function(str, fn){
|
|
var p = unique(props(str));
|
|
if (fn && 'string' == typeof fn) fn = prefixed(fn);
|
|
if (fn) return map(str, p, fn);
|
|
return p;
|
|
};
|
|
|
|
/**
|
|
* Return immediate identifiers in `str`.
|
|
*
|
|
* @param {String} str
|
|
* @return {Array}
|
|
* @api private
|
|
*/
|
|
|
|
function props(str) {
|
|
return str
|
|
.replace(/\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\//g, '')
|
|
.replace(globals, '')
|
|
.match(/[a-zA-Z_]\w*/g)
|
|
|| [];
|
|
}
|
|
|
|
/**
|
|
* Return `str` with `props` mapped with `fn`.
|
|
*
|
|
* @param {String} str
|
|
* @param {Array} props
|
|
* @param {Function} fn
|
|
* @return {String}
|
|
* @api private
|
|
*/
|
|
|
|
function map(str, props, fn) {
|
|
var re = /\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\/|[a-zA-Z_]\w*/g;
|
|
return str.replace(re, function(_){
|
|
if ('(' == _[_.length - 1]) return fn(_);
|
|
if (!~props.indexOf(_)) return _;
|
|
return fn(_);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Return unique array.
|
|
*
|
|
* @param {Array} arr
|
|
* @return {Array}
|
|
* @api private
|
|
*/
|
|
|
|
function unique(arr) {
|
|
var ret = [];
|
|
|
|
for (var i = 0; i < arr.length; i++) {
|
|
if (~ret.indexOf(arr[i])) continue;
|
|
ret.push(arr[i]);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Map with prefix `str`.
|
|
*/
|
|
|
|
function prefixed(str) {
|
|
return function(_){
|
|
return str + _;
|
|
};
|
|
}
|