Merge "Whitelist the <wbr> element."
[mediawiki.git] / resources / mediawiki / mediawiki.user.js
blob7cf9d8fe403f92837b0b6249082a02e941c9075f
1 /**
2  * @class mw.user
3  * @singleton
4  */
5 ( function ( mw, $ ) {
6         var callbacks, options, tokens, user;
8         /**
9          * Gets the current user's groups or rights.
10          *
11          * @private
12          * @param {string} info One of 'groups' or 'rights'
13          * @param {Function} callback
14          */
15         function getUserInfo( info, callback ) {
16                 var api;
17                 if ( callbacks[info] ) {
18                         callbacks[info].add( callback );
19                         return;
20                 }
21                 callbacks.rights = $.Callbacks('once memory');
22                 callbacks.groups = $.Callbacks('once memory');
23                 callbacks[info].add( callback );
24                 api = new mw.Api();
25                 api.get( {
26                         action: 'query',
27                         meta: 'userinfo',
28                         uiprop: 'rights|groups'
29                 } ).always( function ( data ) {
30                         var rights, groups;
31                         if ( data.query && data.query.userinfo ) {
32                                 rights = data.query.userinfo.rights;
33                                 groups = data.query.userinfo.groups;
34                         }
35                         callbacks.rights.fire( rights || [] );
36                         callbacks.groups.fire( groups || [] );
37                 } );
38         }
40         callbacks = {};
42         // Extend the skeleton mw.user from mediawiki.js
43         // This is kind of ugly but we're stuck with this for b/c reasons
44         options = mw.user.options || new mw.Map();
45         tokens = mw.user.tokens || new mw.Map();
47         mw.user = user = {
48                 options: options,
49                 tokens: tokens,
51                 /**
52                  * Generates a random user session ID (32 alpha-numeric characters).
53                  *
54                  * This information would potentially be stored in a cookie to identify a user during a
55                  * session or series of sessions. Its uniqueness should not be depended on.
56                  *
57                  * @return {string} Random set of 32 alpha-numeric characters
58                  */
59                 generateRandomSessionId: function () {
60                         var i, r,
61                                 id = '',
62                                 seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
63                         for ( i = 0; i < 32; i++ ) {
64                                 r = Math.floor( Math.random() * seed.length );
65                                 id += seed.substring( r, r + 1 );
66                         }
67                         return id;
68                 },
70                 /**
71                  * Gets the current user's database id.
72                  *
73                  * Not to be confused with #id
74                  *
75                  * @return {number} Current user's id, or 0 if user is anonymous
76                  */
77                 getId: function () {
78                         return mw.config.get( 'wgUserId', 0 );
79                 },
81                 /**
82                  * Gets the current user's name.
83                  *
84                  * @return {string|null} User name string or null if user is anonymous
85                  */
86                 getName: function () {
87                         return mw.config.get( 'wgUserName' );
88                 },
90                 /**
91                  * @inheritdoc #getName
92                  * @deprecated since 1.20 use #getName instead
93                  */
94                 name: function () {
95                         return user.getName();
96                 },
98                 /**
99                  * Get date user registered, if available.
100                  *
101                  * @return {Date|boolean|null} Date user registered, or false for anonymous users, or
102                  *  null when data is not available
103                  */
104                 getRegistration: function () {
105                         var registration = mw.config.get( 'wgUserRegistration' );
106                         if ( user.isAnon() ) {
107                                 return false;
108                         } else if ( registration === null ) {
109                                 // Information may not be available if they signed up before
110                                 // MW began storing this.
111                                 return null;
112                         } else {
113                                 return new Date( registration );
114                         }
115                 },
117                 /**
118                  * Checks if the current user is anonymous.
119                  *
120                  * @return {boolean}
121                  */
122                 isAnon: function () {
123                         return user.getName() === null;
124                 },
126                 /**
127                  * @inheritdoc #isAnon
128                  * @deprecated since 1.20 use #isAnon instead
129                  */
130                 anonymous: function () {
131                         return user.isAnon();
132                 },
134                 /**
135                  * Gets a random ID automatically generated and stored in a session cookie.
136                  *
137                  * This ID is ephemeral for everyone, staying in their browser only until they close
138                  * their browser.
139                  *
140                  * @return {string} Random session ID
141                  */
142                 sessionId: function () {
143                         var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
144                         if ( typeof sessionId === 'undefined' || sessionId === null ) {
145                                 sessionId = user.generateRandomSessionId();
146                                 $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
147                         }
148                         return sessionId;
149                 },
151                 /**
152                  * Gets the current user's name or the session ID
153                  *
154                  * Not to be confused with #getId
155                  *
156                  * @return {string} User name or random session ID
157                  */
158                 id: function () {
159                         var name = user.getName();
160                         if ( name ) {
161                                 return name;
162                         }
163                         return user.sessionId();
164                 },
166                 /**
167                  * Gets the user's bucket, placing them in one at random based on set odds if needed.
168                  *
169                  *     mw.user.bucket( 'test', {
170                  *         'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
171                  *         'version': 1,
172                  *         'expires': 7
173                  *     } );
174                  *
175                  * @param {string} key Name of bucket
176                  * @param {Object} options Bucket configuration options
177                  * @param {Object} options.buckets List of bucket-name/relative-probability pairs (required,
178                  *  must have at least one pair)
179                  * @param {number} options.version Version of bucket test, changing this forces rebucketing
180                  *  (optional, default: 0)
181                  * @param {number} options.expires Length of time (in days) until the user gets rebucketed
182                  *  (optional, default: 30)
183                  * @return {string} Bucket name - the randomly chosen key of the options.buckets object
184                  */
185                 bucket: function ( key, options ) {
186                         var cookie, parts, version, bucket,
187                                 range, k, rand, total;
189                         options = $.extend( {
190                                 buckets: {},
191                                 version: 0,
192                                 expires: 30
193                         }, options || {} );
195                         cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
197                         // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
198                         if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
199                                 parts = cookie.split( ':' );
200                                 if ( parts.length > 1 && Number( parts[0] ) === options.version ) {
201                                         version = Number( parts[0] );
202                                         bucket = String( parts[1] );
203                                 }
204                         }
205                         if ( bucket === undefined ) {
206                                 if ( !$.isPlainObject( options.buckets ) ) {
207                                         throw 'Invalid buckets error. Object expected for options.buckets.';
208                                 }
209                                 version = Number( options.version );
210                                 // Find range
211                                 range = 0;
212                                 for ( k in options.buckets ) {
213                                         range += options.buckets[k];
214                                 }
215                                 // Select random value within range
216                                 rand = Math.random() * range;
217                                 // Determine which bucket the value landed in
218                                 total = 0;
219                                 for ( k in options.buckets ) {
220                                         bucket = k;
221                                         total += options.buckets[k];
222                                         if ( total >= rand ) {
223                                                 break;
224                                         }
225                                 }
226                                 $.cookie(
227                                         'mediaWiki.user.bucket:' + key,
228                                         version + ':' + bucket,
229                                         { 'path': '/', 'expires': Number( options.expires ) }
230                                 );
231                         }
232                         return bucket;
233                 },
235                 /**
236                  * Gets the current user's groups.
237                  *
238                  * @param {Function} callback
239                  */
240                 getGroups: function ( callback ) {
241                         getUserInfo( 'groups', callback );
242                 },
244                 /**
245                  * Gets the current user's rights.
246                  *
247                  * @param {Function} callback
248                  */
249                 getRights: function ( callback ) {
250                         getUserInfo( 'rights', callback );
251                 }
252         };
254 }( mediaWiki, jQuery ) );