Fix exception when searching for stuff beginning with "Media:"
[mediawiki.git] / resources / mediawiki / mediawiki.user.js
blob5c5c87e29522889edf4cc5d6f10c5751686c7bcf
1 /*
2  * Implementation for mediaWiki.user
3  */
5 ( function ( mw, $ ) {
7         /**
8          * User object
9          */
10         function User( options, tokens ) {
11                 var user, callbacks;
13                 /* Private Members */
15                 user = this;
16                 callbacks = {};
18                 /**
19                  * Gets the current user's groups or rights.
20                  * @param {String} info: One of 'groups' or 'rights'.
21                  * @param {Function} callback
22                  */
23                 function getUserInfo( info, callback ) {
24                         var api;
25                         if ( callbacks[info] ) {
26                                 callbacks[info].add( callback );
27                                 return;
28                         }
29                         callbacks.rights = $.Callbacks('once memory');
30                         callbacks.groups = $.Callbacks('once memory');
31                         callbacks[info].add( callback );
32                         api = new mw.Api();
33                         api.get( {
34                                 action: 'query',
35                                 meta: 'userinfo',
36                                 uiprop: 'rights|groups'
37                         } ).always( function ( data ) {
38                                 var rights, groups;
39                                 if ( data.query && data.query.userinfo ) {
40                                         rights = data.query.userinfo.rights;
41                                         groups = data.query.userinfo.groups;
42                                 }
43                                 callbacks.rights.fire( rights || [] );
44                                 callbacks.groups.fire( groups || [] );
45                         } );
46                 }
48                 /* Public Members */
50                 this.options = options || new mw.Map();
52                 this.tokens = tokens || new mw.Map();
54                 /* Public Methods */
56                 /**
57                  * Generates a random user session ID (32 alpha-numeric characters).
58                  *
59                  * This information would potentially be stored in a cookie to identify a user during a
60                  * session or series of sessions. Its uniqueness should not be depended on.
61                  *
62                  * @return String: Random set of 32 alpha-numeric characters
63                  */
64                 function generateId() {
65                         var i, r,
66                                 id = '',
67                                 seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
68                         for ( i = 0; i < 32; i++ ) {
69                                 r = Math.floor( Math.random() * seed.length );
70                                 id += seed.substring( r, r + 1 );
71                         }
72                         return id;
73                 }
75                 /**
76                  * Gets the current user's name.
77                  *
78                  * @return Mixed: User name string or null if users is anonymous
79                  */
80                 this.getName = function () {
81                         return mw.config.get( 'wgUserName' );
82                 };
84                 /**
85                  * @deprecated since 1.20 use mw.user.getName() instead
86                  */
87                 this.name = function () {
88                         return this.getName();
89                 };
91                 /**
92                  * Checks if the current user is anonymous.
93                  *
94                  * @return Boolean
95                  */
96                 this.isAnon = function () {
97                         return user.getName() === null;
98                 };
100                 /**
101                  * @deprecated since 1.20 use mw.user.isAnon() instead
102                  */
103                 this.anonymous = function () {
104                         return user.isAnon();
105                 };
107                 /**
108                  * Gets a random session ID automatically generated and kept in a cookie.
109                  *
110                  * This ID is ephemeral for everyone, staying in their browser only until they close
111                  * their browser.
112                  *
113                  * @return String: User name or random session ID
114                  */
115                 this.sessionId = function () {
116                         var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
117                         if ( typeof sessionId === 'undefined' || sessionId === null ) {
118                                 sessionId = generateId();
119                                 $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
120                         }
121                         return sessionId;
122                 };
124                 /**
125                  * Gets the current user's name or a random ID automatically generated and kept in a cookie.
126                  *
127                  * This ID is persistent for anonymous users, staying in their browser up to 1 year. The
128                  * expiration time is reset each time the ID is queried, so in most cases this ID will
129                  * persist until the browser's cookies are cleared or the user doesn't visit for 1 year.
130                  *
131                  * @return String: User name or random session ID
132                  */
133                 this.id = function() {
134                         var id,
135                                 name = user.getName();
136                         if ( name ) {
137                                 return name;
138                         }
139                         id = $.cookie( 'mediaWiki.user.id' );
140                         if ( typeof id === 'undefined' || id === null ) {
141                                 id = generateId();
142                         }
143                         // Set cookie if not set, or renew it if already set
144                         $.cookie( 'mediaWiki.user.id', id, {
145                                 expires: 365,
146                                 path: '/'
147                         } );
148                         return id;
149                 };
151                 /**
152                  * Gets the user's bucket, placing them in one at random based on set odds if needed.
153                  *
154                  * @param key String: Name of bucket
155                  * @param options Object: Bucket configuration options
156                  * @param options.buckets Object: List of bucket-name/relative-probability pairs (required,
157                  * must have at least one pair)
158                  * @param options.version Number: Version of bucket test, changing this forces rebucketing
159                  * (optional, default: 0)
160                  * @param options.tracked Boolean: Track the event of bucketing through the API module of
161                  * the ClickTracking extension (optional, default: false)
162                  * @param options.expires Number: Length of time (in days) until the user gets rebucketed
163                  * (optional, default: 30)
164                  * @return String: Bucket name - the randomly chosen key of the options.buckets object
165                  *
166                  * @example
167                  *     mw.user.bucket( 'test', {
168                  *         'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
169                  *         'version': 1,
170                  *         'tracked': true,
171                  *         'expires': 7
172                  *     } );
173                  */
174                 this.bucket = function ( key, options ) {
175                         var cookie, parts, version, bucket,
176                                 range, k, rand, total;
178                         options = $.extend( {
179                                 buckets: {},
180                                 version: 0,
181                                 tracked: false,
182                                 expires: 30
183                         }, options || {} );
185                         cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
187                         // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
188                         if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
189                                 parts = cookie.split( ':' );
190                                 if ( parts.length > 1 && Number( parts[0] ) === options.version ) {
191                                         version = Number( parts[0] );
192                                         bucket = String( parts[1] );
193                                 }
194                         }
195                         if ( bucket === undefined ) {
196                                 if ( !$.isPlainObject( options.buckets ) ) {
197                                         throw 'Invalid buckets error. Object expected for options.buckets.';
198                                 }
199                                 version = Number( options.version );
200                                 // Find range
201                                 range = 0;
202                                 for ( k in options.buckets ) {
203                                         range += options.buckets[k];
204                                 }
205                                 // Select random value within range
206                                 rand = Math.random() * range;
207                                 // Determine which bucket the value landed in
208                                 total = 0;
209                                 for ( k in options.buckets ) {
210                                         bucket = k;
211                                         total += options.buckets[k];
212                                         if ( total >= rand ) {
213                                                 break;
214                                         }
215                                 }
216                                 if ( options.tracked ) {
217                                         mw.loader.using( 'jquery.clickTracking', function () {
218                                                 $.trackAction(
219                                                         'mediaWiki.user.bucket:' + key + '@' + version + ':' + bucket
220                                                 );
221                                         } );
222                                 }
223                                 $.cookie(
224                                         'mediaWiki.user.bucket:' + key,
225                                         version + ':' + bucket,
226                                         { 'path': '/', 'expires': Number( options.expires ) }
227                                 );
228                         }
229                         return bucket;
230                 };
232                 /**
233                  * Gets the current user's groups.
234                  */
235                 this.getGroups = function ( callback ) {
236                         getUserInfo( 'groups', callback );
237                 };
239                 /**
240                  * Gets the current user's rights.
241                  */
242                 this.getRights = function ( callback ) {
243                         getUserInfo( 'rights', callback );
244                 };
245         }
247         // Extend the skeleton mw.user from mediawiki.js
248         // This is kind of ugly but we're stuck with this for b/c reasons
249         mw.user = new User( mw.user.options, mw.user.tokens );
251 }( mediaWiki, jQuery ) );