Merge "resourceloader: Simplify StringSet fallback"
[lhc/web/wiklou.git] / resources / src / mediawiki.api / options.js
1 /**
2 * @class mw.Api.plugin.options
3 */
4 ( function () {
5
6 $.extend( mw.Api.prototype, {
7
8 /**
9 * Asynchronously save the value of a single user option using the API. See #saveOptions.
10 *
11 * @param {string} name
12 * @param {string|null} value
13 * @return {jQuery.Promise}
14 */
15 saveOption: function ( name, value ) {
16 var param = {};
17 param[ name ] = value;
18 return this.saveOptions( param );
19 },
20
21 /**
22 * Asynchronously save the values of user options using the API.
23 *
24 * If a value of `null` is provided, the given option will be reset to the default value.
25 *
26 * Any warnings returned by the API, including warnings about invalid option names or values,
27 * are ignored. However, do not rely on this behavior.
28 *
29 * If necessary, the options will be saved using several sequential API requests. Only one promise
30 * is always returned that will be resolved when all requests complete.
31 *
32 * @param {Object} options Options as a `{ name: value, … }` object
33 * @return {jQuery.Promise}
34 */
35 saveOptions: function ( options ) {
36 var name, value, bundleable,
37 grouped = [],
38 promise = $.Deferred().resolve();
39
40 for ( name in options ) {
41 value = options[ name ] === null ? null : String( options[ name ] );
42
43 // Can we bundle this option, or does it need a separate request?
44 if ( this.defaults.useUS ) {
45 bundleable = name.indexOf( '=' ) === -1;
46 } else {
47 bundleable =
48 ( value === null || value.indexOf( '|' ) === -1 ) &&
49 ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
50 }
51
52 if ( bundleable ) {
53 if ( value !== null ) {
54 grouped.push( name + '=' + value );
55 } else {
56 // Omitting value resets the option
57 grouped.push( name );
58 }
59 } else {
60 if ( value !== null ) {
61 promise = promise.then( function ( name, value ) {
62 return this.postWithToken( 'csrf', {
63 formatversion: 2,
64 action: 'options',
65 optionname: name,
66 optionvalue: value
67 } );
68 }.bind( this, name, value ) );
69 } else {
70 // Omitting value resets the option
71 promise = promise.then( function ( name ) {
72 return this.postWithToken( 'csrf', {
73 formatversion: 2,
74 action: 'options',
75 optionname: name
76 } );
77 }.bind( this, name ) );
78 }
79 }
80 }
81
82 if ( grouped.length ) {
83 promise = promise.then( function () {
84 return this.postWithToken( 'csrf', {
85 formatversion: 2,
86 action: 'options',
87 change: grouped
88 } );
89 }.bind( this ) );
90 }
91
92 return promise;
93 }
94
95 } );
96
97 /**
98 * @class mw.Api
99 * @mixins mw.Api.plugin.options
100 */
101
102 }() );