| 1592 | // Internal: Determines whether the native `JSON.stringify` and `parse` |
| 1593 | // implementations are spec-compliant. Based on work by Ken Snyder. |
| 1594 | function has(name) { |
| 1595 | if (has[name] !== undef) { |
| 1596 | // Return cached feature test result. |
| 1597 | return has[name]; |
| 1598 | } |
| 1599 | |
| 1600 | var isSupported; |
| 1601 | if (name == "bug-string-char-index") { |
| 1602 | // IE <= 7 doesn't support accessing string characters using square |
| 1603 | // bracket notation. IE 8 only supports this for primitives. |
| 1604 | isSupported = "a"[0] != "a"; |
| 1605 | } else if (name == "json") { |
| 1606 | // Indicates whether both `JSON.stringify` and `JSON.parse` are |
| 1607 | // supported. |
| 1608 | isSupported = has("json-stringify") && has("json-parse"); |
| 1609 | } else { |
| 1610 | var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; |
| 1611 | // Test `JSON.stringify`. |
| 1612 | if (name == "json-stringify") { |
| 1613 | var stringify = JSON3.stringify, stringifySupported = typeof stringify == "function" && isExtended; |
| 1614 | if (stringifySupported) { |
| 1615 | // A test function object with a custom `toJSON` method. |
| 1616 | (value = function () { |
| 1617 | return 1; |
| 1618 | }).toJSON = value; |
| 1619 | try { |
| 1620 | stringifySupported = |
| 1621 | // Firefox 3.1b1 and b2 serialize string, number, and boolean |
| 1622 | // primitives as object literals. |
| 1623 | stringify(0) === "0" && |
| 1624 | // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object |
| 1625 | // literals. |
| 1626 | stringify(new Number()) === "0" && |
| 1627 | stringify(new String()) == '""' && |
| 1628 | // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or |
| 1629 | // does not define a canonical JSON representation (this applies to |
| 1630 | // objects with `toJSON` properties as well, *unless* they are nested |
| 1631 | // within an object or array). |
| 1632 | stringify(getClass) === undef && |
| 1633 | // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and |
| 1634 | // FF 3.1b3 pass this test. |
| 1635 | stringify(undef) === undef && |
| 1636 | // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, |
| 1637 | // respectively, if the value is omitted entirely. |
| 1638 | stringify() === undef && |
| 1639 | // FF 3.1b1, 2 throw an error if the given value is not a number, |
| 1640 | // string, array, object, Boolean, or `null` literal. This applies to |
| 1641 | // objects with custom `toJSON` methods as well, unless they are nested |
| 1642 | // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` |
| 1643 | // methods entirely. |
| 1644 | stringify(value) === "1" && |
| 1645 | stringify([value]) == "[1]" && |
| 1646 | // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of |
| 1647 | // `"[null]"`. |
| 1648 | stringify([undef]) == "[null]" && |
| 1649 | // YUI 3.0.0b1 fails to serialize `null` literals. |
| 1650 | stringify(null) == "null" && |
| 1651 | // FF 3.1b1, 2 halts serialization if an array contains a function: |