Commit dc74340733f187dc3d562079b55d5667759a9d41

Authored by Georg Hopp
1 parent 97e13be4

--no commit message

Showing 2 changed files with 320 additions and 0 deletions
@@ -5,3 +5,4 @@ @@ -5,3 +5,4 @@
5 Siehe: 5 Siehe:
6 http://www.admin-wissen.de/tutorials/eigene-tutorials/webentwicklung/ajax-tutorial/ 6 http://www.admin-wissen.de/tutorials/eigene-tutorials/webentwicklung/ajax-tutorial/
7 http://www.json.org/ 7 http://www.json.org/
  8 + http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
  1 +/*
  2 + json.js
  3 + 2007-10-10
  4 +
  5 + Public Domain
  6 +
  7 + This file adds these methods to JavaScript:
  8 +
  9 + array.toJSONString(whitelist)
  10 + boolean.toJSONString()
  11 + date.toJSONString()
  12 + number.toJSONString()
  13 + object.toJSONString(whitelist)
  14 + string.toJSONString()
  15 + These methods produce a JSON text from a JavaScript value.
  16 + It must not contain any cyclical references. Illegal values
  17 + will be excluded.
  18 +
  19 + The default conversion for dates is to an ISO string. You can
  20 + add a toJSONString method to any date object to get a different
  21 + representation.
  22 +
  23 + The object and array methods can take an optional whitelist
  24 + argument. A whitelist is an array of strings. If it is provided,
  25 + keys in objects not found in the whitelist are excluded.
  26 +
  27 + string.parseJSON(filter)
  28 + This method parses a JSON text to produce an object or
  29 + array. It can throw a SyntaxError exception.
  30 +
  31 + The optional filter parameter is a function which can filter and
  32 + transform the results. It receives each of the keys and values, and
  33 + its return value is used instead of the original value. If it
  34 + returns what it received, then structure is not modified. If it
  35 + returns undefined then the member is deleted.
  36 +
  37 + Example:
  38 +
  39 + // Parse the text. If a key contains the string 'date' then
  40 + // convert the value to a date.
  41 +
  42 + myData = text.parseJSON(function (key, value) {
  43 + return key.indexOf('date') >= 0 ? new Date(value) : value;
  44 + });
  45 +
  46 + It is expected that these methods will formally become part of the
  47 + JavaScript Programming Language in the Fourth Edition of the
  48 + ECMAScript standard in 2008.
  49 +
  50 + This file will break programs with improper for..in loops. See
  51 + http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
  52 +
  53 + This is a reference implementation. You are free to copy, modify, or
  54 + redistribute.
  55 +
  56 + Use your own copy. It is extremely unwise to load untrusted third party
  57 + code into your pages.
  58 +*/
  59 +
  60 +/*jslint evil: true */
  61 +
  62 +// Augment the basic prototypes if they have not already been augmented.
  63 +
  64 +if (!Object.prototype.toJSONString) {
  65 +
  66 + Array.prototype.toJSONString = function (w) {
  67 + var a = [], // The array holding the partial texts.
  68 + i, // Loop counter.
  69 + l = this.length,
  70 + v; // The value to be stringified.
  71 +
  72 +// For each value in this array...
  73 +
  74 + for (i = 0; i < l; i += 1) {
  75 + v = this[i];
  76 + switch (typeof v) {
  77 + case 'object':
  78 +
  79 +// Serialize a JavaScript object value. Treat objects thats lack the
  80 +// toJSONString method as null. Due to a specification error in ECMAScript,
  81 +// typeof null is 'object', so watch out for that case.
  82 +
  83 + if (v && typeof v.toJSONString === 'function') {
  84 + a.push(v.toJSONString(w));
  85 + } else {
  86 + a.push('null');
  87 + }
  88 + break;
  89 +
  90 + case 'string':
  91 + case 'number':
  92 + case 'boolean':
  93 + a.push(v.toJSONString());
  94 + break;
  95 + default:
  96 + a.push('null');
  97 + }
  98 + }
  99 +
  100 +// Join all of the member texts together and wrap them in brackets.
  101 +
  102 + return '[' + a.join(',') + ']';
  103 + };
  104 +
  105 +
  106 + Boolean.prototype.toJSONString = function () {
  107 + return String(this);
  108 + };
  109 +
  110 +
  111 + Date.prototype.toJSONString = function () {
  112 +
  113 +// Eventually, this method will be based on the date.toISOString method.
  114 +
  115 + function f(n) {
  116 +
  117 +// Format integers to have at least two digits.
  118 +
  119 + return n < 10 ? '0' + n : n;
  120 + }
  121 +
  122 + return '"' + this.getUTCFullYear() + '-' +
  123 + f(this.getUTCMonth() + 1) + '-' +
  124 + f(this.getUTCDate()) + 'T' +
  125 + f(this.getUTCHours()) + ':' +
  126 + f(this.getUTCMinutes()) + ':' +
  127 + f(this.getUTCSeconds()) + 'Z"';
  128 + };
  129 +
  130 +
  131 + Number.prototype.toJSONString = function () {
  132 +
  133 +// JSON numbers must be finite. Encode non-finite numbers as null.
  134 +
  135 + return isFinite(this) ? String(this) : 'null';
  136 + };
  137 +
  138 +
  139 + Object.prototype.toJSONString = function (w) {
  140 + var a = [], // The array holding the partial texts.
  141 + k, // The current key.
  142 + i, // The loop counter.
  143 + v; // The current value.
  144 +
  145 +// If a whitelist (array of keys) is provided, use it assemble the components
  146 +// of the object.
  147 +
  148 + if (w) {
  149 + for (i = 0; i < w.length; i += 1) {
  150 + k = w[i];
  151 + if (typeof k === 'string') {
  152 + v = this[k];
  153 + switch (typeof v) {
  154 + case 'object':
  155 +
  156 +// Serialize a JavaScript object value. Ignore objects that lack the
  157 +// toJSONString method. Due to a specification error in ECMAScript,
  158 +// typeof null is 'object', so watch out for that case.
  159 +
  160 + if (v) {
  161 + if (typeof v.toJSONString === 'function') {
  162 + a.push(k.toJSONString() + ':' +
  163 + v.toJSONString(w));
  164 + }
  165 + } else {
  166 + a.push(k.toJSONString() + ':null');
  167 + }
  168 + break;
  169 +
  170 + case 'string':
  171 + case 'number':
  172 + case 'boolean':
  173 + a.push(k.toJSONString() + ':' + v.toJSONString());
  174 +
  175 +// Values without a JSON representation are ignored.
  176 +
  177 + }
  178 + }
  179 + }
  180 + } else {
  181 +
  182 +// Iterate through all of the keys in the object, ignoring the proto chain
  183 +// and keys that are not strings.
  184 +
  185 + for (k in this) {
  186 + if (typeof k === 'string' &&
  187 + Object.prototype.hasOwnProperty.apply(this, [k])) {
  188 + v = this[k];
  189 + switch (typeof v) {
  190 + case 'object':
  191 +
  192 +// Serialize a JavaScript object value. Ignore objects that lack the
  193 +// toJSONString method. Due to a specification error in ECMAScript,
  194 +// typeof null is 'object', so watch out for that case.
  195 +
  196 + if (v) {
  197 + if (typeof v.toJSONString === 'function') {
  198 + a.push(k.toJSONString() + ':' +
  199 + v.toJSONString());
  200 + }
  201 + } else {
  202 + a.push(k.toJSONString() + ':null');
  203 + }
  204 + break;
  205 +
  206 + case 'string':
  207 + case 'number':
  208 + case 'boolean':
  209 + a.push(k.toJSONString() + ':' + v.toJSONString());
  210 +
  211 +// Values without a JSON representation are ignored.
  212 +
  213 + }
  214 + }
  215 + }
  216 + }
  217 +
  218 +// Join all of the member texts together and wrap them in braces.
  219 +
  220 + return '{' + a.join(',') + '}';
  221 + };
  222 +
  223 +
  224 + (function (s) {
  225 +
  226 +// Augment String.prototype. We do this in an immediate anonymous function to
  227 +// avoid defining global variables.
  228 +
  229 +// m is a table of character substitutions.
  230 +
  231 + var m = {
  232 + '\b': '\\b',
  233 + '\t': '\\t',
  234 + '\n': '\\n',
  235 + '\f': '\\f',
  236 + '\r': '\\r',
  237 + '"' : '\\"',
  238 + '\\': '\\\\'
  239 + };
  240 +
  241 +
  242 + s.parseJSON = function (filter) {
  243 + var j;
  244 +
  245 + function walk(k, v) {
  246 + var i, n;
  247 + if (v && typeof v === 'object') {
  248 + for (i in v) {
  249 + if (Object.prototype.hasOwnProperty.apply(v, [i])) {
  250 + n = walk(i, v[i]);
  251 + if (n !== undefined) {
  252 + v[i] = n;
  253 + }
  254 + }
  255 + }
  256 + }
  257 + return filter(k, v);
  258 + }
  259 +
  260 +
  261 +// Parsing happens in three stages. In the first stage, we run the text against
  262 +// a regular expression which looks for non-JSON characters. We are especially
  263 +// concerned with '()' and 'new' because they can cause invocation, and '='
  264 +// because it can cause mutation. But just to be safe, we will reject all
  265 +// unexpected characters.
  266 +
  267 +// We split the first stage into 4 regexp operations in order to work around
  268 +// crippling deficiencies in IE's and Safari's regexp engines. First we replace
  269 +// all backslash pairs with '@' (a non-JSON character). Second, we replace all
  270 +// simple value tokens with ']' characters. Third, we delete all open brackets
  271 +// that follow a colon or comma or that begin the text. Finally, we look to see
  272 +// that the remaining characters are only whitespace or ']' or ',' or ':' or '{'
  273 +// or '}'. If that is so, then the text is safe for eval.
  274 +
  275 + if (/^[\],:{}\s]*$/.test(this.replace(/\\./g, '@').
  276 + replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
  277 + replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  278 +
  279 +// In the second stage we use the eval function to compile the text into a
  280 +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  281 +// in JavaScript: it can begin a block or an object literal. We wrap the text
  282 +// in parens to eliminate the ambiguity.
  283 +
  284 + j = eval('(' + this + ')');
  285 +
  286 +// In the optional third stage, we recursively walk the new structure, passing
  287 +// each name/value pair to a filter function for possible transformation.
  288 +
  289 + return typeof filter === 'function' ? walk('', j) : j;
  290 + }
  291 +
  292 +// If the text is not JSON parseable, then a SyntaxError is thrown.
  293 +
  294 + throw new SyntaxError('parseJSON');
  295 + };
  296 +
  297 +
  298 + s.toJSONString = function () {
  299 +
  300 +// If the string contains no control characters, no quote characters, and no
  301 +// backslash characters, then we can simply slap some quotes around it.
  302 +// Otherwise we must also replace the offending characters with safe
  303 +// sequences.
  304 +
  305 + if (/["\\\x00-\x1f]/.test(this)) {
  306 + return '"' + this.replace(/[\x00-\x1f\\"]/g, function (a) {
  307 + var c = m[a];
  308 + if (c) {
  309 + return c;
  310 + }
  311 + c = a.charCodeAt();
  312 + return '\\u00' + Math.floor(c / 16).toString(16) +
  313 + (c % 16).toString(16);
  314 + }) + '"';
  315 + }
  316 + return '"' + this + '"';
  317 + };
  318 + })(String.prototype);
  319 +}
Please register or login to post a comment