Skip to content

Commit

Permalink
Remove broken support for regular expressions
Browse files Browse the repository at this point in the history
It may return at some point in the future.

Ref. #10 and #11.
  • Loading branch information
mathiasbynens committed Aug 3, 2013
1 parent 7b71ba4 commit 0d54d0c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 82 deletions.
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,9 @@ jsesc('foo 𝌆 bar');
// → 'foo \\uD834\\uDF06 bar'
```

Instead of a string, the `value` can also be a regular expression, an array, or an object. In such cases, `jsesc` will return a stringified version of the value where any characters that are not printable ASCII symbols are escaped in the same way.
Instead of a string, the `value` can also be an array, or an object. In such cases, `jsesc` will return a stringified version of the value where any characters that are not printable ASCII symbols are escaped in the same way.

```js
// Escaping a regular expression
jsesc(/©𝌆/g);
// → '/\\xA9\\uD834\\uDF06/g'

// Escaping an array
jsesc([
'Ich ♥ Bücher', 'foo 𝌆 bar'
Expand Down Expand Up @@ -186,8 +182,6 @@ jsesc([ 'Ich ♥ Bücher': 'foo 𝌆 bar' ], {
// → '[\'\x49\x63\x68\x20\u2665\x20\x42\xFC\x63\x68\x65\x72\',\'\x66\x6F\x6F\x20\uD834\uDF06\x20\x62\x61\x72\']'
```

This setting has no effect on the output for regular expressions. Those only use escape sequences for non-printable ASCII symbols and non-ASCII symbols, regardless of the value of the `escapeEverything` setting.

#### `compact`

The `compact` option takes a boolean value (`true` or `false`), and defaults to `true` (enabled). When enabled, the output for arrays and objects will be as compact as possible; it won’t be formatted nicely.
Expand Down Expand Up @@ -235,7 +229,7 @@ jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
// → '[\n \'Ich \u2665 B\xFCcher\',\n\ t\'foo \uD834\uDF06 bar\'\n]'
```

This setting has no effect on the output for strings or regular expressions.
This setting has no effect on the output for strings.

#### `json`

Expand Down Expand Up @@ -263,9 +257,14 @@ jsesc([ 'foo\x00bar', [1, '©', { 'foo': true, 'qux': null }], 42 ], {
'json': true
});
// → '["foo\\u0000bar",[1,"\\u00A9",{"foo":true,"qux":null}],42]'
// Values that aren’t allowed in JSON are run through `JSON.stringify()`:
jsesc([ undefined, -Infinity ], {
'json': true
});
// → '[null,null]'
```

**Note:** Using this option on objects or arrays that contain non-string values relies on `JSON.parse()`. For legacy environments like IE ≤ 7, use [a `JSON` polyfill](http://bestiejs.github.io/json3/).
**Note:** Using this option on objects or arrays that contain non-string values relies on `JSON.stringify()`. For legacy environments like IE ≤ 7, use [a `JSON` polyfill](http://bestiejs.github.io/json3/).

### `jsesc.version`

Expand Down
41 changes: 20 additions & 21 deletions jsesc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*! http://mths.be/jsesc v0.4.1 by @mathias */
;(function(root, evil) {
;(function(root) {

// Detect free variables `exports`
var freeExports = typeof exports == 'object' && exports;
Expand Down Expand Up @@ -54,9 +54,6 @@
// simple, but good enough for what we need
return toString.call(value) == '[object Object]';
};
var isRegExp = function(value) {
return toString.call(value) == '[object RegExp]';
};
var isString = function(value) {
return typeof value == 'string' ||
toString.call(value) == '[object String]';
Expand All @@ -83,6 +80,19 @@
var regexDigit = /[0-9]/;
var regexWhitelist = /[\x20\x21\x23-\x26\x28-\x5B\x5D-\x7E]/;

var stringFromCharCode = String.fromCharCode;
// Modified version of `ucs2encode`; see http://mths.be/punycode
var codePointToSymbol = function(codePoint, strict) {
var output = '';
if (codePoint > 0xFFFF) {
codePoint -= 0x10000;
output += stringFromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);
codePoint = 0xDC00 | codePoint & 0x3FF;
}
output += stringFromCharCode(codePoint);
return output;
};

var jsesc = function(argument, options) {
// Handle options
var defaults = {
Expand All @@ -91,7 +101,7 @@
'wrap': false,
'compact': true,
'indent': '\t',
'__indent': '',
'__indent__': '',
};
options = extend(defaults, options);
if (options.quotes != 'single' && options.quotes != 'double') {
Expand All @@ -114,9 +124,9 @@
if (isArray(argument)) {
result = [];
options.wrap = true;
oldIndent = options.__indent;
oldIndent = options.__indent__;
indent += oldIndent;
options.__indent = indent;
options.__indent__ = indent;
forEach(argument, function(value) {
isEmpty = false;
result.push(
Expand All @@ -129,17 +139,6 @@
}
return '[' + newLine + result.join(',' + newLine) + newLine +
(compact ? '' : oldIndent) + ']';
} else if (!json && isRegExp(argument)) {
return '/' + jsesc(
evil(
'\'' + argument.source.replace(regexEval, jsesc) + '\''
),
extend(options, {
'wrap': false,
'escapeEverything': false
}
)) + '/' + (argument.global ? 'g' : '') +
(argument.ignoreCase ? 'i' : '') + (argument.multiline ? 'm' : '');
} else if (!isObject(argument)) {
if (json) {
// For some values (e.g. `undefined`, `function` objects),
Expand All @@ -150,9 +149,9 @@
} else { // it’s an object
result = [];
options.wrap = true;
oldIndent = options.__indent;
oldIndent = options.__indent__;
indent += oldIndent;
options.__indent = indent;
options.__indent__ = indent;
forOwn(argument, function(key, value) {
isEmpty = false;
result.push(
Expand Down Expand Up @@ -244,4 +243,4 @@
root.jsesc = jsesc;
}

}(this, eval));
}(this));
41 changes: 20 additions & 21 deletions src/jsesc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*! http://mths.be/jsesc v<%= version %> by @mathias */
;(function(root, evil) {
;(function(root) {

// Detect free variables `exports`
var freeExports = typeof exports == 'object' && exports;
Expand Down Expand Up @@ -54,9 +54,6 @@
// simple, but good enough for what we need
return toString.call(value) == '[object Object]';
};
var isRegExp = function(value) {
return toString.call(value) == '[object RegExp]';
};
var isString = function(value) {
return typeof value == 'string' ||
toString.call(value) == '[object String]';
Expand All @@ -83,6 +80,19 @@
var regexDigit = /[0-9]/;
var regexWhitelist = /<%= whitelist %>/;

var stringFromCharCode = String.fromCharCode;
// Modified version of `ucs2encode`; see http://mths.be/punycode
var codePointToSymbol = function(codePoint, strict) {
var output = '';
if (codePoint > 0xFFFF) {
codePoint -= 0x10000;
output += stringFromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);
codePoint = 0xDC00 | codePoint & 0x3FF;
}
output += stringFromCharCode(codePoint);
return output;
};

var jsesc = function(argument, options) {
// Handle options
var defaults = {
Expand All @@ -91,7 +101,7 @@
'wrap': false,
'compact': true,
'indent': '\t',
'__indent': '',
'__indent__': '',
};
options = extend(defaults, options);
if (options.quotes != 'single' && options.quotes != 'double') {
Expand All @@ -114,9 +124,9 @@
if (isArray(argument)) {
result = [];
options.wrap = true;
oldIndent = options.__indent;
oldIndent = options.__indent__;
indent += oldIndent;
options.__indent = indent;
options.__indent__ = indent;
forEach(argument, function(value) {
isEmpty = false;
result.push(
Expand All @@ -129,17 +139,6 @@
}
return '[' + newLine + result.join(',' + newLine) + newLine +
(compact ? '' : oldIndent) + ']';
} else if (!json && isRegExp(argument)) {
return '/' + jsesc(
evil(
'\'' + argument.source.replace(regexEval, jsesc) + '\''
),
extend(options, {
'wrap': false,
'escapeEverything': false
}
)) + '/' + (argument.global ? 'g' : '') +
(argument.ignoreCase ? 'i' : '') + (argument.multiline ? 'm' : '');
} else if (!isObject(argument)) {
if (json) {
// For some values (e.g. `undefined`, `function` objects),
Expand All @@ -150,9 +149,9 @@
} else { // it’s an object
result = [];
options.wrap = true;
oldIndent = options.__indent;
oldIndent = options.__indent__;
indent += oldIndent;
options.__indent = indent;
options.__indent__ = indent;
forOwn(argument, function(key, value) {
isEmpty = false;
result.push(
Expand Down Expand Up @@ -244,4 +243,4 @@
root.jsesc = jsesc;
}

}(this, eval));
}(this));
39 changes: 8 additions & 31 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,30 +206,6 @@
'["\\u0066\\u006F\\u006F\\u0000\\u0062\\u0061\\u0072\\uFFFD\\u0062\\u0061\\u007A","\\u0066\\u006F\\u006F\\u0000\\u0062\\u0061\\u0072\\uFFFD\\u0062\\u0061\\u007A"]',
'JSON-stringifying a flat array with `escapeEverything: true`'
);
equal(
jsesc(/foo©bar𝌆[a-z0-9]ö/ig),
'/foo\\xA9bar\\uD834\\uDF06[a-z0-9]\\xF6/gi',
'Escaping a regular expression'
);
equal(
jsesc(/foo\xA9bar\uD834\uDF06[a-z0-9]\xF6/ig),
'/foo\\xA9bar\\uD834\\uDF06[a-z0-9]\\xF6/gi',
'Escaping an already-escaped regular expression'
);
equal(
jsesc(/foo©bar𝌆[a-z0-9]ö/, {
'escapeEverything': true // should ignore the setting for the regex source part
}),
'/foo\\xA9bar\\uD834\\uDF06[a-z0-9]\\xF6/',
'Escaping a regular expression with `escapeEverything: true`'
);
equal(
jsesc(['abc', /foo©bar𝌆[a-z0-9]ö/mig], {
'escapeEverything': true // should ignore the setting for the regex source part
}),
'[\'\\x61\\x62\\x63\',/foo\\xA9bar\\uD834\\uDF06[a-z0-9]\\xF6/gim]',
'Escaping an array containing a regular expression with `escapeEverything: true`'
);
});

if (runExtendedTests) {
Expand Down Expand Up @@ -305,31 +281,32 @@
var testArray = [
undefined, Infinity, new Number(Infinity), -Infinity,
new Number(-Infinity), 0, new Number(0), -0, new Number(-0), +0,
new Number(+0), /foo[z-©]/g, new RegExp(/foo[z-©]/g), new Function(),
'str', function zomg() { return 'desu'; }, null, true, new Boolean(true),
false, new Boolean(false),
{ "foo": 42, "baz": /löl/g, "hah": [ 1, 2, 3, { "foo" : 42 } ] }
new Number(+0), new Function(), 'str',
function zomg() { return 'desu'; }, null, true, new Boolean(true),
false, new Boolean(false), {
"foo": 42, "hah": [ 1, 2, 3, { "foo" : 42 } ]
}
];
equal(
jsesc(testArray, {
'json': false
}),
'[undefined,Infinity,Infinity,-Infinity,-Infinity,0,0,0,0,0,0,/foo[z-\\xA9]/g,/foo[z-\\xA9]/g,function anonymous() {\n\n},\'str\',function zomg() { return \'desu\'; },null,true,true,false,false,{\'foo\':42,\'baz\':/l\\xF6l/g,\'hah\':[1,2,3,{\'foo\':42}]}]',
'[undefined,Infinity,Infinity,-Infinity,-Infinity,0,0,0,0,0,0,function anonymous() {\n\n},\'str\',function zomg() { return \'desu\'; },null,true,true,false,false,{\'foo\':42,\'hah\':[1,2,3,{\'foo\':42}]}]',
'Escaping a non-flat array with all kinds of values'
);
equal(
jsesc(testArray, {
'json': true
}),
'[null,null,null,null,null,0,0,0,0,0,0,{},{},null,"str",null,null,true,true,false,false,{"foo":42,"baz":{},"hah":[1,2,3,{"foo":42}]}]',
'[null,null,null,null,null,0,0,0,0,0,0,null,"str",null,null,true,true,false,false,{"foo":42,"hah":[1,2,3,{"foo":42}]}]',
'Escaping a non-flat array with all kinds of values, with `json: true`'
);
equal(
jsesc(testArray, {
'json': true,
'compact': false
}),
'[\n\tnull,\n\tnull,\n\tnull,\n\tnull,\n\tnull,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t{},\n\t{},\n\tnull,\n\t"str",\n\tnull,\n\tnull,\n\ttrue,\n\ttrue,\n\tfalse,\n\tfalse,\n\t{\n\t\t"foo": 42,\n\t\t"baz": {},\n\t\t"hah": [\n\t\t\t1,\n\t\t\t2,\n\t\t\t3,\n\t\t\t{\n\t\t\t\t"foo": 42\n\t\t\t}\n\t\t]\n\t}\n]',
'[\n\tnull,\n\tnull,\n\tnull,\n\tnull,\n\tnull,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\tnull,\n\t"str",\n\tnull,\n\tnull,\n\ttrue,\n\ttrue,\n\tfalse,\n\tfalse,\n\t{\n\t\t"foo": 42,\n\t\t"hah": [\n\t\t\t1,\n\t\t\t2,\n\t\t\t3,\n\t\t\t{\n\t\t\t\t"foo": 42\n\t\t\t}\n\t\t]\n\t}\n]',
'Escaping a non-flat array with all kinds of values, with `json: true, compact: false`'
);
}
Expand Down

0 comments on commit 0d54d0c

Please sign in to comment.