项目原始demo,不改动
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。
 
 
 
 

120 行
3.8 KiB

  1. /*
  2. Copyright (c) 2014, Yahoo! Inc. All rights reserved.
  3. Copyrights licensed under the New BSD License.
  4. See the accompanying LICENSE file for terms.
  5. */
  6. 'use strict';
  7. // Generate an internal UID to make the regexp pattern harder to guess.
  8. var UID = Math.floor(Math.random() * 0x10000000000).toString(16);
  9. var PLACE_HOLDER_REGEXP = new RegExp('"@__(F|R|D)-' + UID + '-(\\d+)__@"', 'g');
  10. var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g;
  11. var UNSAFE_CHARS_REGEXP = /[<>\/\u2028\u2029]/g;
  12. // Mapping of unsafe HTML and invalid JavaScript line terminator chars to their
  13. // Unicode char counterparts which are safe to use in JavaScript strings.
  14. var ESCAPED_CHARS = {
  15. '<' : '\\u003C',
  16. '>' : '\\u003E',
  17. '/' : '\\u002F',
  18. '\u2028': '\\u2028',
  19. '\u2029': '\\u2029'
  20. };
  21. function escapeUnsafeChars(unsafeChar) {
  22. return ESCAPED_CHARS[unsafeChar];
  23. }
  24. module.exports = function serialize(obj, options) {
  25. options || (options = {});
  26. // Backwards-compatibility for `space` as the second argument.
  27. if (typeof options === 'number' || typeof options === 'string') {
  28. options = {space: options};
  29. }
  30. var functions = [];
  31. var regexps = [];
  32. var dates = [];
  33. // Returns placeholders for functions and regexps (identified by index)
  34. // which are later replaced by their string representation.
  35. function replacer(key, value) {
  36. if (!value) {
  37. return value;
  38. }
  39. // If the value is an object w/ a toJSON method, toJSON is called before
  40. // the replacer runs, so we use this[key] to get the non-toJSONed value.
  41. var origValue = this[key];
  42. var type = typeof origValue;
  43. if (type === 'object') {
  44. if(origValue instanceof RegExp) {
  45. return '@__R-' + UID + '-' + (regexps.push(origValue) - 1) + '__@';
  46. }
  47. if(origValue instanceof Date) {
  48. return '@__D-' + UID + '-' + (dates.push(origValue) - 1) + '__@';
  49. }
  50. }
  51. if (type === 'function') {
  52. return '@__F-' + UID + '-' + (functions.push(origValue) - 1) + '__@';
  53. }
  54. return value;
  55. }
  56. var str;
  57. // Creates a JSON string representation of the value.
  58. // NOTE: Node 0.12 goes into slow mode with extra JSON.stringify() args.
  59. if (options.isJSON && !options.space) {
  60. str = JSON.stringify(obj);
  61. } else {
  62. str = JSON.stringify(obj, options.isJSON ? null : replacer, options.space);
  63. }
  64. // Protects against `JSON.stringify()` returning `undefined`, by serializing
  65. // to the literal string: "undefined".
  66. if (typeof str !== 'string') {
  67. return String(str);
  68. }
  69. // Replace unsafe HTML and invalid JavaScript line terminator chars with
  70. // their safe Unicode char counterpart. This _must_ happen before the
  71. // regexps and functions are serialized and added back to the string.
  72. if (options.unsafe !== true) {
  73. str = str.replace(UNSAFE_CHARS_REGEXP, escapeUnsafeChars);
  74. }
  75. if (functions.length === 0 && regexps.length === 0 && dates.length === 0) {
  76. return str;
  77. }
  78. // Replaces all occurrences of function, regexp and date placeholders in the
  79. // JSON string with their string representations. If the original value can
  80. // not be found, then `undefined` is used.
  81. return str.replace(PLACE_HOLDER_REGEXP, function (match, type, valueIndex) {
  82. if (type === 'D') {
  83. return "new Date(\"" + dates[valueIndex].toISOString() + "\")";
  84. }
  85. if (type === 'R') {
  86. return regexps[valueIndex].toString();
  87. }
  88. var fn = functions[valueIndex];
  89. var serializedFn = fn.toString();
  90. if (IS_NATIVE_CODE_REGEXP.test(serializedFn)) {
  91. throw new TypeError('Serializing native function: ' + fn.name);
  92. }
  93. return serializedFn;
  94. });
  95. }