Merge "Some fixes to our jQuery UI skin for buttons"
[lhc/web/wiklou.git] / resources / mediawiki / mediawiki.user.js
1 /*
2 * Implementation for mediaWiki.user
3 */
4
5 (function( $ ) {
6
7 /**
8 * User object
9 */
10 function User( options, tokens ) {
11
12 /* Private Members */
13
14 var that = this;
15
16 /* Public Members */
17
18 this.options = options || new mw.Map();
19
20 this.tokens = tokens || new mw.Map();
21
22 /* Public Methods */
23
24 /**
25 * Generates a random user session ID (32 alpha-numeric characters).
26 *
27 * This information would potentially be stored in a cookie to identify a user during a
28 * session or series of sessions. Its uniqueness should not be depended on.
29 *
30 * @return String: Random set of 32 alpha-numeric characters
31 */
32 function generateId() {
33 var id = '';
34 var seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
35 for ( var i = 0, r; i < 32; i++ ) {
36 r = Math.floor( Math.random() * seed.length );
37 id += seed.substring( r, r + 1 );
38 }
39 return id;
40 }
41
42 /**
43 * Gets the current user's name.
44 *
45 * @return Mixed: User name string or null if users is anonymous
46 */
47 this.name = function() {
48 return mw.config.get( 'wgUserName' );
49 };
50
51 /**
52 * Checks if the current user is anonymous.
53 *
54 * @return Boolean
55 */
56 this.anonymous = function() {
57 return that.name() ? false : true;
58 };
59
60 /**
61 * Gets a random session ID automatically generated and kept in a cookie.
62 *
63 * This ID is ephemeral for everyone, staying in their browser only until they close
64 * their browser.
65 *
66 * @return String: User name or random session ID
67 */
68 this.sessionId = function () {
69 var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
70 if ( typeof sessionId == 'undefined' || sessionId === null ) {
71 sessionId = generateId();
72 $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
73 }
74 return sessionId;
75 };
76
77 /**
78 * Gets the current user's name or a random ID automatically generated and kept in a cookie.
79 *
80 * This ID is persistent for anonymous users, staying in their browser up to 1 year. The
81 * expiration time is reset each time the ID is queried, so in most cases this ID will
82 * persist until the browser's cookies are cleared or the user doesn't visit for 1 year.
83 *
84 * @return String: User name or random session ID
85 */
86 this.id = function() {
87 var name = that.name();
88 if ( name ) {
89 return name;
90 }
91 var id = $.cookie( 'mediaWiki.user.id' );
92 if ( typeof id == 'undefined' || id === null ) {
93 id = generateId();
94 }
95 // Set cookie if not set, or renew it if already set
96 $.cookie( 'mediaWiki.user.id', id, { 'expires': 365, 'path': '/' } );
97 return id;
98 };
99
100 /**
101 * Gets the user's bucket, placing them in one at random based on set odds if needed.
102 *
103 * @param key String: Name of bucket
104 * @param options Object: Bucket configuration options
105 * @param options.buckets Object: List of bucket-name/relative-probability pairs (required,
106 * must have at least one pair)
107 * @param options.version Number: Version of bucket test, changing this forces rebucketing
108 * (optional, default: 0)
109 * @param options.tracked Boolean: Track the event of bucketing through the API module of
110 * the ClickTracking extension (optional, default: false)
111 * @param options.expires Number: Length of time (in days) until the user gets rebucketed
112 * (optional, default: 30)
113 * @return String: Bucket name - the randomly chosen key of the options.buckets object
114 *
115 * @example
116 * mw.user.bucket( 'test', {
117 * 'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
118 * 'version': 1,
119 * 'tracked': true,
120 * 'expires': 7
121 * } );
122 */
123 this.bucket = function( key, options ) {
124 options = $.extend( {
125 'buckets': {},
126 'version': 0,
127 'tracked': false,
128 'expires': 30
129 }, options || {} );
130 var cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
131 var bucket = null;
132 var version = 0;
133 // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
134 if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
135 var parts = cookie.split( ':' );
136 if ( parts.length > 1 && parts[0] == options.version ) {
137 version = Number( parts[0] );
138 bucket = String( parts[1] );
139 }
140 }
141 if ( bucket === null ) {
142 if ( !$.isPlainObject( options.buckets ) ) {
143 throw 'Invalid buckets error. Object expected for options.buckets.';
144 }
145 version = Number( options.version );
146 // Find range
147 var range = 0, k;
148 for ( k in options.buckets ) {
149 range += options.buckets[k];
150 }
151 // Select random value within range
152 var rand = Math.random() * range;
153 // Determine which bucket the value landed in
154 var total = 0;
155 for ( k in options.buckets ) {
156 bucket = k;
157 total += options.buckets[k];
158 if ( total >= rand ) {
159 break;
160 }
161 }
162 if ( options.tracked ) {
163 mw.loader.using( 'jquery.clickTracking', function() {
164 $.trackAction(
165 'mediaWiki.user.bucket:' + key + '@' + version + ':' + bucket
166 );
167 } );
168 }
169 $.cookie(
170 'mediaWiki.user.bucket:' + key,
171 version + ':' + bucket,
172 { 'path': '/', 'expires': Number( options.expires ) }
173 );
174 }
175 return bucket;
176 };
177 }
178
179 // Extend the skeleton mw.user from mediawiki.js
180 // This is kind of ugly but we're stuck with this for b/c reasons
181 mw.user = new User( mw.user.options, mw.user.tokens );
182
183 })(jQuery);