@@ -10,40 +10,69 @@ var isRegExp = require('util').isRegExp;
10
10
11
11
// Generate an internal UID to make the regexp pattern harder to guess.
12
12
var UID = Math . floor ( Math . random ( ) * 0x10000000000 ) . toString ( 16 ) ;
13
- var PLACE_HOLDER_REGEXP = new RegExp ( '"@__(FUNCTION|REGEXP )-' + UID + '-(\\d+)__@"' , 'g' ) ;
13
+ var PLACE_HOLDER_REGEXP = new RegExp ( '"@__(F|R )-' + UID + '-(\\d+)__@"' , 'g' ) ;
14
14
15
15
var IS_NATIVE_CODE_REGEXP = / \{ \s * \[ n a t i v e c o d e \] \s * \} / g;
16
16
var UNSAFE_CHARS_REGEXP = / [ < > \/ \u2028 \u2029 ] / g;
17
17
18
18
// Mapping of unsafe HTML and invalid JavaScript line terminator chars to their
19
19
// Unicode char counterparts which are safe to use in JavaScript strings.
20
- var UNICODE_CHARS = {
20
+ var ESCAPED_CHARS = {
21
21
'<' : '\\u003C' ,
22
22
'>' : '\\u003E' ,
23
23
'/' : '\\u002F' ,
24
24
'\u2028' : '\\u2028' ,
25
25
'\u2029' : '\\u2029'
26
26
} ;
27
27
28
- module . exports = function serialize ( obj , space ) {
28
+ function escapeUnsafeChars ( unsafeChar ) {
29
+ return ESCAPED_CHARS [ unsafeChar ] ;
30
+ }
31
+
32
+ module . exports = function serialize ( obj , options ) {
33
+ options || ( options = { } ) ;
34
+
35
+ // Backwards-compatability for `space` as the second argument.
36
+ if ( typeof options === 'number' || typeof options === 'string' ) {
37
+ options = { space : options } ;
38
+ }
39
+
29
40
var functions = [ ] ;
30
41
var regexps = [ ] ;
31
- var str ;
32
42
33
- // Creates a JSON string representation of the object and uses placeholders
34
- // for functions and regexps (identified by index) which are later
35
- // replaced.
36
- str = JSON . stringify ( obj , function ( key , value ) {
37
- if ( typeof value === 'function' ) {
38
- return '@__FUNCTION-' + UID + '-' + ( functions . push ( value ) - 1 ) + '__@' ;
43
+ // Returns placeholders for functions and regexps (identified by index)
44
+ // which are later replaced by their string representation.
45
+ function replacer ( key , value ) {
46
+ if ( ! value ) {
47
+ return value ;
48
+ }
49
+
50
+ var type = typeof value ;
51
+
52
+ if ( type === 'object' ) {
53
+ if ( isRegExp ( value ) ) {
54
+ return '@__R-' + UID + '-' + ( regexps . push ( value ) - 1 ) + '__@' ;
55
+ }
56
+
57
+ return value ;
39
58
}
40
59
41
- if ( typeof value === 'object' && isRegExp ( value ) ) {
42
- return '@__REGEXP -' + UID + '-' + ( regexps . push ( value ) - 1 ) + '__@' ;
60
+ if ( type === 'function' ) {
61
+ return '@__F -' + UID + '-' + ( functions . push ( value ) - 1 ) + '__@' ;
43
62
}
44
63
45
64
return value ;
46
- } , space ) ;
65
+ }
66
+
67
+ var str ;
68
+
69
+ // Creates a JSON string representation of the value.
70
+ // NOTE: Node 0.12 goes into slow mode with extra JSON.stringify() args.
71
+ if ( options . isJSON && ! options . space ) {
72
+ str = JSON . stringify ( obj ) ;
73
+ } else {
74
+ str = JSON . stringify ( obj , options . isJSON ? null : replacer , options . space ) ;
75
+ }
47
76
48
77
// Protects against `JSON.stringify()` returning `undefined`, by serializing
49
78
// to the literal string: "undefined".
@@ -54,9 +83,7 @@ module.exports = function serialize(obj, space) {
54
83
// Replace unsafe HTML and invalid JavaScript line terminator chars with
55
84
// their safe Unicode char counterpart. This _must_ happen before the
56
85
// regexps and functions are serialized and added back to the string.
57
- str = str . replace ( UNSAFE_CHARS_REGEXP , function ( unsafeChar ) {
58
- return UNICODE_CHARS [ unsafeChar ] ;
59
- } ) ;
86
+ str = str . replace ( UNSAFE_CHARS_REGEXP , escapeUnsafeChars ) ;
60
87
61
88
if ( functions . length === 0 && regexps . length === 0 ) {
62
89
return str ;
@@ -66,7 +93,7 @@ module.exports = function serialize(obj, space) {
66
93
// string with their string representations. If the original value can not
67
94
// be found, then `undefined` is used.
68
95
return str . replace ( PLACE_HOLDER_REGEXP , function ( match , type , valueIndex ) {
69
- if ( type === 'REGEXP ' ) {
96
+ if ( type === 'R ' ) {
70
97
return regexps [ valueIndex ] . toString ( ) ;
71
98
}
72
99
0 commit comments