diff --git a/doc/UTIL_API.md b/doc/UTIL_API.md
index 5d324bf..63a710a 100644
--- a/doc/UTIL_API.md
+++ b/doc/UTIL_API.md
@@ -506,6 +506,52 @@ $test.find('.test').each(function (idx, element) {
});
```
+## Stack
+
+Stack data structure.
+
+### clear
+
+Clear the stack.
+
+### push
+
+Add an item to the stack.
+
+|Name |Type |Desc |
+|------|------|------------|
+|item |* |Item to add |
+|return|number|Current size|
+
+### pop
+
+Get the last item of the stack.
+
+### peek
+
+Get the last item without removing it.
+
+### forEach
+
+Iterate over the stack.
+
+|Name |Type |Desc |
+|--------|--------|--------------------------|
+|iterator|function|Function invoked iteration|
+|[ctx] |* |Function context |
+
+### toArr
+
+Convert the stack to a JavaScript array.
+
+```javascript
+const stack = new Stack();
+
+stack.push(2); // -> 1
+stack.push(3); // -> 2
+stack.pop(); // -> 3
+```
+
## Store
Memory storage.
@@ -1317,8 +1363,8 @@ comment, string, number, keyword, operator
```javascript
highlight('const a = 5;', 'js', {
- number: 'color:#0086b3;'
-}); // -> 'const a = 5;'
+ keyword: 'color:#569cd6;'
+}); // -> 'const a = 5;'
```
## identity
@@ -1650,6 +1696,21 @@ isObj({}); // -> true
isObj([]); // -> true
```
+## isPrimitive
+
+Check if value is string, number, boolean or null.
+
+|Name |Type |Desc |
+|------|-------|----------------------------|
+|val |* |Value to check |
+|return|boolean|True if value is a primitive|
+
+```javascript
+isPrimitive(5); // -> true
+isPrimitive('abc'); // -> true
+isPrimitive(false); // -> true
+```
+
## isPromise
Check if value looks like a promise.
diff --git a/src/Console/Log.js b/src/Console/Log.js
index 972b89f..93e16a6 100644
--- a/src/Console/Log.js
+++ b/src/Console/Log.js
@@ -6,6 +6,7 @@ import {
isObj,
isStr,
isErr,
+ isPrimitive,
wrap,
defaults,
dateFormat,
@@ -28,7 +29,8 @@ import {
highlight,
each,
trim,
- lowerCase
+ lowerCase,
+ keys
} from '../lib/util'
export default class Log {
@@ -323,6 +325,8 @@ const getAbstract = wrap(origGetAbstract, function(fn, obj) {
})
})
+const Value = '__ErudaValue'
+
function formatTable(args) {
const table = args[0]
let ret = ''
@@ -332,33 +336,39 @@ function formatTable(args) {
if (isStr(filter)) filter = toArr(filter)
if (!isArr(filter)) filter = null
- if (!isArr(table)) return formatMsg(args)
+ if (!isObj(table)) return formatMsg(args)
- table.forEach(val => {
- if (!isObj(val)) return
- columns = columns.concat(Object.getOwnPropertyNames(val))
+ each(table, val => {
+ if (isPrimitive(val)) {
+ columns.push(Value)
+ } else if (isObj(val)) {
+ columns = columns.concat(keys(val))
+ }
})
columns = unique(columns)
columns.sort()
if (filter) columns = columns.filter(val => contain(filter, val))
+ if (columns.length > 20) columns = columns.slice(0, 20)
if (isEmpty(columns)) return formatMsg(args)
ret += '
| (index) | '
- columns.forEach(val => (ret += `${val} | `))
+ columns.forEach(
+ val => (ret += `${val === Value ? 'Value' : toStr(val)} | `)
+ )
ret += '
'
- table.forEach((obj, idx) => {
- if (!isObj(obj)) return
+ each(table, (obj, idx) => {
ret += `| ${idx} | `
columns.forEach(column => {
- let val = obj[column]
- if (isUndef(val)) {
- val = ''
- } else if (isObj(val)) {
- val = getObjType(val)
+ if (isObj(obj)) {
+ ret +=
+ column === Value
+ ? ' | '
+ : `${formatTableVal(obj[column])} | `
+ } else if (isPrimitive(obj)) {
+ ret +=
+ column === Value ? `${formatTableVal(obj)} | ` : ' | '
}
-
- ret += `${val} | `
})
ret += '
'
})
@@ -369,6 +379,13 @@ function formatTable(args) {
return ret
}
+function formatTableVal(val) {
+ if (isObj(val)) return (val = '{…}')
+ if (isPrimitive(val)) return getAbstract(val)
+
+ return toStr(val)
+}
+
const regJsUrl = /https?:\/\/([0-9.\-A-Za-z]+)(?::(\d+))?\/[A-Z.a-z0-9/]*\.js/g
const regErudaJs = /eruda(\.min)?\.js/
diff --git a/src/lib/util.js b/src/lib/util.js
index 6f010b6..fdca8f1 100644
--- a/src/lib/util.js
+++ b/src/lib/util.js
@@ -2596,6 +2596,34 @@ export var isNull = _.isNull = (function (exports) {
return exports;
})({});
+/* ------------------------------ isPrimitive ------------------------------ */
+
+export var isPrimitive = _.isPrimitive = (function (exports) {
+ /* Check if value is string, number, boolean or null.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|----------------------------|
+ * |val |* |Value to check |
+ * |return|boolean|True if value is a primitive|
+ */
+
+ /* example
+ * isPrimitive(5); // -> true
+ * isPrimitive('abc'); // -> true
+ * isPrimitive(false); // -> true
+ */
+
+ /* typescript
+ * export declare function isPrimitive(val: any): boolean;
+ */
+ exports = function(val) {
+ var type = typeof val;
+ return val == null || (type !== 'function' && type !== 'object');
+ };
+
+ return exports;
+})({});
+
/* ------------------------------ isPromise ------------------------------ */
export var isPromise = _.isPromise = (function (exports) {
diff --git a/test/util.js b/test/util.js
index f66777f..14fe619 100644
--- a/test/util.js
+++ b/test/util.js
@@ -16,6 +16,50 @@
if (typeof window === 'object' && window.util) _ = window.util;
+ /* ------------------------------ inherits ------------------------------ */
+
+ var inherits = _.inherits = (function (exports) {
+ /* Inherit the prototype methods from one constructor into another.
+ *
+ * |Name |Type |Desc |
+ * |----------|--------|-----------|
+ * |Class |function|Child Class|
+ * |SuperClass|function|Super Class|
+ */
+
+ /* example
+ * function People(name) {
+ * this._name = name;
+ * }
+ * People.prototype = {
+ * getName: function () {
+ * return this._name;
+ * }
+ * };
+ * function Student(name) {
+ * this._name = name;
+ * }
+ * inherits(Student, People);
+ * const s = new Student('RedHood');
+ * s.getName(); // -> 'RedHood'
+ */
+
+ /* typescript
+ * export declare function inherits(Class: Function, SuperClass: Function): void;
+ */
+ exports = function(Class, SuperClass) {
+ if (objCreate) return (Class.prototype = objCreate(SuperClass.prototype));
+ noop.prototype = SuperClass.prototype;
+ Class.prototype = new noop();
+ };
+
+ var objCreate = Object.create;
+
+ function noop() {}
+
+ return exports;
+ })({});
+
/* ------------------------------ noop ------------------------------ */
var noop = _.noop = (function (exports) {
@@ -63,6 +107,61 @@
return exports;
})({});
+ /* ------------------------------ has ------------------------------ */
+
+ var has = _.has = (function (exports) {
+ /* Checks if key is a direct property.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|--------------------------------|
+ * |obj |object |Object to query |
+ * |key |string |Path to check |
+ * |return|boolean|True if key is a direct property|
+ */
+
+ /* example
+ * has({one: 1}, 'one'); // -> true
+ */
+
+ /* typescript
+ * export declare function has(obj: {}, key: string): boolean;
+ */
+ var hasOwnProp = Object.prototype.hasOwnProperty;
+
+ exports = function(obj, key) {
+ return hasOwnProp.call(obj, key);
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ idxOf ------------------------------ */
+
+ var idxOf = _.idxOf = (function (exports) {
+ /* Get the index at which the first occurrence of value.
+ *
+ * |Name |Type |Desc |
+ * |---------|------|--------------------|
+ * |arr |array |Array to search |
+ * |val |* |Value to search for |
+ * |fromIdx=0|number|Index to search from|
+ * |return |number|Value index |
+ */
+
+ /* example
+ * idxOf([1, 2, 1, 2], 2, 2); // -> 3
+ */
+
+ /* typescript
+ * export declare function idxOf(arr: any[], val: any, fromIdx?: number): number;
+ */
+ exports = function(arr, val, fromIdx) {
+ return Array.prototype.indexOf.call(arr, val, fromIdx);
+ };
+
+ return exports;
+ })({});
+
/* ------------------------------ isUndef ------------------------------ */
var isUndef = _.isUndef = (function (exports) {
@@ -354,6 +453,62 @@
return exports;
})({});
+ /* ------------------------------ restArgs ------------------------------ */
+
+ var restArgs = _.restArgs = (function (exports) {
+ /* This accumulates the arguments passed into an array, after a given index.
+ *
+ * |Name |Type |Desc |
+ * |------------|--------|---------------------------------------|
+ * |function |function|Function that needs rest parameters |
+ * |[startIndex]|number |The start index to accumulates |
+ * |return |function|Generated function with rest parameters|
+ */
+
+ /* example
+ * const paramArr = restArgs(function (rest) { return rest });
+ * paramArr(1, 2, 3, 4); // -> [1, 2, 3, 4]
+ */
+
+ /* typescript
+ * export declare function restArgs(fn: Function, startIndex?: number): Function;
+ */
+ exports = function(fn, startIdx) {
+ startIdx = startIdx == null ? fn.length - 1 : +startIdx;
+ return function() {
+ var len = Math.max(arguments.length - startIdx, 0);
+ var rest = new Array(len);
+ var i;
+
+ for (i = 0; i < len; i++) {
+ rest[i] = arguments[i + startIdx];
+ } // Call runs faster than apply.
+
+ switch (startIdx) {
+ case 0:
+ return fn.call(this, rest);
+
+ case 1:
+ return fn.call(this, arguments[0], rest);
+
+ case 2:
+ return fn.call(this, arguments[0], arguments[1], rest);
+ }
+
+ var args = new Array(startIdx + 1);
+
+ for (i = 0; i < startIdx; i++) {
+ args[i] = arguments[i];
+ }
+
+ args[startIdx] = rest;
+ return fn.apply(this, args);
+ };
+ };
+
+ return exports;
+ })({});
+
/* ------------------------------ optimizeCb ------------------------------ */
var optimizeCb = _.optimizeCb = (function (exports) {
@@ -432,6 +587,33 @@
return exports;
})({});
+ /* ------------------------------ endWith ------------------------------ */
+
+ var endWith = _.endWith = (function (exports) {
+ /* Check if string ends with the given target string.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|-------------------------------|
+ * |str |string |The string to search |
+ * |suffix|string |String suffix |
+ * |return|boolean|True if string ends with target|
+ */
+
+ /* example
+ * endWith('ab', 'b'); // -> true
+ */
+
+ /* typescript
+ * export declare function endWith(str: string, suffix: string): boolean;
+ */
+ exports = function(str, suffix) {
+ var idx = str.length - suffix.length;
+ return idx >= 0 && str.indexOf(suffix, idx) === idx;
+ };
+
+ return exports;
+ })({});
+
/* ------------------------------ toStr ------------------------------ */
var toStr = _.toStr = (function (exports) {
@@ -460,31 +642,58 @@
return exports;
})({});
- /* ------------------------------ has ------------------------------ */
+ /* ------------------------------ escapeJsStr ------------------------------ */
- var has = _.has = (function (exports) {
- /* Checks if key is a direct property.
+ var escapeJsStr = _.escapeJsStr = (function (exports) {
+ /* Escape string to be a valid JavaScript string literal between quotes.
*
- * |Name |Type |Desc |
- * |------|-------|--------------------------------|
- * |obj |object |Object to query |
- * |key |string |Path to check |
- * |return|boolean|True if key is a direct property|
+ * http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
+ *
+ * |Name |Type |Desc |
+ * |------|------|----------------|
+ * |str |string|String to escape|
+ * |return|string|Escaped string |
*/
/* example
- * has({one: 1}, 'one'); // -> true
+ * escapeJsStr('\"\n'); // -> '\\"\\\\n'
*/
/* typescript
- * export declare function has(obj: {}, key: string): boolean;
+ * export declare function escapeJsStr(str: string): string;
*/
- var hasOwnProp = Object.prototype.hasOwnProperty;
- exports = function(obj, key) {
- return hasOwnProp.call(obj, key);
+ /* dependencies
+ * toStr
+ */
+
+ exports = function(str) {
+ return toStr(str).replace(regEscapeChars, function(char) {
+ switch (char) {
+ case '"':
+ case "'":
+ case '\\':
+ return '\\' + char;
+
+ case '\n':
+ return '\\n';
+
+ case '\r':
+ return '\\r';
+ // Line separator
+
+ case '\u2028':
+ return '\\u2028';
+ // Paragraph separator
+
+ case '\u2029':
+ return '\\u2029';
+ }
+ });
};
+ var regEscapeChars = /["'\\\n\r\u2028\u2029]/g;
+
return exports;
})({});
@@ -572,6 +781,169 @@
return exports;
})({});
+ /* ------------------------------ isArr ------------------------------ */
+
+ var isArr = _.isArr = (function (exports) {
+ /* Check if value is an `Array` object.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|----------------------------------|
+ * |val |* |Value to check |
+ * |return|boolean|True if value is an `Array` object|
+ */
+
+ /* example
+ * isArr([]); // -> true
+ * isArr({}); // -> false
+ */
+
+ /* typescript
+ * export declare function isArr(val: any): boolean;
+ */
+
+ /* dependencies
+ * objToStr
+ */
+
+ exports =
+ Array.isArray ||
+ function(val) {
+ return objToStr(val) === '[object Array]';
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ castPath ------------------------------ */
+
+ var castPath = _.castPath = (function (exports) {
+ /* Cast value into a property path array.
+ *
+ * |Name |Type |Desc |
+ * |------|------------|-------------------|
+ * |path |string array|Value to inspect |
+ * |[obj] |object |Object to query |
+ * |return|array |Property path array|
+ */
+
+ /* example
+ * castPath('a.b.c'); // -> ['a', 'b', 'c']
+ * castPath(['a']); // -> ['a']
+ * castPath('a[0].b'); // -> ['a', '0', 'b']
+ * castPath('a.b.c', {'a.b.c': true}); // -> ['a.b.c']
+ */
+
+ /* typescript
+ * export declare function castPath(path: string | string[], obj?: any): string[];
+ */
+
+ /* dependencies
+ * has isArr
+ */
+
+ exports = function(str, obj) {
+ if (isArr(str)) return str;
+ if (obj && has(obj, str)) return [str];
+ var ret = [];
+ str.replace(regPropName, function(match, number, quote, str) {
+ ret.push(quote ? str.replace(regEscapeChar, '$1') : number || match);
+ });
+ return ret;
+ }; // Lodash _stringToPath
+
+ var regPropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
+ var regEscapeChar = /\\(\\)?/g;
+
+ return exports;
+ })({});
+
+ /* ------------------------------ safeGet ------------------------------ */
+
+ var safeGet = _.safeGet = (function (exports) {
+ /* Get object property, don't throw undefined error.
+ *
+ * |Name |Type |Desc |
+ * |------|------------|-------------------------|
+ * |obj |object |Object to query |
+ * |path |array string|Path of property to get |
+ * |return|* |Target value or undefined|
+ */
+
+ /* example
+ * const obj = {a: {aa: {aaa: 1}}};
+ * safeGet(obj, 'a.aa.aaa'); // -> 1
+ * safeGet(obj, ['a', 'aa']); // -> {aaa: 1}
+ * safeGet(obj, 'a.b'); // -> undefined
+ */
+
+ /* typescript
+ * export declare function safeGet(obj: any, path: string | string[]): any;
+ */
+
+ /* dependencies
+ * isUndef castPath
+ */
+
+ exports = function(obj, path) {
+ path = castPath(path, obj);
+ var prop;
+ prop = path.shift();
+
+ while (!isUndef(prop)) {
+ obj = obj[prop];
+ if (obj == null) return;
+ prop = path.shift();
+ }
+
+ return obj;
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ flatten ------------------------------ */
+
+ var flatten = _.flatten = (function (exports) {
+ /* Recursively flatten an array.
+ *
+ * |Name |Type |Desc |
+ * |------|-----|-------------------|
+ * |arr |array|Array to flatten |
+ * |return|array|New flattened array|
+ */
+
+ /* example
+ * flatten(['a', ['b', ['c']], 'd', ['e']]); // -> ['a', 'b', 'c', 'd', 'e']
+ */
+
+ /* typescript
+ * export declare function flatten(arr: any[]): any[];
+ */
+
+ /* dependencies
+ * isArr
+ */
+
+ exports = function(arr) {
+ return flat(arr, []);
+ };
+
+ function flat(arr, res) {
+ var len = arr.length,
+ i = -1,
+ cur;
+
+ while (len--) {
+ cur = arr[++i];
+ isArr(cur) ? flat(cur, res) : res.push(cur);
+ }
+
+ return res;
+ }
+
+ return exports;
+ })({});
+
/* ------------------------------ isFn ------------------------------ */
var isFn = _.isFn = (function (exports) {
@@ -651,6 +1023,30 @@
return exports;
})({});
+ /* ------------------------------ isMiniProgram ------------------------------ */
+
+ var isMiniProgram = _.isMiniProgram = (function (exports) {
+ /* Check if running in wechat mini program.
+ */
+
+ /* example
+ * console.log(isMiniProgram); // -> true if running in mini program.
+ */
+
+ /* typescript
+ * export declare const isMiniProgram: boolean;
+ */
+
+ /* dependencies
+ * isFn
+ */
+ /* eslint-disable no-undef */
+
+ exports = typeof wx !== 'undefined' && isFn(wx.openLocation);
+
+ return exports;
+ })({});
+
/* ------------------------------ isNum ------------------------------ */
var isNum = _.isNum = (function (exports) {
@@ -721,35 +1117,32 @@
return exports;
})({});
- /* ------------------------------ isArr ------------------------------ */
+ /* ------------------------------ isStr ------------------------------ */
- var isArr = _.isArr = (function (exports) {
- /* Check if value is an `Array` object.
+ var isStr = _.isStr = (function (exports) {
+ /* Check if value is a string primitive.
*
- * |Name |Type |Desc |
- * |------|-------|----------------------------------|
- * |val |* |Value to check |
- * |return|boolean|True if value is an `Array` object|
+ * |Name |Type |Desc |
+ * |------|-------|-----------------------------------|
+ * |val |* |Value to check |
+ * |return|boolean|True if value is a string primitive|
*/
/* example
- * isArr([]); // -> true
- * isArr({}); // -> false
+ * isStr('licia'); // -> true
*/
/* typescript
- * export declare function isArr(val: any): boolean;
+ * export declare function isStr(val: any): boolean;
*/
/* dependencies
* objToStr
*/
- exports =
- Array.isArray ||
- function(val) {
- return objToStr(val) === '[object Array]';
- };
+ exports = function(val) {
+ return objToStr(val) === '[object String]';
+ };
return exports;
})({});
@@ -958,6 +1351,78 @@
return exports;
})({});
+ /* ------------------------------ values ------------------------------ */
+
+ var values = _.values = (function (exports) {
+ /* Create an array of the own enumerable property values of object.
+ *
+ * |Name |Type |Desc |
+ * |------|------|------------------------|
+ * |obj |object|Object to query |
+ * |return|array |Array of property values|
+ */
+
+ /* example
+ * values({one: 1, two: 2}); // -> [1, 2]
+ */
+
+ /* typescript
+ * export declare function values(obj: any): any[];
+ */
+
+ /* dependencies
+ * each
+ */
+
+ exports = function(obj) {
+ var ret = [];
+ each(obj, function(val) {
+ ret.push(val);
+ });
+ return ret;
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ contain ------------------------------ */
+
+ var contain = _.contain = (function (exports) {
+ /* Check if the value is present in the list.
+ *
+ * |Name |Type |Desc |
+ * |------|-------------------|------------------------------------|
+ * |target|array object string|Target object |
+ * |value |* |Value to check |
+ * |return|boolean |True if value is present in the list|
+ */
+
+ /* example
+ * contain([1, 2, 3], 1); // -> true
+ * contain({a: 1, b: 2}, 1); // -> true
+ * contain('abc', 'a'); // -> true
+ */
+
+ /* typescript
+ * export declare function contain(
+ * arr: any[] | {} | string,
+ * val: any
+ * ): boolean;
+ */
+
+ /* dependencies
+ * idxOf isStr isArrLike values
+ */
+
+ exports = function(arr, val) {
+ if (isStr(arr)) return arr.indexOf(val) > -1;
+ if (!isArrLike(arr)) arr = values(arr);
+ return idxOf(arr, val) >= 0;
+ };
+
+ return exports;
+ })({});
+
/* ------------------------------ extendOwn ------------------------------ */
var extendOwn = _.extendOwn = (function (exports) {
@@ -987,36 +1452,6 @@
return exports;
})({});
- /* ------------------------------ isStr ------------------------------ */
-
- var isStr = _.isStr = (function (exports) {
- /* Check if value is a string primitive.
- *
- * |Name |Type |Desc |
- * |------|-------|-----------------------------------|
- * |val |* |Value to check |
- * |return|boolean|True if value is a string primitive|
- */
-
- /* example
- * isStr('licia'); // -> true
- */
-
- /* typescript
- * export declare function isStr(val: any): boolean;
- */
-
- /* dependencies
- * objToStr
- */
-
- exports = function(val) {
- return objToStr(val) === '[object String]';
- };
-
- return exports;
- })({});
-
/* ------------------------------ isEmpty ------------------------------ */
var isEmpty = _.isEmpty = (function (exports) {
@@ -1097,6 +1532,100 @@
return exports;
})({});
+ /* ------------------------------ isNaN ------------------------------ */
+
+ var isNaN = _.isNaN = (function (exports) {
+ /* Check if value is an NaN.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|-----------------------|
+ * |val |* |Value to check |
+ * |return|boolean|True if value is an NaN|
+ *
+ * Undefined is not an NaN, different from global isNaN function.
+ */
+
+ /* example
+ * isNaN(0); // -> false
+ * isNaN(NaN); // -> true
+ */
+
+ /* typescript
+ * export declare function isNaN(val: any): boolean;
+ */
+
+ /* dependencies
+ * isNum
+ */
+
+ exports = function(val) {
+ return isNum(val) && val !== +val;
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ isNil ------------------------------ */
+
+ var isNil = _.isNil = (function (exports) {
+ /* Check if value is null or undefined, the same as value == null.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|----------------------------------|
+ * |val |* |Value to check |
+ * |return|boolean|True if value is null or undefined|
+ */
+
+ /* example
+ * isNil(null); // -> true
+ * isNil(void 0); // -> true
+ * isNil(undefined); // -> true
+ * isNil(false); // -> false
+ * isNil(0); // -> false
+ * isNil([]); // -> false
+ */
+
+ /* typescript
+ * export declare function isNil(val: any): boolean;
+ */
+ exports = function(val) {
+ return val == null;
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ isPromise ------------------------------ */
+
+ var isPromise = _.isPromise = (function (exports) {
+ /* Check if value looks like a promise.
+ *
+ * |Name |Type |Desc |
+ * |------|-------|----------------------------------|
+ * |val |* |Value to check |
+ * |return|boolean|True if value looks like a promise|
+ */
+
+ /* example
+ * isPromise(new Promise(function () {})); // -> true
+ * isPromise({}); // -> false
+ */
+
+ /* typescript
+ * export declare function isPromise(val: any): boolean;
+ */
+
+ /* dependencies
+ * isObj isFn
+ */
+
+ exports = function(val) {
+ return isObj(val) && isFn(val.then);
+ };
+
+ return exports;
+ })({});
+
/* ------------------------------ ltrim ------------------------------ */
var ltrim = _.ltrim = (function (exports) {
@@ -1266,6 +1795,40 @@
return exports;
})({});
+ /* ------------------------------ difference ------------------------------ */
+
+ var difference = _.difference = (function (exports) {
+ /* Create an array of unique array values not included in the other given array.
+ *
+ * |Name |Type |Desc |
+ * |---------|-----|----------------------------|
+ * |arr |array|Array to inspect |
+ * |[...rest]|array|Values to exclude |
+ * |return |array|New array of filtered values|
+ */
+
+ /* example
+ * difference([3, 2, 1], [4, 2]); // -> [3, 1]
+ */
+
+ /* typescript
+ * export declare function difference(arr: any[], ...rest: any[]): any[];
+ */
+
+ /* dependencies
+ * restArgs flatten filter contain
+ */
+
+ exports = restArgs(function(arr, rest) {
+ rest = flatten(rest);
+ return filter(arr, function(val) {
+ return !contain(rest, val);
+ });
+ });
+
+ return exports;
+ })({});
+
/* ------------------------------ evalCss ------------------------------ */
_.evalCss = (function (exports) {
/* Eval css.
@@ -1496,6 +2059,35 @@
return exports;
})({});
+ /* ------------------------------ extend ------------------------------ */
+
+ var extend = _.extend = (function (exports) {
+ /* Copy all of the properties in the source objects over to the destination object.
+ *
+ * |Name |Type |Desc |
+ * |-----------|------|------------------|
+ * |destination|object|Destination object|
+ * |...sources |object|Sources objects |
+ * |return |object|Destination object|
+ */
+
+ /* example
+ * extend({name: 'RedHood'}, {age: 24}); // -> {name: 'RedHood', age: 24}
+ */
+
+ /* typescript
+ * export declare function extend(destination: any, ...sources: any[]): any;
+ */
+
+ /* dependencies
+ * createAssigner allKeys
+ */
+
+ exports = createAssigner(allKeys);
+
+ return exports;
+ })({});
+
/* ------------------------------ map ------------------------------ */
var map = _.map = (function (exports) {
@@ -1736,6 +2328,198 @@
return exports;
})({});
+ /* ------------------------------ toArr ------------------------------ */
+
+ var toArr = _.toArr = (function (exports) {
+ /* Convert value to an array.
+ *
+ * |Name |Type |Desc |
+ * |------|-----|----------------|
+ * |val |* |Value to convert|
+ * |return|array|Converted array |
+ */
+
+ /* example
+ * toArr({a: 1, b: 2}); // -> [{a: 1, b: 2}]
+ * toArr('abc'); // -> ['abc']
+ * toArr(1); // -> [1]
+ * toArr(null); // -> []
+ */
+
+ /* typescript
+ * export declare function toArr(val: any): any[];
+ */
+
+ /* dependencies
+ * isArrLike map isArr isStr
+ */
+
+ exports = function(val) {
+ if (!val) return [];
+ if (isArr(val)) return val;
+ if (isArrLike(val) && !isStr(val)) return map(val);
+ return [val];
+ };
+
+ return exports;
+ })({});
+
+ /* ------------------------------ Class ------------------------------ */
+
+ var Class = _.Class = (function (exports) {
+ /* Create JavaScript class.
+ *
+ * |Name |Type |Desc |
+ * |---------|--------|---------------------------------|
+ * |methods |object |Public methods |
+ * |[statics]|object |Static methods |
+ * |return |function|Function used to create instances|
+ */
+
+ /* example
+ * const People = Class({
+ * initialize: function People(name, age) {
+ * this.name = name;
+ * this.age = age;
+ * },
+ * introduce: function () {
+ * return 'I am ' + this.name + ', ' + this.age + ' years old.';
+ * }
+ * });
+ *
+ * const Student = People.extend({
+ * initialize: function Student(name, age, school) {
+ * this.callSuper(People, 'initialize', arguments);
+ *
+ * this.school = school;
+ * },
+ * introduce: function () {
+ * return this.callSuper(People, 'introduce') + '\n I study at ' + this.school + '.';
+ * }
+ * }, {
+ * is: function (obj) {
+ * return obj instanceof Student;
+ * }
+ * });
+ *
+ * const a = new Student('allen', 17, 'Hogwarts');
+ * a.introduce(); // -> 'I am allen, 17 years old. \n I study at Hogwarts.'
+ * Student.is(a); // -> true
+ */
+
+ /* typescript
+ * export declare namespace Class {
+ * class Base {
+ * toString(): string;
+ * }
+ * class IConstructor extends Base {
+ * constructor(...args: any[]);
+ * static extend(methods: any, statics: any): IConstructor;
+ * static inherits(Class: Function): void;
+ * static methods(methods: any): IConstructor;
+ * static statics(statics: any): IConstructor;
+ * [method: string]: any;
+ * }
+ * }
+ * export declare function Class(methods: any, statics?: any): Class.IConstructor;
+ */
+
+ /* dependencies
+ * extend toArr inherits safeGet isMiniProgram
+ */
+
+ exports = function(methods, statics) {
+ return Base.extend(methods, statics);
+ };
+
+ function makeClass(parent, methods, statics) {
+ statics = statics || {};
+ var className =
+ methods.className || safeGet(methods, 'initialize.name') || '';
+ delete methods.className;
+ var ctor;
+
+ if (isMiniProgram) {
+ ctor = function() {
+ var args = toArr(arguments);
+ return this.initialize
+ ? this.initialize.apply(this, args) || this
+ : this;
+ };
+ } else {
+ ctor = new Function(
+ 'toArr',
+ 'return function ' +
+ className +
+ '()' +
+ '{' +
+ 'var args = toArr(arguments);' +
+ 'return this.initialize ? this.initialize.apply(this, args) || this : this;' +
+ '};'
+ )(toArr);
+ }
+
+ inherits(ctor, parent);
+ ctor.prototype.constructor = ctor;
+
+ ctor.extend = function(methods, statics) {
+ return makeClass(ctor, methods, statics);
+ };
+
+ ctor.inherits = function(Class) {
+ inherits(ctor, Class);
+ };
+
+ ctor.methods = function(methods) {
+ extend(ctor.prototype, methods);
+ return ctor;
+ };
+
+ ctor.statics = function(statics) {
+ extend(ctor, statics);
+ return ctor;
+ };
+
+ ctor.methods(methods).statics(statics);
+ return ctor;
+ }
+
+ var Base = (exports.Base = makeClass(Object, {
+ className: 'Base',
+ callSuper: function(parent, name, args) {
+ var superMethod = parent.prototype[name];
+ return superMethod.apply(this, args);
+ },
+ toString: function() {
+ return this.constructor.name;
+ }
+ }));
+
+ return exports;
+ })({});
+
+ /* ------------------------------ now ------------------------------ */
+
+ var now = _.now = (function (exports) {
+ /* Gets the number of milliseconds that have elapsed since the Unix epoch.
+ */
+
+ /* example
+ * now(); // -> 1468826678701
+ */
+
+ /* typescript
+ * export declare function now(): number;
+ */
+ exports =
+ Date.now ||
+ function() {
+ return new Date().getTime();
+ };
+
+ return exports;
+ })({});
+
/* ------------------------------ rtrim ------------------------------ */
var rtrim = _.rtrim = (function (exports) {
@@ -2088,5 +2872,406 @@
return exports;
})({});
+ /* ------------------------------ type ------------------------------ */
+
+ var type = _.type = (function (exports) {
+ /* Determine the internal JavaScript [[Class]] of an object.
+ *
+ * |Name |Type |Desc |
+ * |--------------|-------|-----------------|
+ * |val |* |Value to get type|
+ * |lowerCase=true|boolean|LowerCase result |
+ * |return |string |Type of object |
+ */
+
+ /* example
+ * type(5); // -> 'number'
+ * type({}); // -> 'object'
+ * type(function () {}); // -> 'function'
+ * type([]); // -> 'array'
+ * type([], false); // -> 'Array'
+ * type(async function () {}, false); // -> 'AsyncFunction'
+ */
+
+ /* typescript
+ * export declare function type(val: any, lowerCase?: boolean): string;
+ */
+
+ /* dependencies
+ * objToStr isNaN
+ */
+
+ exports = function(val) {
+ var lowerCase =
+ arguments.length > 1 && arguments[1] !== undefined
+ ? arguments[1]
+ : true;
+ if (val === null) return lowerCase ? 'null' : 'Null';
+ if (val === undefined) return lowerCase ? 'undefined' : 'Undefined';
+ if (isNaN(val)) return lowerCase ? 'nan' : 'NaN';
+ var ret = objToStr(val).match(regObj);
+ if (!ret) return '';
+ return lowerCase ? ret[1].toLowerCase() : ret[1];
+ };
+
+ var regObj = /^\[object\s+(.*?)]$/;
+
+ return exports;
+ })({});
+
+ /* ------------------------------ toSrc ------------------------------ */
+
+ var toSrc = _.toSrc = (function (exports) {
+ /* Convert function to its source code.
+ *
+ * |Name |Type |Desc |
+ * |------|--------|-------------------|
+ * |fn |function|Function to convert|
+ * |return|string |Source code |
+ */
+
+ /* example
+ * toSrc(Math.min); // -> 'function min() { [native code] }'
+ * toSrc(function () {}) // -> 'function () { }'
+ */
+
+ /* typescript
+ * export declare function toSrc(fn: Function): string;
+ */
+
+ /* dependencies
+ * isNil
+ */
+
+ exports = function(fn) {
+ if (isNil(fn)) return '';
+
+ try {
+ return fnToStr.call(fn);
+ /* eslint-disable no-empty */
+ } catch (e) {}
+
+ try {
+ return fn + '';
+ /* eslint-disable no-empty */
+ } catch (e) {}
+
+ return '';
+ };
+
+ var fnToStr = Function.prototype.toString;
+
+ return exports;
+ })({});
+
+ /* ------------------------------ stringifyAll ------------------------------ */
+ _.stringifyAll = (function (exports) {
+ /* Stringify object into json with types.
+ *
+ * |Name |Type |Desc |
+ * |---------|------|-------------------|
+ * |obj |* |Object to stringify|
+ * |[options]|object|Stringify options |
+ * |return |string|Stringified object |
+ *
+ * Available options:
+ *
+ * |Name |Type |Desc |
+ * |------------------|-------|-------------------------|
+ * |unenumerable=false|boolean|Include unenumerable keys|
+ * |symbol=false |boolean|Include symbol keys |
+ * |accessGetter=false|boolean|Access getter value |
+ * |timeout=0 |number |Timeout of stringify |
+ * |depth=0 |number |Max depth of recursion |
+ * |[ignore] |array |Values to ignore |
+ *
+ * When time is out, all remaining values will all be "Timeout".
+ */
+
+ /* example
+ * stringifyAll(function test() {}); // -> '{"value":"function test() {}","type":"Function",...}'
+ */
+
+ /* typescript
+ * export declare namespace stringifyAll {
+ * interface IOptions {
+ * unenumerable?: boolean;
+ * symbol?: boolean;
+ * accessGetter?: boolean;
+ * timeout?: number;
+ * depth?: number;
+ * ignore?: any[];
+ * }
+ * }
+ * export declare function stringifyAll(
+ * obj: any,
+ * options?: stringifyAll.IOptions
+ * ): string;
+ */
+
+ /* dependencies
+ * escapeJsStr type toStr endWith toSrc keys each Class getProto difference extend isPromise filter now allKeys contain
+ */
+
+ exports = function(obj) {
+ var _ref =
+ arguments.length > 1 && arguments[1] !== undefined
+ ? arguments[1]
+ : {},
+ self = _ref.self,
+ _ref$startTime = _ref.startTime,
+ startTime = _ref$startTime === void 0 ? now() : _ref$startTime,
+ _ref$timeout = _ref.timeout,
+ timeout = _ref$timeout === void 0 ? 0 : _ref$timeout,
+ _ref$depth = _ref.depth,
+ depth = _ref$depth === void 0 ? 0 : _ref$depth,
+ _ref$curDepth = _ref.curDepth,
+ curDepth = _ref$curDepth === void 0 ? 1 : _ref$curDepth,
+ _ref$visitor = _ref.visitor,
+ visitor = _ref$visitor === void 0 ? new Visitor() : _ref$visitor,
+ _ref$unenumerable = _ref.unenumerable,
+ unenumerable = _ref$unenumerable === void 0 ? false : _ref$unenumerable,
+ _ref$symbol = _ref.symbol,
+ symbol = _ref$symbol === void 0 ? false : _ref$symbol,
+ _ref$accessGetter = _ref.accessGetter,
+ accessGetter = _ref$accessGetter === void 0 ? false : _ref$accessGetter,
+ _ref$ignore = _ref.ignore,
+ ignore = _ref$ignore === void 0 ? [] : _ref$ignore;
+
+ var json = '';
+ var options = {
+ visitor: visitor,
+ unenumerable: unenumerable,
+ symbol: symbol,
+ accessGetter: accessGetter,
+ depth: depth,
+ curDepth: curDepth + 1,
+ timeout: timeout,
+ startTime: startTime,
+ ignore: ignore
+ };
+ var t = type(obj, false);
+
+ if (t === 'String') {
+ json = wrapStr(obj);
+ } else if (t === 'Number') {
+ json = toStr(obj);
+
+ if (endWith(json, 'Infinity')) {
+ json = '{"value":"'.concat(json, '","type":"Number"}');
+ }
+ } else if (t === 'NaN') {
+ json = '{"value":"NaN","type":"Number"}';
+ } else if (t === 'Boolean') {
+ json = obj ? 'true' : 'false';
+ } else if (t === 'Null') {
+ json = 'null';
+ } else if (t === 'Undefined') {
+ json = '{"type":"Undefined"}';
+ } else if (t === 'Symbol') {
+ var val = 'Symbol';
+
+ try {
+ val = toStr(obj);
+ /* eslint-disable no-empty */
+ } catch (e) {}
+
+ json = '{"value":'.concat(wrapStr(val), ',"type":"Symbol"}');
+ } else {
+ if (timeout && now() - startTime > timeout) {
+ return wrapStr('Timeout');
+ }
+
+ if (depth && curDepth > depth) {
+ return wrapStr('{...}');
+ }
+
+ json = '{';
+ var parts = [];
+ var visitedObj = visitor.get(obj);
+ var id;
+
+ if (visitedObj) {
+ id = visitedObj.id;
+ parts.push('"reference":'.concat(id));
+ } else {
+ id = visitor.set(obj);
+ parts.push('"id":'.concat(id));
+ }
+
+ parts.push('"type":"'.concat(t, '"'));
+
+ if (endWith(t, 'Function')) {
+ parts.push('"value":'.concat(wrapStr(toSrc(obj))));
+ } else if (t === 'RegExp') {
+ parts.push('"value":'.concat(wrapStr(obj)));
+ }
+
+ if (!visitedObj) {
+ var enumerableKeys = keys(obj);
+
+ if (enumerableKeys.length) {
+ parts.push(
+ iterateObj(
+ 'enumerable',
+ enumerableKeys,
+ self || obj,
+ options
+ )
+ );
+ }
+
+ if (unenumerable) {
+ var unenumerableKeys = difference(
+ allKeys(obj, {
+ prototype: false,
+ unenumerable: true
+ }),
+ enumerableKeys
+ );
+
+ if (unenumerableKeys.length) {
+ parts.push(
+ iterateObj(
+ 'unenumerable',
+ unenumerableKeys,
+ self || obj,
+ options
+ )
+ );
+ }
+ }
+
+ if (symbol) {
+ var symbolKeys = filter(
+ allKeys(obj, {
+ prototype: false,
+ symbol: true
+ }),
+ function(key) {
+ return typeof key === 'symbol';
+ }
+ );
+
+ if (symbolKeys.length) {
+ parts.push(
+ iterateObj('symbol', symbolKeys, self || obj, options)
+ );
+ }
+ }
+
+ var prototype = getProto(obj);
+
+ if (prototype && !contain(ignore, prototype)) {
+ var proto = '"proto":'.concat(
+ exports(
+ prototype,
+ extend(options, {
+ self: self || obj
+ })
+ )
+ );
+ parts.push(proto);
+ }
+ }
+
+ json += parts.join(',') + '}';
+ }
+
+ return json;
+ };
+
+ function iterateObj(name, keys, obj, options) {
+ var parts = [];
+ each(keys, function(key) {
+ var val;
+ var descriptor = Object.getOwnPropertyDescriptor(obj, key);
+ var hasGetter = descriptor && descriptor.get;
+ var hasSetter = descriptor && descriptor.set;
+
+ if (!options.accessGetter && hasGetter) {
+ val = '(...)';
+ } else {
+ try {
+ val = obj[key];
+
+ if (contain(options.ignore, val)) {
+ return;
+ }
+
+ if (isPromise(val)) {
+ val.catch(function() {});
+ }
+ } catch (e) {
+ val = e.message;
+ }
+ }
+
+ parts.push(''.concat(wrapKey(key), ':').concat(exports(val, options)));
+
+ if (hasGetter) {
+ parts.push(
+ ''
+ .concat(wrapKey('get ' + toStr(key)), ':')
+ .concat(exports(descriptor.get, options))
+ );
+ }
+
+ if (hasSetter) {
+ parts.push(
+ ''
+ .concat(wrapKey('set ' + toStr(key)), ':')
+ .concat(exports(descriptor.set, options))
+ );
+ }
+ });
+ return '"'.concat(name, '":{') + parts.join(',') + '}';
+ }
+
+ function wrapKey(key) {
+ return '"'.concat(escapeJsonStr(key), '"');
+ }
+
+ function wrapStr(str) {
+ return '"'.concat(escapeJsonStr(toStr(str)), '"');
+ }
+
+ function escapeJsonStr(str) {
+ return escapeJsStr(str)
+ .replace(/\\'/g, "'")
+ .replace(/\t/g, '\\t');
+ }
+
+ var Visitor = Class({
+ initialize: function() {
+ this.id = 0;
+ this.visited = [];
+ },
+ set: function(val) {
+ var visited = this.visited,
+ id = this.id;
+ var obj = {
+ id: id,
+ val: val
+ };
+ visited.push(obj);
+ this.id++;
+ return id;
+ },
+ get: function(val) {
+ var visited = this.visited;
+
+ for (var i = 0, len = visited.length; i < len; i++) {
+ var obj = visited[i];
+ if (val === obj.val) return obj;
+ }
+
+ return false;
+ }
+ });
+
+ return exports;
+ })({});
+
return _;
}));
\ No newline at end of file