r87020 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r87019‎ | r87020 | r87021 >
Date:17:30, 27 April 2011
Author:catrope
Status:ok
Tags:
Comment:
1.17wmf1: MFT r86577, r86579, r86657
Modified paths:
  • /branches/wmf/1.17wmf1/resources/Resources.php (modified) (history)
  • /branches/wmf/1.17wmf1/resources/jquery/jquery.json.js (added) (history)
  • /branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.js (modified) (history)

Diff [purge]

Index: branches/wmf/1.17wmf1/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: branches/wmf/1.17wmf1/resources/jquery/jquery.json.js
___________________________________________________________________
Added: svn:eol-style
1182 + native
Added: svn:mime-type
2183 + text/plain
Index: branches/wmf/1.17wmf1/resources/Resources.php
@@ -65,6 +65,9 @@
6666 'jquery.placeholder' => array(
6767 'scripts' => 'resources/jquery/jquery.placeholder.js'
6868 ),
 69+ 'jquery.json' => array(
 70+ 'scripts' => 'resources/jquery/jquery.json.js',
 71+ ),
6972 'jquery.localize' => array(
7073 'scripts' => 'resources/jquery/jquery.localize.js'
7174 ),
Property changes on: branches/wmf/1.17wmf1/resources/Resources.php
___________________________________________________________________
Modified: svn:mergeinfo
7275 Merged /trunk/phase3/resources/Resources.php:r86577,86579,86657
Index: branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.js
@@ -319,6 +319,82 @@
320320 $.cookie( 'mediaWiki.user.id', id, { 'expires': 365, 'path': '/' } );
321321 return id;
322322 };
 323+
 324+ /**
 325+ * Gets the user's bucket, placing them in one at random based on set odds if needed.
 326+ *
 327+ * @param key String: Name of bucket
 328+ * @param options Object: Bucket configuration options
 329+ * @param options.buckets Object: List of bucket-name/relative-probability pairs (required,
 330+ * must have at least one pair)
 331+ * @param options.version Number: Version of bucket test, changing this forces rebucketing
 332+ * (optional, default: 0)
 333+ * @param options.tracked Boolean: Track the event of bucketing through the API module of
 334+ * the ClickTracking extension (optional, default: false)
 335+ * @param options.expires Number: Length of time (in days) until the user gets rebucketed
 336+ * (optional, default: 30)
 337+ * @return String: Bucket name - the randomly chosen key of the options.buckets object
 338+ *
 339+ * @example
 340+ * mw.user.bucket( 'test', {
 341+ * 'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
 342+ * 'version': 1,
 343+ * 'tracked': true,
 344+ * 'expires': 7
 345+ * } );
 346+ */
 347+ this.bucket = function( key, options ) {
 348+ options = $.extend( {
 349+ 'buckets': {},
 350+ 'version': 0,
 351+ 'tracked': false,
 352+ 'expires': 30
 353+ }, options || {} );
 354+ var cookie = $.cookie( 'mw.user.bucket:' + key );
 355+ var bucket = null;
 356+ var version = 0;
 357+ // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
 358+ if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
 359+ var parts = cookie.split( ':' );
 360+ if ( parts.length > 1 && parts[1] == options.version ) {
 361+ version = Number( parts[0] );
 362+ bucket = Number( parts[1] );
 363+ }
 364+ }
 365+ if ( bucket === null ) {
 366+ if ( !$.isPlainObject( options.buckets ) ) {
 367+ throw 'Invalid buckets error. Object expected for options.buckets.';
 368+ }
 369+ version = Number( options.version );
 370+ // Find range
 371+ var range = 0;
 372+ for ( var k in options.buckets ) {
 373+ range += options.buckets[k];
 374+ }
 375+ // Select random value within range
 376+ var rand = Math.random() * range;
 377+ // Determine which bucket the value landed in
 378+ var total = 0;
 379+ for ( var k in options.buckets ) {
 380+ bucket = k;
 381+ total += options.buckets[k];
 382+ if ( total >= rand ) {
 383+ break;
 384+ }
 385+ }
 386+ if ( options.tracked ) {
 387+ mw.loader.using( 'jquery.clickTracking', function() {
 388+ $.trackAction( 'mw.user.bucket:' + key + '@' + version + ':' + bucket );
 389+ } );
 390+ }
 391+ $.cookie(
 392+ 'mw.user.bucket:' + key,
 393+ version + ':' + bucket,
 394+ { 'path': '/', 'expires': Number( options.expires ) }
 395+ );
 396+ }
 397+ return bucket;
 398+ };
323399 }
324400
325401 /* Public Members */
Property changes on: branches/wmf/1.17wmf1/resources/mediawiki/mediawiki.js
___________________________________________________________________
Modified: svn:mergeinfo
326402 Merged /trunk/phase3/resources/mediawiki/mediawiki.js:r86577,86579,86657

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r86577Added generic bucketing feature to the user object, which handles bucketing u...tparscal23:58, 20 April 2011
r86579Fixed mismatched cookie names, changed to using ":" instead of "-" between co...tparscal00:02, 21 April 2011
r86657Added jquery.json library to core.tparscal19:33, 21 April 2011

Status & tagging log