Projekt

Obecné

Profil

Stáhnout (9.22 KB) Statistiky
| Větev: | Revize:
1
/*! https://mths.be/jsesc v1.3.0 by @mathias */
2
;(function(root) {
3

    
4
	// Detect free variables `exports`
5
	var freeExports = typeof exports == 'object' && exports;
6

    
7
	// Detect free variable `module`
8
	var freeModule = typeof module == 'object' && module &&
9
		module.exports == freeExports && module;
10

    
11
	// Detect free variable `global`, from Node.js or Browserified code,
12
	// and use it as `root`
13
	var freeGlobal = typeof global == 'object' && global;
14
	if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
15
		root = freeGlobal;
16
	}
17

    
18
	/*--------------------------------------------------------------------------*/
19

    
20
	var object = {};
21
	var hasOwnProperty = object.hasOwnProperty;
22
	var forOwn = function(object, callback) {
23
		var key;
24
		for (key in object) {
25
			if (hasOwnProperty.call(object, key)) {
26
				callback(key, object[key]);
27
			}
28
		}
29
	};
30

    
31
	var extend = function(destination, source) {
32
		if (!source) {
33
			return destination;
34
		}
35
		forOwn(source, function(key, value) {
36
			destination[key] = value;
37
		});
38
		return destination;
39
	};
40

    
41
	var forEach = function(array, callback) {
42
		var length = array.length;
43
		var index = -1;
44
		while (++index < length) {
45
			callback(array[index]);
46
		}
47
	};
48

    
49
	var toString = object.toString;
50
	var isArray = function(value) {
51
		return toString.call(value) == '[object Array]';
52
	};
53
	var isObject = function(value) {
54
		// This is a very simple check, but it’s good enough for what we need.
55
		return toString.call(value) == '[object Object]';
56
	};
57
	var isString = function(value) {
58
		return typeof value == 'string' ||
59
			toString.call(value) == '[object String]';
60
	};
61
	var isNumber = function(value) {
62
		return typeof value == 'number' ||
63
			toString.call(value) == '[object Number]';
64
	};
65
	var isFunction = function(value) {
66
		// In a perfect world, the `typeof` check would be sufficient. However,
67
		// in Chrome 1–12, `typeof /x/ == 'object'`, and in IE 6–8
68
		// `typeof alert == 'object'` and similar for other host objects.
69
		return typeof value == 'function' ||
70
			toString.call(value) == '[object Function]';
71
	};
72
	var isMap = function(value) {
73
		return toString.call(value) == '[object Map]';
74
	};
75
	var isSet = function(value) {
76
		return toString.call(value) == '[object Set]';
77
	};
78

    
79
	/*--------------------------------------------------------------------------*/
80

    
81
	// https://mathiasbynens.be/notes/javascript-escapes#single
82
	var singleEscapes = {
83
		'"': '\\"',
84
		'\'': '\\\'',
85
		'\\': '\\\\',
86
		'\b': '\\b',
87
		'\f': '\\f',
88
		'\n': '\\n',
89
		'\r': '\\r',
90
		'\t': '\\t'
91
		// `\v` is omitted intentionally, because in IE < 9, '\v' == 'v'.
92
		// '\v': '\\x0B'
93
	};
94
	var regexSingleEscape = /["'\\\b\f\n\r\t]/;
95

    
96
	var regexDigit = /[0-9]/;
97
	var regexWhitelist = /[ !#-&\(-\[\]-~]/;
98

    
99
	var jsesc = function(argument, options) {
100
		// Handle options
101
		var defaults = {
102
			'escapeEverything': false,
103
			'escapeEtago': false,
104
			'quotes': 'single',
105
			'wrap': false,
106
			'es6': false,
107
			'json': false,
108
			'compact': true,
109
			'lowercaseHex': false,
110
			'numbers': 'decimal',
111
			'indent': '\t',
112
			'__indent__': '',
113
			'__inline1__': false,
114
			'__inline2__': false
115
		};
116
		var json = options && options.json;
117
		if (json) {
118
			defaults.quotes = 'double';
119
			defaults.wrap = true;
120
		}
121
		options = extend(defaults, options);
122
		if (options.quotes != 'single' && options.quotes != 'double') {
123
			options.quotes = 'single';
124
		}
125
		var quote = options.quotes == 'double' ? '"' : '\'';
126
		var compact = options.compact;
127
		var indent = options.indent;
128
		var lowercaseHex = options.lowercaseHex;
129
		var oldIndent = '';
130
		var inline1 = options.__inline1__;
131
		var inline2 = options.__inline2__;
132
		var newLine = compact ? '' : '\n';
133
		var result;
134
		var isEmpty = true;
135
		var useBinNumbers = options.numbers == 'binary';
136
		var useOctNumbers = options.numbers == 'octal';
137
		var useDecNumbers = options.numbers == 'decimal';
138
		var useHexNumbers = options.numbers == 'hexadecimal';
139

    
140
		if (json && argument && isFunction(argument.toJSON)) {
141
			argument = argument.toJSON();
142
		}
143

    
144
		if (!isString(argument)) {
145
			if (isMap(argument)) {
146
				if (argument.size == 0) {
147
					return 'new Map()';
148
				}
149
				if (!compact) {
150
					options.__inline1__ = true;
151
				}
152
				return 'new Map(' + jsesc(Array.from(argument), options) + ')';
153
			}
154
			if (isSet(argument)) {
155
				if (argument.size == 0) {
156
					return 'new Set()';
157
				}
158
				return 'new Set(' + jsesc(Array.from(argument), options) + ')';
159
			}
160
			if (isArray(argument)) {
161
				result = [];
162
				options.wrap = true;
163
				if (inline1) {
164
					options.__inline1__ = false;
165
					options.__inline2__ = true;
166
				} else {
167
					oldIndent = options.__indent__;
168
					indent += oldIndent;
169
					options.__indent__ = indent;
170
				}
171
				forEach(argument, function(value) {
172
					isEmpty = false;
173
					if (inline2) {
174
						options.__inline2__ = false;
175
					}
176
					result.push(
177
						(compact || inline2 ? '' : indent) +
178
						jsesc(value, options)
179
					);
180
				});
181
				if (isEmpty) {
182
					return '[]';
183
				}
184
				if (inline2) {
185
					return '[' + result.join(', ') + ']';
186
				}
187
				return '[' + newLine + result.join(',' + newLine) + newLine +
188
					(compact ? '' : oldIndent) + ']';
189
			} else if (isNumber(argument)) {
190
				if (json) {
191
					// Some number values (e.g. `Infinity`) cannot be represented in JSON.
192
					return JSON.stringify(argument);
193
				}
194
				if (useDecNumbers) {
195
					return String(argument);
196
				}
197
				if (useHexNumbers) {
198
					var tmp = argument.toString(16);
199
					if (!lowercaseHex) {
200
						tmp = tmp.toUpperCase();
201
					}
202
					return '0x' + tmp;
203
				}
204
				if (useBinNumbers) {
205
					return '0b' + argument.toString(2);
206
				}
207
				if (useOctNumbers) {
208
					return '0o' + argument.toString(8);
209
				}
210
			} else if (!isObject(argument)) {
211
				if (json) {
212
					// For some values (e.g. `undefined`, `function` objects),
213
					// `JSON.stringify(value)` returns `undefined` (which isn’t valid
214
					// JSON) instead of `'null'`.
215
					return JSON.stringify(argument) || 'null';
216
				}
217
				return String(argument);
218
			} else { // it’s an object
219
				result = [];
220
				options.wrap = true;
221
				oldIndent = options.__indent__;
222
				indent += oldIndent;
223
				options.__indent__ = indent;
224
				forOwn(argument, function(key, value) {
225
					isEmpty = false;
226
					result.push(
227
						(compact ? '' : indent) +
228
						jsesc(key, options) + ':' +
229
						(compact ? '' : ' ') +
230
						jsesc(value, options)
231
					);
232
				});
233
				if (isEmpty) {
234
					return '{}';
235
				}
236
				return '{' + newLine + result.join(',' + newLine) + newLine +
237
					(compact ? '' : oldIndent) + '}';
238
			}
239
		}
240

    
241
		var string = argument;
242
		// Loop over each code unit in the string and escape it
243
		var index = -1;
244
		var length = string.length;
245
		var first;
246
		var second;
247
		var codePoint;
248
		result = '';
249
		while (++index < length) {
250
			var character = string.charAt(index);
251
			if (options.es6) {
252
				first = string.charCodeAt(index);
253
				if ( // check if it’s the start of a surrogate pair
254
					first >= 0xD800 && first <= 0xDBFF && // high surrogate
255
					length > index + 1 // there is a next code unit
256
				) {
257
					second = string.charCodeAt(index + 1);
258
					if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
259
						// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
260
						codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
261
						var hexadecimal = codePoint.toString(16);
262
						if (!lowercaseHex) {
263
							hexadecimal = hexadecimal.toUpperCase();
264
						}
265
						result += '\\u{' + hexadecimal + '}';
266
						index++;
267
						continue;
268
					}
269
				}
270
			}
271
			if (!options.escapeEverything) {
272
				if (regexWhitelist.test(character)) {
273
					// It’s a printable ASCII character that is not `"`, `'` or `\`,
274
					// so don’t escape it.
275
					result += character;
276
					continue;
277
				}
278
				if (character == '"') {
279
					result += quote == character ? '\\"' : character;
280
					continue;
281
				}
282
				if (character == '\'') {
283
					result += quote == character ? '\\\'' : character;
284
					continue;
285
				}
286
			}
287
			if (
288
				character == '\0' &&
289
				!json &&
290
				!regexDigit.test(string.charAt(index + 1))
291
			) {
292
				result += '\\0';
293
				continue;
294
			}
295
			if (regexSingleEscape.test(character)) {
296
				// no need for a `hasOwnProperty` check here
297
				result += singleEscapes[character];
298
				continue;
299
			}
300
			var charCode = character.charCodeAt(0);
301
			var hexadecimal = charCode.toString(16);
302
			if (!lowercaseHex) {
303
				hexadecimal = hexadecimal.toUpperCase();
304
			}
305
			var longhand = hexadecimal.length > 2 || json;
306
			var escaped = '\\' + (longhand ? 'u' : 'x') +
307
				('0000' + hexadecimal).slice(longhand ? -4 : -2);
308
			result += escaped;
309
			continue;
310
		}
311
		if (options.wrap) {
312
			result = quote + result + quote;
313
		}
314
		if (options.escapeEtago) {
315
			// https://mathiasbynens.be/notes/etago
316
			return result.replace(/<\/(script|style)/gi, '<\\/$1');
317
		}
318
		return result;
319
	};
320

    
321
	jsesc.version = '1.3.0';
322

    
323
	/*--------------------------------------------------------------------------*/
324

    
325
	// Some AMD build optimizers, like r.js, check for specific condition patterns
326
	// like the following:
327
	if (
328
		typeof define == 'function' &&
329
		typeof define.amd == 'object' &&
330
		define.amd
331
	) {
332
		define(function() {
333
			return jsesc;
334
		});
335
	}	else if (freeExports && !freeExports.nodeType) {
336
		if (freeModule) { // in Node.js or RingoJS v0.8.0+
337
			freeModule.exports = jsesc;
338
		} else { // in Narwhal or RingoJS v0.7.0-
339
			freeExports.jsesc = jsesc;
340
		}
341
	} else { // in Rhino or a web browser
342
		root.jsesc = jsesc;
343
	}
344

    
345
}(this));
(1-1/2)