UNPKG

3.28 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var FREEZING = require('../internals/freezing');
4var NATIVE_RAW_JSON = require('../internals/native-raw-json');
5var getBuiltIn = require('../internals/get-built-in');
6var call = require('../internals/function-call');
7var uncurryThis = require('../internals/function-uncurry-this');
8var isCallable = require('../internals/is-callable');
9var isRawJSON = require('../internals/is-raw-json');
10var toString = require('../internals/to-string');
11var createProperty = require('../internals/create-property');
12var parseJSONString = require('../internals/parse-json-string');
13var getReplacerFunction = require('../internals/get-json-replacer-function');
14var uid = require('../internals/uid');
15var setInternalState = require('../internals/internal-state').set;
16
17var $String = String;
18var $SyntaxError = SyntaxError;
19var parse = getBuiltIn('JSON', 'parse');
20var $stringify = getBuiltIn('JSON', 'stringify');
21var create = getBuiltIn('Object', 'create');
22var freeze = getBuiltIn('Object', 'freeze');
23var at = uncurryThis(''.charAt);
24var slice = uncurryThis(''.slice);
25var exec = uncurryThis(/./.exec);
26var push = uncurryThis([].push);
27
28var MARK = uid();
29var MARK_LENGTH = MARK.length;
30var ERROR_MESSAGE = 'Unacceptable as raw JSON';
31var IS_WHITESPACE = /^[\t\n\r ]$/;
32
33// `JSON.parse` method
34// https://tc39.es/proposal-json-parse-with-source/#sec-json.israwjson
35// https://github.com/tc39/proposal-json-parse-with-source
36$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, {
37 rawJSON: function rawJSON(text) {
38 var jsonString = toString(text);
39 if (jsonString === '' || exec(IS_WHITESPACE, at(jsonString, 0)) || exec(IS_WHITESPACE, at(jsonString, jsonString.length - 1))) {
40 throw new $SyntaxError(ERROR_MESSAGE);
41 }
42 var parsed = parse(jsonString);
43 if (typeof parsed == 'object' && parsed !== null) throw new $SyntaxError(ERROR_MESSAGE);
44 var obj = create(null);
45 setInternalState(obj, { type: 'RawJSON' });
46 createProperty(obj, 'rawJSON', jsonString);
47 return FREEZING ? freeze(obj) : obj;
48 }
49});
50
51// `JSON.stringify` method
52// https://tc39.es/ecma262/#sec-json.stringify
53// https://github.com/tc39/proposal-json-parse-with-source
54if ($stringify) $({ target: 'JSON', stat: true, arity: 3, forced: !NATIVE_RAW_JSON }, {
55 stringify: function stringify(text, replacer, space) {
56 var replacerFunction = getReplacerFunction(replacer);
57 var rawStrings = [];
58
59 var json = $stringify(text, function (key, value) {
60 // some old implementations (like WebKit) could pass numbers as keys
61 var v = isCallable(replacerFunction) ? call(replacerFunction, this, $String(key), value) : value;
62 return isRawJSON(v) ? MARK + (push(rawStrings, v.rawJSON) - 1) : v;
63 }, space);
64
65 if (typeof json != 'string') return json;
66
67 var result = '';
68 var length = json.length;
69
70 for (var i = 0; i < length; i++) {
71 var chr = at(json, i);
72 if (chr === '"') {
73 var end = parseJSONString(json, ++i).end - 1;
74 var string = slice(json, i, end);
75 result += slice(string, 0, MARK_LENGTH) === MARK
76 ? rawStrings[slice(string, MARK_LENGTH)]
77 : '"' + string + '"';
78 i = end;
79 } else result += chr;
80 }
81
82 return result;
83 }
84});