| 1062 | // Internal: Determines whether the native `JSON.stringify` and `parse` |
| 1063 | // implementations are spec-compliant. Based on work by Ken Snyder. |
| 1064 | function has(name) { |
| 1065 | if (has[name] !== undef) { |
| 1066 | // Return cached feature test result. |
| 1067 | return has[name]; |
| 1068 | } |
| 1069 | var isSupported; |
| 1070 | if (name == "bug-string-char-index") { |
| 1071 | // IE <= 7 doesn't support accessing string characters using square |
| 1072 | // bracket notation. IE 8 only supports this for primitives. |
| 1073 | isSupported = "a"[0] != "a"; |
| 1074 | } else if (name == "json") { |
| 1075 | // Indicates whether both `JSON.stringify` and `JSON.parse` are |
| 1076 | // supported. |
| 1077 | isSupported = has("json-stringify") && has("json-parse"); |
| 1078 | } else { |
| 1079 | var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; |
| 1080 | // Test `JSON.stringify`. |
| 1081 | if (name == "json-stringify") { |
| 1082 | var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended; |
| 1083 | if (stringifySupported) { |
| 1084 | // A test function object with a custom `toJSON` method. |
| 1085 | (value = function () { |
| 1086 | return 1; |
| 1087 | }).toJSON = value; |
| 1088 | try { |
| 1089 | stringifySupported = |
| 1090 | // Firefox 3.1b1 and b2 serialize string, number, and boolean |
| 1091 | // primitives as object literals. |
| 1092 | stringify(0) === "0" && |
| 1093 | // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object |
| 1094 | // literals. |
| 1095 | stringify(new Number()) === "0" && |
| 1096 | stringify(new String()) == '""' && |
| 1097 | // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or |
| 1098 | // does not define a canonical JSON representation (this applies to |
| 1099 | // objects with `toJSON` properties as well, *unless* they are nested |
| 1100 | // within an object or array). |
| 1101 | stringify(getClass) === undef && |
| 1102 | // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and |
| 1103 | // FF 3.1b3 pass this test. |
| 1104 | stringify(undef) === undef && |
| 1105 | // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, |
| 1106 | // respectively, if the value is omitted entirely. |
| 1107 | stringify() === undef && |
| 1108 | // FF 3.1b1, 2 throw an error if the given value is not a number, |
| 1109 | // string, array, object, Boolean, or `null` literal. This applies to |
| 1110 | // objects with custom `toJSON` methods as well, unless they are nested |
| 1111 | // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` |
| 1112 | // methods entirely. |
| 1113 | stringify(value) === "1" && |
| 1114 | stringify([value]) == "[1]" && |
| 1115 | // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of |
| 1116 | // `"[null]"`. |
| 1117 | stringify([undef]) == "[null]" && |
| 1118 | // YUI 3.0.0b1 fails to serialize `null` literals. |
| 1119 | stringify(null) == "null" && |
| 1120 | // FF 3.1b1, 2 halts serialization if an array contains a function: |
| 1121 | // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 |