123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- (function (root, stringify) {
-
- if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
-
- module.exports = stringify();
- } else if (typeof define === 'function' && define.amd) {
-
- define(function () {
- return stringify();
- });
- } else {
-
- root.javascriptStringify = stringify();
- }
- })(this, function () {
-
- var ESCAPABLE = /[\\\'\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
-
- var META_CHARS = {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- "'": "\\'",
- '"': '\\"',
- '\\': '\\\\'
- };
-
- function escapeChar (char) {
- var meta = META_CHARS[char];
- return meta || '\\u' + ('0000' + char.charCodeAt(0).toString(16)).slice(-4);
- };
-
- var RESERVED_WORDS = {};
-
- (
- 'break else new var case finally return void catch for switch while ' +
- 'continue function this with default if throw delete in try ' +
- 'do instanceof typeof abstract enum int short boolean export ' +
- 'interface static byte extends long super char final native synchronized ' +
- 'class float package throws const goto private transient debugger ' +
- 'implements protected volatile double import public let yield'
- ).split(' ').map(function (key) {
- RESERVED_WORDS[key] = true;
- });
-
- var IS_VALID_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
-
- function isValidVariableName (name) {
- return !RESERVED_WORDS[name] && IS_VALID_IDENTIFIER.test(name);
- }
-
- function toGlobalVariable (value) {
- return 'Function(' + stringify('return this;') + ')()';
- }
-
- function toPath (path) {
- var result = '';
- for (var i = 0; i < path.length; i++) {
- if (isValidVariableName(path[i])) {
- result += '.' + path[i];
- } else {
- result += '[' + stringify(path[i]) + ']';
- }
- }
- return result;
- }
-
- function stringifyArray (array, indent, next) {
-
- var values = array.map(function (value, index) {
- var str = next(value, index);
- if (str === undefined) {
- return String(str);
- }
- return indent + str.split('\n').join('\n' + indent);
- }).join(indent ? ',\n' : ',');
-
- if (indent && values) {
- return '[\n' + values + '\n]';
- }
- return '[' + values + ']';
- }
-
- function stringifyObject (object, indent, next) {
-
- var values = Object.keys(object).reduce(function (values, key) {
- var value = next(object[key], key);
-
- if (value === undefined) {
- return values;
- }
-
- key = isValidVariableName(key) ? key : stringify(key);
- value = String(value).split('\n').join('\n' + indent);
-
- values.push(indent + key + ':' + (indent ? ' ' : '') + value);
- return values;
- }, []).join(indent ? ',\n' : ',');
-
- if (indent && values) {
- return '{\n' + values + '\n}';
- }
- return '{' + values + '}';
- }
-
- var OBJECT_TYPES = {
- '[object Array]': stringifyArray,
- '[object Object]': stringifyObject,
- '[object Error]': function (error) {
- return 'new Error(' + stringify(error.message) + ')';
- },
- '[object Date]': function (date) {
- return 'new Date(' + date.getTime() + ')';
- },
- '[object String]': function (string) {
- return 'new String(' + stringify(string.toString()) + ')';
- },
- '[object Number]': function (number) {
- return 'new Number(' + number + ')';
- },
- '[object Boolean]': function (boolean) {
- return 'new Boolean(' + boolean + ')';
- },
- '[object Uint8Array]': function (array, indent) {
- return 'new Uint8Array(' + stringifyArray(array) + ')';
- },
- '[object Set]': function (array, indent, next) {
- if (typeof Array.from === 'function') {
- return 'new Set(' + stringify(Array.from(array), indent, next) + ')';
- } else return undefined;
- },
- '[object Map]': function (array, indent, next) {
- if (typeof Array.from === 'function') {
- return 'new Map(' + stringify(Array.from(array), indent, next) + ')';
- } else return undefined;
- },
- '[object RegExp]': String,
- '[object Function]': String,
- '[object global]': toGlobalVariable,
- '[object Window]': toGlobalVariable
- };
-
- var PRIMITIVE_TYPES = {
- 'string': function (string) {
- return "'" + string.replace(ESCAPABLE, escapeChar) + "'";
- },
- 'number': String,
- 'object': String,
- 'boolean': String,
- 'symbol': String,
- 'undefined': String
- };
-
- function stringify (value, indent, next) {
-
- if (Object(value) !== value) {
- return PRIMITIVE_TYPES[typeof value](value, indent, next);
- }
-
- if (typeof Buffer === 'function' && Buffer.isBuffer(value)) {
- return 'new Buffer(' + next(value.toString()) + ')';
- }
-
- var toString = OBJECT_TYPES[Object.prototype.toString.call(value)];
-
- return toString ? toString(value, indent, next) : undefined;
- }
-
- return function (value, replacer, space, options) {
- options = options || {}
-
- if (typeof space !== 'string') {
- space = new Array(Math.max(0, space|0) + 1).join(' ');
- }
- var maxDepth = Number(options.maxDepth) || 100;
- var references = !!options.references;
- var skipUndefinedProperties = !!options.skipUndefinedProperties;
- var valueCount = Number(options.maxValues) || 100000;
- var path = [];
- var stack = [];
- var encountered = [];
- var paths = [];
- var restore = [];
-
- function next (value, key) {
- if (skipUndefinedProperties && value === undefined) {
- return undefined;
- }
- path.push(key);
- var result = recurse(value, stringify);
- path.pop();
- return result;
- }
-
- var recurse = references ?
- function (value, stringify) {
- if (value && (typeof value === 'object' || typeof value === 'function')) {
- var seen = encountered.indexOf(value);
-
- if (seen > -1) {
- restore.push(path.slice(), paths[seen]);
- return;
- }
-
- encountered.push(value);
- paths.push(path.slice());
- }
-
- if (path.length > maxDepth || valueCount-- <= 0) {
- return;
- }
-
- return stringify(value, space, next);
- } :
- function (value, stringify) {
- var seen = stack.indexOf(value);
- if (seen > -1 || path.length > maxDepth || valueCount-- <= 0) {
- return;
- }
- stack.push(value);
- var value = stringify(value, space, next);
- stack.pop();
- return value;
- };
-
-
- if (typeof replacer === 'function') {
- var before = recurse
-
- recurse = function (value, stringify) {
- return before(value, function (value, space, next) {
- return replacer(value, space, function (value) {
- return stringify(value, space, next);
- });
- });
- };
- }
- var result = recurse(value, stringify);
-
- if (restore.length) {
- var sep = space ? '\n' : '';
- var assignment = space ? ' = ' : '=';
- var eol = ';' + sep;
- var before = space ? '(function () {' : '(function(){'
- var after = '}())'
- var results = ['var x' + assignment + result];
- for (var i = 0; i < restore.length; i += 2) {
- results.push('x' + toPath(restore[i]) + assignment + 'x' + toPath(restore[i + 1]));
- }
- results.push('return x');
- return before + sep + results.join(eol) + eol + after
- }
- return result;
- };
- });
|