r88254 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r88253‎ | r88254 | r88255 >
Date:17:58, 16 May 2011
Author:krinkle
Status:ok
Tags:
Comment:
Split mw.user from mediawiki.js into its own module
* Split mw.user from mediawiki.js into its own module
* Except for "new Map()" to "new mw.Map()", no code was changed.
* Merged addModules call in OutputPage->addDefaultModules for "mediawiki.action.view.tablesorting" into existing call to addModules (no need for two calls, addModules takes an array)
* This also makes the mw.loader.load call at the bottom of mediawiki.js redundant (now in dependancies for mediawiki.user in Resources.php)
* Added QUnit test suite for mw.user
Modified paths:
  • /trunk/phase3/includes/OutputPage.php (modified) (history)
  • /trunk/phase3/resources/Resources.php (modified) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.js (modified) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.user.js (added) (history)
  • /trunk/phase3/resources/test/index.html (modified) (history)
  • /trunk/phase3/resources/test/unit/mediawiki/mediawiki.js (modified) (history)
  • /trunk/phase3/resources/test/unit/mediawiki/mediawiki.user.js (added) (history)

Diff [purge]

Index: trunk/phase3/resources/test/index.html
@@ -11,6 +11,7 @@
1212 <script> function startUp(){} </script>
1313 <script src="../mediawiki/mediawiki.js"></script>
1414 <script> mw.config = new mw.Map( false ); </script>
 15+ <script src="../mediawiki/mediawiki.user.js"></script>
1516
1617 <script src="../jquery/jquery.checkboxShiftClick.js"></script>
1718 <script src="../jquery/jquery.client.js"></script>
@@ -31,6 +32,7 @@
3233
3334 <!-- Your test suites go here -->
3435 <script src="unit/mediawiki/mediawiki.js"></script>
 36+ <script src="unit/mediawiki/mediawiki.user.js"></script>
3537 <script src="unit/mediawiki.util/mediawiki.util.js"></script>
3638 <script src="unit/jquery/jquery.colorUtil.js"></script>
3739
Index: trunk/phase3/resources/test/unit/mediawiki/mediawiki.user.js
@@ -0,0 +1,30 @@
 2+module( 'mediawiki.user.js' );
 3+
 4+test( '-- Initial check', function(){
 5+
 6+ ok( mw.user, 'mw.user defined' );
 7+
 8+});
 9+
 10+
 11+test( 'options', function(){
 12+
 13+ ok( mw.user.options instanceof mw.Map, 'options instance of mw.Map' );
 14+
 15+});
 16+
 17+test( 'User login status', function(){
 18+
 19+ deepEqual( mw.user.name(), null, 'user.name() When anonymous' );
 20+ ok( mw.user.anonymous(), 'user.anonymous() When anonymous' );
 21+
 22+ // Not part of startUp module
 23+ mw.config.set( 'wgUserName', 'John' );
 24+
 25+ equal( mw.user.name(), 'John', 'user.name() When logged-in as John' );
 26+ ok( !mw.user.anonymous(), 'user.anonymous() When logged-in' );
 27+
 28+ equal( mw.user.id(), 'John', 'user.id() When logged-in as John' );
 29+
 30+
 31+});
