r86657 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r86656‎ | r86657 | r86658 >
Date:19:33, 21 April 2011
Author:tparscal
Status:ok (Comments)
Tags:
Comment:
Added jquery.json library to core.
Modified paths:
  • /trunk/phase3/resources/Resources.php (modified) (history)
  • /trunk/phase3/resources/jquery/jquery.json.js (added) (history)

Diff [purge]

Index: trunk/phase3/resources/jquery/jquery.json.js
@@ -0,0 +1,180 @@
 2+/*
 3+ * jQuery JSON Plugin
 4+ * version: 2.1 (2009-08-14)
 5+ *
 6+ * This document is licensed as free software under the terms of the
 7+ * MIT License: http://www.opensource.org/licenses/mit-license.php
 8+ *
 9+ * Brantley Harris wrote this plugin. It is based somewhat on the JSON.org
 10+ * website's http://www.json.org/json2.js, which proclaims:
 11+ * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
 12+ * I uphold.
 13+ *
 14+ * It is also influenced heavily by MochiKit's serializeJSON, which is
 15+ * copyrighted 2005 by Bob Ippolito.
 16+ *
 17+ * @see http://code.google.com/p/jquery-json/
 18+ */
 19+
 20+(function($) {
 21+ /** jQuery.toJSON( json-serializble )
 22+ Converts the given argument into a JSON respresentation.
 23+
 24+ If an object has a "toJSON" function, that will be used to get the representation.
 25+ Non-integer/string keys are skipped in the object, as are keys that point to a function.
 26+
 27+ json-serializble:
 28+ The *thing* to be converted.
 29+ **/
 30+ $.toJSON = function(o)
 31+ {
 32+ if (typeof(JSON) == 'object' && JSON.stringify)
 33+ return JSON.stringify(o);
 34+
 35+ var type = typeof(o);
 36+
 37+ if (o === null)
 38+ return "null";
 39+
 40+ if (type == "undefined")
 41+ return undefined;
 42+
 43+ if (type == "number" || type == "boolean")
 44+ return o + "";
 45+
 46+ if (type == "string")
 47+ return $.quoteString(o);
 48+
 49+ if (type == 'object')
 50+ {
 51+ if (typeof o.toJSON == "function")
 52+ return $.toJSON( o.toJSON() );
 53+
 54+ if (o.constructor === Date)
 55+ {
 56+ var month = o.getUTCMonth() + 1;
 57+ if (month < 10) month = '0' + month;
 58+
 59+ var day = o.getUTCDate();
 60+ if (day < 10) day = '0' + day;
 61+
 62+ var year = o.getUTCFullYear();
 63+
 64+ var hours = o.getUTCHours();
 65+ if (hours < 10) hours = '0' + hours;
 66+
 67+ var minutes = o.getUTCMinutes();
 68+ if (minutes < 10) minutes = '0' + minutes;
 69+
 70+ var seconds = o.getUTCSeconds();
 71+ if (seconds < 10) seconds = '0' + seconds;
 72+
 73+ var milli = o.getUTCMilliseconds();
 74+ if (milli < 100) milli = '0' + milli;
 75+ if (milli < 10) milli = '0' + milli;
 76+
 77+ return '"' + year + '-' + month + '-' + day + 'T' +
 78+ hours + ':' + minutes + ':' + seconds +
 79+ '.' + milli + 'Z"';
 80+ }
 81+
 82+ if (o.constructor === Array)
 83+ {
 84+ var ret = [];
 85+ for (var i = 0; i < o.length; i++)
 86+ ret.push( $.toJSON(o[i]) || "null" );
 87+
 88+ return "[" + ret.join(",") + "]";
 89+ }
 90+
 91+ var pairs = [];
 92+ for (var k in o) {
 93+ var name;
 94+ var type = typeof k;
 95+
 96+ if (type == "number")
 97+ name = '"' + k + '"';
 98+ else if (type == "string")
 99+ name = $.quoteString(k);
 100+ else
 101+ continue; //skip non-string or number keys
 102+
 103+ if (typeof o[k] == "function")
 104+ continue; //skip pairs where the value is a function.
 105+
 106+ var val = $.toJSON(o[k]);
 107+
 108+ pairs.push(name + ":" + val);
 109+ }
 110+
 111+ return "{" + pairs.join(", ") + "}";
 112+ }
 113+ };
 114+
 115+ /** jQuery.evalJSON(src)
 116+ Evaluates a given piece of json source.
 117+ **/
 118+ $.evalJSON = function(src)
 119+ {
 120+ if (typeof(JSON) == 'object' && JSON.parse)
 121+ return JSON.parse(src);
 122+ return eval("(" + src + ")");
 123+ };
 124+
 125+ /** jQuery.secureEvalJSON(src)
 126+ Evals JSON in a way that is *more* secure.
 127+ **/
 128+ $.secureEvalJSON = function(src)
 129+ {
 130+ if (typeof(JSON) == 'object' && JSON.parse)
 131+ return JSON.parse(src);
 132+
 133+ var filtered = src;
 134+ filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
 135+ filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
 136+ filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
 137+
 138+ if (/^[\],:{}\s]*$/.test(filtered))
 139+ return eval("(" + src + ")");
 140+ else
 141+ throw new SyntaxError("Error parsing JSON, source is not valid.");
 142+ };
 143+
 144+ /** jQuery.quoteString(string)
 145+ Returns a string-repr of a string, escaping quotes intelligently.
 146+ Mostly a support function for toJSON.
 147+
 148+ Examples:
 149+ >>> jQuery.quoteString("apple")
 150+ "apple"
 151+
 152+ >>> jQuery.quoteString('"Where are we going?", she asked.')
 153+ "\"Where are we going?\", she asked."
 154+ **/
 155+ $.quoteString = function(string)
 156+ {
 157+ if (string.match(_escapeable))
 158+ {
 159+ return '"' + string.replace(_escapeable, function (a)
 160+ {
 161+ var c = _meta[a];
 162+ if (typeof c === 'string') return c;
 163+ c = a.charCodeAt();
 164+ return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
 165+ }) + '"';
 166+ }
 167+ return '"' + string + '"';
 168+ };
 169+
 170+ var _escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
 171+
 172+ var _meta = {
 173+ '\b': '\\b',
 174+ '\t': '\\t',
 175+ '\n': '\\n',
 176+ '\f': '\\f',
 177+ '\r': '\\r',
 178+ '"' : '\\"',
 179+ '\\': '\\\\'
 180+ };
 181+})(jQuery);
