PageRenderTime 30ms CodeModel.GetById 11ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/utils.js

https://bitbucket.org/renren_platform/renren-api-javascript-sdk/
JavaScript | 329 lines | 305 code | 18 blank | 6 comment | 103 complexity | d3502b96dd173624da73ae0f848bfca6 MD5 | raw file
  1/**
  2 * #@+
  3 * 
  4 * @private
  5 */
  6var overloadSetter = function(fn) {
  7	return function(s, a, b) {
  8		if (a == null)
  9			return s;
 10		if (typeof a != 'string') {
 11			for (var k in a)
 12				fn.call(s, k, a[k]);
 13		} else {
 14			fn.call(s, a, b);
 15		}
 16		return s;
 17	};
 18},
 19
 20typeOf = function(item) {
 21	if (item == null)
 22		return 'null';
 23	if (item instanceof String || typeof item == 'string')
 24		return 'string';
 25	if (item instanceof Array)
 26		return 'array';
 27	if (item.nodeName) {
 28		if (item.nodeType == 1)
 29			return 'element';
 30		if (item.nodeType == 3)
 31			return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
 32	} else if (typeof item.length == 'number') {
 33		if (item.callee)
 34			return 'arguments';
 35		if ('item' in item)
 36			return 'collection';
 37	}
 38	return typeof item;
 39},
 40
 41guid = function() {
 42	return (Math.random() * (1 << 30)).toString(36).replace('.', '');
 43},
 44
 45extend = overloadSetter(function(key, value) {
 46			this[key] = value;
 47		}),
 48
 49implement = overloadSetter(function(key, value) {
 50			this.prototype[key] = value;
 51		}),
 52
 53bind = function(fn, thisobj, args) {
 54	return function() {
 55		if (!args && !arguments.length)
 56			return fn.call(thisobj);
 57		if (args && arguments.length)
 58			return fn.apply(thisobj, args.concat(Array.from(arguments)));
 59		return fn.apply(thisobj, args || arguments);
 60	};
 61},
 62
 63cloneOf = function(item) {
 64	switch (typeOf(item)) {
 65		case 'array' :
 66		case 'object' :
 67			return clone(item);
 68		default :
 69			return item;
 70	}
 71},
 72
 73clone = function(original) {
 74	if (typeOf(original) == 'array') {
 75		var i = original.length, clone = new Array(i);
 76		while (i--)
 77			clone[i] = cloneOf(original[i]);
 78		return clone;
 79	} else if (typeOf(original) == 'string') {
 80		return new String(original);
 81	}
 82	var clone = {};
 83	for (var key in original)
 84		clone[key] = cloneOf(original[key]);
 85	return clone;
 86},
 87
 88forEach = function(object, fn, bind) {
 89	if (typeOf(object) == 'array') {
 90		for (var i = 0, l = object.length; i < l; i++) {
 91			if (i in object)
 92				fn.call(bind, object[i], i, object);
 93		}
 94	} else
 95		for (var key in object) {
 96			if (Object.prototype.hasOwnProperty.call(object, key))
 97				fn.call(bind, object[key], key, object);
 98		}
 99},