\ No newline at end of file
Property changes on: trunk/phase3/resources/test/unit/mediawiki/mediawiki.user.js
___________________________________________________________________
Added: svn:eol-style
132 + native
Index: trunk/phase3/resources/test/unit/mediawiki/mediawiki.js
@@ -109,24 +109,6 @@
110110 // params, toString, parse, plain, escaped, exists
111111 });
112112
113 -test( 'mw.user', function(){
114 -
115 - ok( mw.user, 'user defined' );
116 - ok( mw.user.options instanceof mw.Map, 'user.options instance of mw.Map' );
117 -
118 - same( mw.user.name(), null, 'user.name() Anonymous' );
119 - ok( mw.user.anonymous(), 'user.anonymous() Anonymous' );
120 -
121 - // Not part of startUp module
122 - mw.config.set( 'wgUserName', 'John' );
123 -
124 - equals( mw.user.name(), 'John', 'user.name() Logged-in' );
125 - ok( !mw.user.anonymous(), 'user.anonymous() Logged-in' );
126 -
127 - equals( mw.user.id(), 'John', 'user.id() Logged-in' );
128 -
129 -});
130 -
131113 test( 'mw.loader', function(){
132114 expect(2);
133115
Index: trunk/phase3/resources/Resources.php
@@ -434,6 +434,12 @@
435435 'mediawiki.htmlform' => array(
436436 'scripts' => 'resources/mediawiki/mediawiki.htmlform.js',
437437 ),
 438+ 'mediawiki.user' => array(
 439+ 'scripts' => 'resources/mediawiki/mediawiki.user.js',
 440+ 'dependencies' => array(
 441+ 'jquery.cookie',
 442+ ),
 443+ ),
438444 'mediawiki.util' => array(
439445 'scripts' => 'resources/mediawiki.util/mediawiki.util.js',
440446 'dependencies' => array(
Index: trunk/phase3/resources/mediawiki/mediawiki.user.js
@@ -0,0 +1,187 @@
 2+/*
 3+ * Implementation for mediaWiki.log stub
 4+ */
 5+
 6+(function( $ ) {
 7+
 8+ /**
 9+ * User object
 10+ */
 11+ function User() {
 12+
 13+ /* Private Members */
 14+
 15+ var that = this;
 16+
 17+ /* Public Members */
 18+
 19+ this.options = new mw.Map();
 20+
 21+ /* Public Methods */
 22+
 23+ /**
 24+ * Generates a random user session ID (32 alpha-numeric characters).
 25+ *
 26+ * This information would potentially be stored in a cookie to identify a user during a
 27+ * session or series of sessions. It's uniqueness should not be depended on.
 28+ *
 29+ * @return string random set of 32 alpha-numeric characters
 30+ */
 31+ function generateId() {
 32+ var id = '';
 33+ var seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
 34+ for ( var i = 0, r; i < 32; i++ ) {
 35+ r = Math.floor( Math.random() * seed.length );
 36+ id += seed.substring( r, r + 1 );
 37+ }
 38+ return id;
 39+ }
 40+
 41+ /**
 42+ * Gets the current user's name.
 43+ *
 44+ * @return mixed user name string or null if users is anonymous
 45+ */
 46+ this.name = function() {
 47+ return mw.config.get( 'wgUserName' );
 48+ };
 49+
 50+ /**
 51+ * Checks if the current user is anonymous.
 52+ *
 53+ * @return boolean
 54+ */
 55+ this.anonymous = function() {
 56+ return that.name() ? false : true;
 57+ };
 58+
 59+ /**
 60+ * Gets a random session ID automatically generated and kept in a cookie.
 61+ *
 62+ * This ID is ephemeral for everyone, staying in their browser only until they close
 63+ * their browser.
 64+ *
 65+ * Do not use this method before the first call to mw.loader.go(), it depends on
 66+ * jquery.cookie, which is added to the first pay-load just after mediaWiki is defined, but
 67+ * won't be loaded until the first call to go().
 68+ *
 69+ * @return string user name or random session ID
 70+ */
 71+ this.sessionId = function () {
 72+ var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
 73+ if ( typeof sessionId == 'undefined' || sessionId === null ) {
 74+ sessionId = generateId();
 75+ $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
 76+ }
 77+ return sessionId;
 78+ };
 79+
 80+ /**
 81+ * Gets the current user's name or a random ID automatically generated and kept in a cookie.
 82+ *
 83+ * This ID is persistent for anonymous users, staying in their browser up to 1 year. The
 84+ * expiration time is reset each time the ID is queried, so in most cases this ID will
 85+ * persist until the browser's cookies are cleared or the user doesn't visit for 1 year.
 86+ *
 87+ * Do not use this method before the first call to mw.loader.go(), it depends on
 88+ * jquery.cookie, which is added to the first pay-load just after mediaWiki is defined, but
 89+ * won't be loaded until the first call to go().
 90+ *
 91+ * @return string user name or random session ID
 92+ */
 93+ this.id = function() {
 94+ var name = that.name();
 95+ if ( name ) {
 96+ return name;
 97+ }
 98+ var id = $.cookie( 'mediaWiki.user.id' );
 99+ if ( typeof id == 'undefined' || id === null ) {
 100+ id = generateId();
 101+ }
 102+ // Set cookie if not set, or renew it if already set
 103+ $.cookie( 'mediaWiki.user.id', id, { 'expires': 365, 'path': '/' } );
 104+ return id;
 105+ };
 106+
 107+ /**
 108+ * Gets the user's bucket, placing them in one at random based on set odds if needed.
 109+ *
 110+ * @param key String: Name of bucket
 111+ * @param options Object: Bucket configuration options
 112+ * @param options.buckets Object: List of bucket-name/relative-probability pairs (required,
 113+ * must have at least one pair)
 114+ * @param options.version Number: Version of bucket test, changing this forces rebucketing
 115+ * (optional, default: 0)
 116+ * @param options.tracked Boolean: Track the event of bucketing through the API module of
 117+ * the ClickTracking extension (optional, default: false)
 118+ * @param options.expires Number: Length of time (in days) until the user gets rebucketed
 119+ * (optional, default: 30)
 120+ * @return String: Bucket name - the randomly chosen key of the options.buckets object
 121+ *
 122+ * @example
 123+ * mw.user.bucket( 'test', {
 124+ * 'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
 125+ * 'version': 1,
 126+ * 'tracked': true,
 127+ * 'expires': 7
 128+ * } );
 129+ */
 130+ this.bucket = function( key, options ) {
 131+ options = $.extend( {
 132+ 'buckets': {},
 133+ 'version': 0,
 134+ 'tracked': false,
 135+ 'expires': 30
 136+ }, options || {} );
 137+ var cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
 138+ var bucket = null;
 139+ var version = 0;
 140+ // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
 141+ if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
 142+ var parts = cookie.split( ':' );
 143+ if ( parts.length > 1 && parts[0] == options.version ) {
 144+ version = Number( parts[0] );
 145+ bucket = String( parts[1] );
 146+ }
 147+ }
 148+ if ( bucket === null ) {
 149+ if ( !$.isPlainObject( options.buckets ) ) {
 150+ throw 'Invalid buckets error. Object expected for options.buckets.';
 151+ }
 152+ version = Number( options.version );
 153+ // Find range
 154+ var range = 0, k;
 155+ for ( k in options.buckets ) {
 156+ range += options.buckets[k];
 157+ }
 158+ // Select random value within range
 159+ var rand = Math.random() * range;
 160+ // Determine which bucket the value landed in
 161+ var total = 0;
 162+ for ( k in options.buckets ) {
 163+ bucket = k;
 164+ total += options.buckets[k];
 165+ if ( total >= rand ) {
 166+ break;
 167+ }
 168+ }
 169+ if ( options.tracked ) {
 170+ mw.loader.using( 'jquery.clickTracking', function() {
 171+ $.trackAction(
 172+ 'mediaWiki.user.bucket:' + key + '@' + version + ':' + bucket
 173+ );
 174+ } );
 175+ }
 176+ $.cookie(
 177+ 'mediaWiki.user.bucket:' + key,
 178+ version + ':' + bucket,
 179+ { 'path': '/', 'expires': Number( options.expires ) }
 180+ );
 181+ }
 182+ return bucket;
 183+ };
 184+ }
 185+
 186+ mw.user = new User();
 187+
 188+})(jQuery);
\ No newline at end of file
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.user.js
___________________________________________________________________
Added: svn:eol-style
1189 + native
Index: trunk/phase3/resources/mediawiki/mediawiki.js
@@ -306,184 +306,6 @@
307307 return this.map.exists( this.key );
308308 };
309309
310 - /**
311 - * User object
312 - */
313 - function User() {
314 -
315 - /* Private Members */
316 -
317 - var that = this;
318 -
319 - /* Public Members */
320 -
321 - this.options = new Map();
322 -
323 - /* Public Methods */
324 -
325 - /**
326 - * Generates a random user session ID (32 alpha-numeric characters).
327 - *
328 - * This information would potentially be stored in a cookie to identify a user during a
329 - * session or series of sessions. It's uniqueness should not be depended on.
330 - *
331 - * @return string random set of 32 alpha-numeric characters
332 - */
333 - function generateId() {
334 - var id = '';
335 - var seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
336 - for ( var i = 0, r; i < 32; i++ ) {
337 - r = Math.floor( Math.random() * seed.length );
338 - id += seed.substring( r, r + 1 );
339 - }
340 - return id;
341 - }
342 -
343 - /**
344 - * Gets the current user's name.
345 - *
346 - * @return mixed user name string or null if users is anonymous
347 - */
348 - this.name = function() {
349 - return mw.config.get( 'wgUserName' );
350 - };
351 -
352 - /**
353 - * Checks if the current user is anonymous.
354 - *
355 - * @return boolean
356 - */
357 - this.anonymous = function() {
358 - return that.name() ? false : true;
359 - };
360 -
361 - /**
362 - * Gets a random session ID automatically generated and kept in a cookie.
363 - *
364 - * This ID is ephemeral for everyone, staying in their browser only until they close
365 - * their browser.
366 - *
367 - * Do not use this method before the first call to mw.loader.go(), it depends on
368 - * jquery.cookie, which is added to the first pay-load just after mediaWiki is defined, but
369 - * won't be loaded until the first call to go().
370 - *
371 - * @return string user name or random session ID
372 - */
373 - this.sessionId = function () {
374 - var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
375 - if ( typeof sessionId == 'undefined' || sessionId === null ) {
376 - sessionId = generateId();
377 - $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
378 - }
379 - return sessionId;
380 - };
381 -
382 - /**
383 - * Gets the current user's name or a random ID automatically generated and kept in a cookie.
384 - *
385 - * This ID is persistent for anonymous users, staying in their browser up to 1 year. The
386 - * expiration time is reset each time the ID is queried, so in most cases this ID will
387 - * persist until the browser's cookies are cleared or the user doesn't visit for 1 year.
388 - *
389 - * Do not use this method before the first call to mw.loader.go(), it depends on
390 - * jquery.cookie, which is added to the first pay-load just after mediaWiki is defined, but
391 - * won't be loaded until the first call to go().
392 - *
393 - * @return string user name or random session ID
394 - */
395 - this.id = function() {
396 - var name = that.name();
397 - if ( name ) {
398 - return name;
399 - }
400 - var id = $.cookie( 'mediaWiki.user.id' );
401 - if ( typeof id == 'undefined' || id === null ) {
402 - id = generateId();
403 - }
404 - // Set cookie if not set, or renew it if already set
405 - $.cookie( 'mediaWiki.user.id', id, { 'expires': 365, 'path': '/' } );
406 - return id;
407 - };
408 -
409 - /**
410 - * Gets the user's bucket, placing them in one at random based on set odds if needed.
411 - *
412 - * @param key String: Name of bucket
413 - * @param options Object: Bucket configuration options
414 - * @param options.buckets Object: List of bucket-name/relative-probability pairs (required,
415 - * must have at least one pair)
416 - * @param options.version Number: Version of bucket test, changing this forces rebucketing
417 - * (optional, default: 0)
418 - * @param options.tracked Boolean: Track the event of bucketing through the API module of
419 - * the ClickTracking extension (optional, default: false)
420 - * @param options.expires Number: Length of time (in days) until the user gets rebucketed
421 - * (optional, default: 30)
422 - * @return String: Bucket name - the randomly chosen key of the options.buckets object
423 - *
424 - * @example
425 - * mw.user.bucket( 'test', {
426 - * 'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
427 - * 'version': 1,
428 - * 'tracked': true,
429 - * 'expires': 7
430 - * } );
431 - */
432 - this.bucket = function( key, options ) {
433 - options = $.extend( {
434 - 'buckets': {},
435 - 'version': 0,
436 - 'tracked': false,
437 - 'expires': 30
438 - }, options || {} );
439 - var cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
440 - var bucket = null;
441 - var version = 0;
442 - // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
443 - if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
444 - var parts = cookie.split( ':' );
445 - if ( parts.length > 1 && parts[0] == options.version ) {
446 - version = Number( parts[0] );
447 - bucket = String( parts[1] );
448 - }
449 - }
450 - if ( bucket === null ) {
451 - if ( !$.isPlainObject( options.buckets ) ) {
452 - throw 'Invalid buckets error. Object expected for options.buckets.';
453 - }
454 - version = Number( options.version );
455 - // Find range
456 - var range = 0, k;
457 - for ( k in options.buckets ) {
458 - range += options.buckets[k];
459 - }
460 - // Select random value within range
461 - var rand = Math.random() * range;
462 - // Determine which bucket the value landed in
463 - var total = 0;
464 - for ( k in options.buckets ) {
465 - bucket = k;
466 - total += options.buckets[k];
467 - if ( total >= rand ) {
468 - break;
469 - }
470 - }
471 - if ( options.tracked ) {
472 - mw.loader.using( 'jquery.clickTracking', function() {
473 - $.trackAction(
474 - 'mediaWiki.user.bucket:' + key + '@' + version + ':' + bucket
475 - );
476 - } );
477 - }
478 - $.cookie(
479 - 'mediaWiki.user.bucket:' + key,
480 - version + ':' + bucket,
481 - { 'path': '/', 'expires': Number( options.expires ) }
482 - );
483 - }
484 - return bucket;
485 - };
486 - }
487 -
488310 /* Public Members */
489311
490312 /*
@@ -507,11 +329,6 @@
508330 this.config = null;
509331
510332 /*
511 - * Information about the current user
512 - */
513 - this.user = new User();
514 -
515 - /*
516333 * Localization system
517334 */
518335 this.messages = new this.Map();
@@ -1434,6 +1251,3 @@
14351252 startUp();
14361253 delete startUp;
14371254 }
1438 -
1439 -// Add jQuery Cookie to initial payload (used in mw.user)
1440 -mw.loader.load( 'jquery.cookie' );
Index: trunk/phase3/includes/OutputPage.php
@@ -2335,8 +2335,8 @@
23362336 $wgUseAjax, $wgAjaxWatch, $wgEnableMWSuggest;
23372337
23382338 // Add base resources
2339 - $this->addModules( 'mediawiki.util' );
2340 - if( $wgIncludeLegacyJavaScript ){
 2339+ $this->addModules( array( 'mediawiki.user', 'mediawiki.util', 'mediawiki.action.view.tablesorting' ) );
 2340+ if ( $wgIncludeLegacyJavaScript ){
23412341 $this->addModules( 'mediawiki.legacy.wikibits' );
23422342 }
23432343
@@ -2358,7 +2358,6 @@
23592359 if( $this->getUser()->getBoolOption( 'editsectiononrightclick' ) ) {
23602360 $this->addModules( 'mediawiki.action.view.rightClickEdit' );
23612361 }
2362 - $this->addModules( 'mediawiki.action.view.tablesorting' );
23632362 }
23642363
23652364 /**

Status & tagging log