Property changes on: trunk/phase3/resources/jquery/jquery.json.js
___________________________________________________________________
Added: svn:eol-style
1182 + native
Added: svn:mime-type
2183 + text/plain
Index: trunk/phase3/resources/Resources.php
@@ -114,6 +114,9 @@
115115 'jquery.placeholder' => array(
116116 'scripts' => 'resources/jquery/jquery.placeholder.js',
117117 ),
 118+ 'jquery.json' => array(
 119+ 'scripts' => 'resources/jquery/jquery.json.js',
 120+ ),
118121 'jquery.localize' => array(
119122 'scripts' => 'resources/jquery/jquery.localize.js',
120123 ),

Follow-up revisions

RevisionCommit summaryAuthorDate
r870201.17wmf1: MFT r86577, r86579, r86657catrope17:30, 27 April 2011
r87921remove jquery.json from InlineEditor (dupe)...hashar18:34, 12 May 2011

Comments

#Comment by JanPaul123 (talk | contribs)   20:56, 23 April 2011

Perhaps it'd be good to do $.evalJSON = $.secureEvalJSON - there is no reason not to do it securely, with the filtering regexes.

#Comment by Krinkle (talk | contribs)   20:59, 23 April 2011

I'd say request it upstream.

Possible reasons not to would be backwards compatibility and/or problems with $.secureEvalJSON (ie. it replacing things it shouldn't in some edge cases).

If MediaWiki does not want people to use it non-secure, I'd recommend doing $.evalJSON = null; instead of $.evalJSON = $.secureEvalJSON;. That way people that are familiar with the Google Code project won't get confused when something goes wrong.

#Comment by JanPaul123 (talk | contribs)   21:03, 23 April 2011

As it's like this by design, I don't think they'll "fix" it upstream. Your suggestion of $.evalJSON = null; makes sense!

#Comment by Fomafix (talk | contribs)   11:13, 29 April 2011

What is faster?

'\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16)

or

'\\u' + ('000' + c.toString(16)).substr(-4)
#Comment by Dantman (talk | contribs)   11:55, 29 April 2011

Both only take 0.0003ms in FF3, no difference. Second one however looks saner code wise.

#Comment by Krinkle (talk | contribs)   17:27, 29 April 2011

For what it's worth:

r86657-cr http://jsperf.com/mediawiki-r86657-cr

The former seems to be faster.

#Comment by Krinkle (talk | contribs)   17:30, 29 April 2011

Okay, so CR parsing is messing up as usual. Second attempt: http://jsperf.com/mediawiki-r86657-cr

#Comment by Dantman (talk | contribs)   20:42, 29 April 2011
/ that tool doesn't want to add Konqueror to the list of browsers:

A: 336,372 ±2.94%22% slower B: 430,547 ±1.39% fastest

So the first is slightly faster in Chrome, Opera, Safari, and Midori. While the latter is slightly faster in Firefox and Konqueror.

Not that the speed difference is in any way notable.

Status & tagging log