100
101indexOf = function(array, item, from) {
102	var len = array.length;
103	for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) {
104		if (array[i] === item)
105			return i;
106	}
107	return -1;
108},
109
110mergeOne = function(source, key, current) {
111	switch (typeOf(current)) {
112		case 'object' :
113			if (typeOf(source[key]) == 'object')
114				merge(source[key], current);
115			else
116				source[key] = clone(current);
117			break;
118		case 'array' :
119			source[key] = clone(current);
120			break;
121		default :
122			source[key] = current;
123	}
124	return source;
125},
126
127merge = function(source, k, v) {
128	if (typeOf(k) == 'string')
129		return mergeOne(source, k, v);
130	for (var i = 1, l = arguments.length; i < l; i++) {
131		var object = arguments[i];
132		for (var key in object)
133			mergeOne(source, key, object[key]);
134	}
135	return source;
136},
137
138combineOne = function(source, key, value) {
139	var st = typeOf(source[key]);
140	switch (typeOf(value)) {
141		case 'object' :
142		case 'array' :
143			if (st == 'object')
144				combine(source[key], value);
145			else if (st == 'array') {
146				var array = clone(value);
147				for (var i = 0, l = array.length; i < l; i++) {
148					if (indexOf(source[key], array[i]) == -1)
149						source[key].push(array[i]);
150				}
151			} else if (st == 'null')
152				source[key] = clone(value);
153			break;
154		default :
155			if (st == 'null')
156				source[key] = value;
157	}
158	return source;
159},
160
161combine = function(source, k, v) {
162	if (typeOf(k) == 'string')
163		return combineOne(source, k, v);
164	for (var i = 1, l = arguments.length; i < l; i++) {
165		var object = arguments[i];
166		for (var key in object)
167			combineOne(source, key, object[key]);
168	}
169	return source;
170},
171
172append = function(original) {
173	for (var i = 1, l = arguments.length; i < l; i++) {
174		if (typeOf(original) == 'array') {
175			var atp = typeOf(arguments[i]);
176			if (atp == 'array' || atp == 'arguments') {
177				for (var j = 0, lg = arguments[i].length; j < lg; j++)
178					original.push(arguments[i][j]);
179			} else if (atp != 'null')
180				original.push(arguments[i]);
181		} else {
182			var extended = arguments[i] || {};
183			for (var key in extended)
184				original[key] = extended[key];
185		}
186	}
187	return original;
188},
189
190parsePiece = function(key, val, base) {
191	var sliced = /([^\]]*)\[([^\]]*)\](.*)?/.exec(key);
192	if (!sliced) {
193		base[key] = val;
194		return;
195	}
196	var prop = sliced[1], subp = sliced[2], others = sliced[3];
197	if (!isNaN(subp)) {
198		var numVal = +subp;
199		if (subp === numVal.toString(10)) {
200			subp = numVal;
201		}
202	}
203	base[prop] = base[prop] || (typeof subp == 'number' ? [] : {});
204	if (others == null)
205		base[prop][subp] = val;
206	else
207		parsePiece('' + subp + others, val, base[prop]);
208},
209
210fromQueryString = function(qs) {
211	var decode = function(s) {
212		return decodeURIComponent(s.replace(/\+/g, ' '));
213	}, params = {}, parts = qs.split('&'), pair, val;
214	for (var i = 0; i < parts.length; i++) {
215		pair = parts[i].split('=', 2);
216		if (pair && pair.length == 2) {
217			val = decode(pair[1]);
218			if (typeOf(val) == 'string') {
219				val = val.replace(/^\s+|\s+$/g, '');
220				// convert numerals to numbers
221				if (!isNaN(val)) {
222					numVal = +val;
223					if (val === numVal.toString(10)) {
224						val = numVal;
225					}
226				}
227			}
228			parsePiece(decode(pair[0]), val, params);
229		}
230	}
231	return params;
232},
233
234toQueryString = function(object, base) {
235	var queryString = [];
236	forEach(object, function(value, key) {
237				if (base)
238					key = base + '[' + key + ']';
239				var result;
240				switch (typeOf(value)) {
241					case 'object' :
242						result = toQueryString(value, key);
243						break;
244					case 'array' :
245						var qs = {};
246						forEach(value, function(val, i) {
247									qs[i] = val;
248								});
249						result = toQueryString(qs, key);
250						break;
251					case 'string' :
252					case 'number' :
253						result = encodeURIComponent(key) + '='
254								+ encodeURIComponent(value);
255						break;
256				}
257				if (result && value != null)
258					queryString.push(result);
259			});
260	return queryString.join('&');
261},
262
263special = {
264	'\b' : '\\b',
265	'\t' : '\\t',
266	'\n' : '\\n',
267	'\f' : '\\f',
268	'\r' : '\\r',
269	'"' : '\\"',
270	'\\' : '\\\\'
271},
272
273escape = function(chr) {
274	return special[chr] || '\\u'
275			+ ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
276},
277
278validateJSON = function(string) {
279	string = string
280			.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
281			.replace(
282					/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
283					']').replace(/(?:^|:|,)(?:\s*\[)+/g, '');
284	return (/^[\],:{}\s]*$/).test(string);
285},
286
287parseJSON = function(string) {
288	if (!string || typeOf(string) != 'string')
289		return null;
290	if (window.JSON && window.JSON.parse)
291		return window.JSON.parse(string);
292	if (!validateJSON(string))
293		throw new Error("Invalid JSON: " + string);
294	return eval('(' + string + ')');
295},
296
297toJSON = window.JSON && window.JSON.stringify ? function(obj) {
298	return window.JSON.stringify(obj);
299} : function(obj) {
300	if (obj && obj.toJSON)
301		obj = obj.toJSON();
302	switch (typeOf(obj)) {
303		case 'string' :
304			return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
305		case 'array' :
306			var string = [];
307			forEach(obj, function(value, key) {
308						var json = toJSON(value);
309						if (json)
310							string.push(json);
311					});
312			return '[' + string + ']';
313		case 'object' :
314			var string = [];
315			forEach(obj, function(value, key) {
316						var json = toJSON(value);
317						if (json)
318							string.push(toJSON(key) + ':' + json);
319					});
320			return '{' + string + '}';
321		case 'number' :
322		case 'boolean' :
323			return '' + obj;
324		case 'null' :
325			return 'null';
326	}
327	return null;
328};
329/** #@- */