Skip to content

Commit

Permalink
Add support for toJSON
Browse files Browse the repository at this point in the history
This brings `jsesc(data, { 'json': true })` closer to `JSON.stringify(data)`.

Fixes #17.
  • Loading branch information
sonneveld authored and mathiasbynens committed Aug 18, 2014
1 parent a4368cc commit 506dc7d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
8 changes: 8 additions & 0 deletions jsesc.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
return typeof value == 'string' ||
toString.call(value) == '[object String]';
};
var isFunction = function(value) {
return typeof value == 'function';
};

/*--------------------------------------------------------------------------*/

Expand Down Expand Up @@ -108,6 +111,11 @@
var result;
var isEmpty = true;

// convert argument to toJSON if needed.
if (json && argument && isObject(argument) && isFunction(argument.toJSON)) {
argument = argument.toJSON();
}

if (!isString(argument)) {
if (isArray(argument)) {
result = [];
Expand Down
15 changes: 13 additions & 2 deletions src/jsesc.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,20 @@
return toString.call(value) == '[object Array]';
};
var isObject = function(value) {
// simple, but good enough for what we need
// This is a very simple check, but it’s good enough for what we need.
return toString.call(value) == '[object Object]';
};
var isString = function(value) {
return typeof value == 'string' ||
toString.call(value) == '[object String]';
};
var isFunction = function(value) {
// In a perfect world, the `typeof` check would be sufficient. However,
// in Chrome 1–12, `typeof /x/ == 'object'`, and in IE 6–8
// `typeof alert == 'object'` and similar for other host objects.
return typeof value == 'function' ||
toString.call(value) == '[object Function]';
};

/*--------------------------------------------------------------------------*/

Expand All @@ -71,7 +78,7 @@
'\n': '\\n',
'\r': '\\r',
'\t': '\\t'
// `\v` is omitted intentionally, because in IE < 9, '\v' == 'v'
// `\v` is omitted intentionally, because in IE < 9, '\v' == 'v'.
// '\v': '\\x0B'
};
var regexSingleEscape = /["'\\\b\f\n\r\t]/;
Expand Down Expand Up @@ -108,6 +115,10 @@
var result;
var isEmpty = true;

if (json && argument && isFunction(argument.toJSON)) {
argument = argument.toJSON();
}

if (!isString(argument)) {
if (isArray(argument)) {
result = [];
Expand Down
20 changes: 20 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,26 @@
'"foo\\u{1D306}bar\\u00A9baz"',
'Escaping as JSON with `es6: true`'
);
var tmp = {
'shouldn\u2019t be here': 10,
'toJSON': function() {
return {
'hello': 'world',
'\uD83D\uDCA9': 'foo',
'pile': '\uD83D\uDCA9'
};
}
};
equal(
jsesc(tmp, { 'json' : true }),
'{"hello":"world","\\uD83D\\uDCA9":"foo","pile":"\\uD83D\\uDCA9"}',
'`toJSON` methods are called when `json: true`'
);
notEqual(
jsesc(tmp),
'{"hello":"world","\\uD83D\\uDCA9":"foo","pile":"\\uD83D\\uDCA9"}',
'`toJSON` methods are not called when `json: false`'
);
});

if (runExtendedTests) {
Expand Down

0 comments on commit 506dc7d

Please sign in to comment.