Index: trunk/phase3/resources/mediawiki/mediawiki.api.js |
— | — | @@ -1,179 +1,189 @@ |
2 | | -/* mw.Api objects represent the API of a particular MediaWiki server. */ |
| 2 | +/* mw.Api objects represent the API of a particular MediaWiki server. */ |
3 | 3 | |
4 | | -( function( mw, $j, undefined ) { |
5 | | - |
| 4 | +( function( $, mw, undefined ) { |
| 5 | + |
6 | 6 | /** |
7 | | - * Represents the API of a particular MediaWiki server. |
8 | | - * |
9 | | - * Required options: |
10 | | - * url - complete URL to API endpoint. Usually equivalent to wgServer + wgScriptPath + '/api.php' |
11 | | - * |
12 | | - * Other options: |
13 | | - * can override the parameter defaults and ajax default options. |
14 | | - * XXX document! |
15 | | - * |
16 | | - * TODO share api objects with exact same config. |
17 | | - * |
18 | | - * ajax options can also be overriden on every get() or post() |
19 | | - * |
20 | | - * @param options {Mixed} can take many options, but must include at minimum the API url. |
| 7 | + * @var defaultsOptions {Object} |
| 8 | + * We allow people to omit these default parameters from API requests |
| 9 | + * there is very customizable error handling here, on a per-call basis |
| 10 | + * wondering, would it be simpler to make it easy to clone the api object, |
| 11 | + * change error handling, and use that instead? |
21 | 12 | */ |
22 | | - mw.Api = function( options ) { |
| 13 | + var defaultsOptions = { |
23 | 14 | |
24 | | - if ( options === undefined ) { |
25 | | - options = {}; |
26 | | - } |
27 | | - |
28 | | - // make sure we at least have a URL endpoint for the API |
29 | | - if ( options.url === undefined ) { |
30 | | - options.url = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api' + mw.config.get( 'wgScriptExtension' ); |
31 | | - } |
32 | | - |
33 | | - this.url = options.url; |
34 | | - |
35 | | - /* We allow people to omit these default parameters from API requests */ |
36 | | - // there is very customizable error handling here, on a per-call basis |
37 | | - // wondering, would it be simpler to make it easy to clone the api object, change error handling, and use that instead? |
38 | | - this.defaults = { |
| 15 | + // Query parameters for API requests |
39 | 16 | parameters: { |
40 | 17 | action: 'query', |
41 | 18 | format: 'json' |
42 | 19 | }, |
43 | 20 | |
| 21 | + // Ajax options for jQuery.ajax() |
44 | 22 | ajax: { |
45 | | - // force toString if we got a mw.Uri object |
46 | | - url: new String( this.url ), |
| 23 | + url: mw.util.wikiScript( 'api' ), |
47 | 24 | |
48 | | - /* default function for success and no API error */ |
49 | 25 | ok: function() {}, |
50 | 26 | |
51 | 27 | // caller can supply handlers for http transport error or api errors |
52 | 28 | err: function( code, result ) { |
53 | | - mw.log( "mw.Api error: " + code, 'debug' ); |
| 29 | + mw.log( 'mw.Api error: ' + code, 'debug' ); |
54 | 30 | }, |
55 | 31 | |
56 | | - timeout: 30000, /* 30 seconds */ |
| 32 | + timeout: 30000, // 30 seconds |
57 | 33 | |
58 | 34 | dataType: 'json' |
59 | | - |
60 | 35 | } |
61 | 36 | }; |
62 | 37 | |
| 38 | + /** |
| 39 | + * Constructor to create an object to interact with the API of a particular MediaWiki server. |
| 40 | + * |
| 41 | + * @todo Share API objects with exact same config. |
| 42 | + * @example |
| 43 | + * <code> |
| 44 | + * var api = new mw.Api(); |
| 45 | + * api.get( { |
| 46 | + * action: 'query', |
| 47 | + * meta: 'userinfo' |
| 48 | + * }, { |
| 49 | + * ok: function () { console.log( arguments ); } |
| 50 | + * } ); |
| 51 | + * </code> |
| 52 | + * |
| 53 | + * @constructor |
| 54 | + * @param options {Object} See defaultOptions documentation above. Ajax options can also be |
| 55 | + * overridden for each individual request to jQuery.ajax() later on. |
| 56 | + */ |
| 57 | + mw.Api = function( options ) { |
63 | 58 | |
64 | | - if ( options.parameters ) { |
65 | | - $j.extend( this.defaults.parameters, options.parameters ); |
| 59 | + if ( options === undefined ) { |
| 60 | + options = {}; |
66 | 61 | } |
67 | 62 | |
68 | | - if ( options.ajax ) { |
69 | | - $j.extend( this.defaults.ajax, options.ajax ); |
| 63 | + // Force toString if we got a mw.Uri object |
| 64 | + if ( options.ajax && options.ajax.url !== undefined ) { |
| 65 | + options.ajax.url = String( options.ajax.url ); |
70 | 66 | } |
| 67 | + |
| 68 | + options.parameters = $.extend( {}, defaultsOptions.parameters, options.parameters ); |
| 69 | + options.ajax = $.extend( {}, defaultsOptions.ajax, options.ajax ); |
| 70 | + |
| 71 | + this.defaults = options; |
71 | 72 | }; |
72 | 73 | |
73 | 74 | mw.Api.prototype = { |
74 | 75 | |
75 | 76 | /** |
76 | 77 | * For api queries, in simple cases the caller just passes a success callback. |
77 | | - * In complex cases they pass an object with a success property as callback and probably other options. |
| 78 | + * In complex cases they pass an object with a success property as callback and |
| 79 | + * probably other options. |
78 | 80 | * Normalize the argument so that it's always the latter case. |
79 | | - * |
80 | | - * @param {Object|Function} ajax properties, or just a success function |
81 | | - * @return Function |
| 81 | + * |
| 82 | + * @param {Object|Function} An object contaning one or more of options.ajax, |
| 83 | + * or just a success function (options.ajax.ok). |
| 84 | + * @return {Object} Normalized ajax options. |
82 | 85 | */ |
83 | 86 | normalizeAjaxOptions: function( arg ) { |
| 87 | + var opt = arg; |
84 | 88 | if ( typeof arg === 'function' ) { |
85 | | - var ok = arg; |
86 | | - arg = { 'ok': ok }; |
| 89 | + opt = { 'ok': arg }; |
87 | 90 | } |
88 | | - if (! arg.ok ) { |
89 | | - throw Error( "ajax options must include ok callback" ); |
| 91 | + if ( !opt.ok ) { |
| 92 | + throw new Error( 'ajax options must include ok callback' ); |
90 | 93 | } |
91 | | - return arg; |
| 94 | + return opt; |
92 | 95 | }, |
93 | 96 | |
94 | 97 | /** |
95 | 98 | * Perform API get request |
96 | 99 | * |
97 | | - * @param {Object} request parameters |
98 | | - * @param {Object|Function} ajax properties, or just a success function |
99 | | - */ |
| 100 | + * @param {Object} request parameters |
| 101 | + * @param {Object|Function} ajax options, or just a success function |
| 102 | + * @return {jqXHR} |
| 103 | + */ |
100 | 104 | get: function( parameters, ajaxOptions ) { |
101 | 105 | ajaxOptions = this.normalizeAjaxOptions( ajaxOptions ); |
102 | 106 | ajaxOptions.type = 'GET'; |
103 | | - this.ajax( parameters, ajaxOptions ); |
| 107 | + return this.ajax( parameters, ajaxOptions ); |
104 | 108 | }, |
105 | 109 | |
106 | 110 | /** |
107 | 111 | * Perform API post request |
108 | | - * TODO post actions for nonlocal will need proxy |
109 | | - * |
110 | | - * @param {Object} request parameters |
111 | | - * @param {Object|Function} ajax properties, or just a success function |
| 112 | + * @todo Post actions for nonlocal will need proxy |
| 113 | + * |
| 114 | + * @param {Object} request parameters |
| 115 | + * @param {Object|Function} ajax options, or just a success function |
| 116 | + * @return {jqXHR} |
112 | 117 | */ |
113 | 118 | post: function( parameters, ajaxOptions ) { |
114 | 119 | ajaxOptions = this.normalizeAjaxOptions( ajaxOptions ); |
115 | 120 | ajaxOptions.type = 'POST'; |
116 | | - this.ajax( parameters, ajaxOptions ); |
| 121 | + return this.ajax( parameters, ajaxOptions ); |
117 | 122 | }, |
118 | 123 | |
119 | 124 | /** |
120 | | - * Perform the API call. |
121 | | - * |
122 | | - * @param {Object} request parameters |
123 | | - * @param {Object} ajax properties |
| 125 | + * Perform the API call. |
| 126 | + * |
| 127 | + * @param {Object} request parameters |
| 128 | + * @param {Object} ajax options |
| 129 | + * @return {jqXHR} |
124 | 130 | */ |
125 | 131 | ajax: function( parameters, ajaxOptions ) { |
126 | | - parameters = $j.extend( {}, this.defaults.parameters, parameters ); |
127 | | - ajaxOptions = $j.extend( {}, this.defaults.ajax, ajaxOptions ); |
| 132 | + parameters = $.extend( {}, this.defaults.parameters, parameters ); |
| 133 | + ajaxOptions = $.extend( {}, this.defaults.ajax, ajaxOptions ); |
128 | 134 | |
129 | 135 | // Some deployed MediaWiki >= 1.17 forbid periods in URLs, due to an IE XSS bug |
130 | 136 | // So let's escape them here. See bug #28235 |
131 | 137 | // This works because jQuery accepts data as a query string or as an Object |
132 | | - ajaxOptions.data = $j.param( parameters ).replace( /\./g, '%2E' ); |
133 | | - |
| 138 | + ajaxOptions.data = $.param( parameters ).replace( /\./g, '%2E' ); |
| 139 | + |
134 | 140 | ajaxOptions.error = function( xhr, textStatus, exception ) { |
135 | | - ajaxOptions.err( 'http', { xhr: xhr, textStatus: textStatus, exception: exception } ); |
| 141 | + ajaxOptions.err( 'http', { |
| 142 | + xhr: xhr, |
| 143 | + textStatus: textStatus, |
| 144 | + exception: exception |
| 145 | + } ); |
136 | 146 | }; |
137 | 147 | |
138 | | - |
139 | | - /* success just means 200 OK; also check for output and API errors */ |
| 148 | + // Success just means 200 OK; also check for output and API errors |
140 | 149 | ajaxOptions.success = function( result ) { |
141 | 150 | if ( result === undefined || result === null || result === '' ) { |
142 | | - ajaxOptions.err( "ok-but-empty", "OK response but empty result (check HTTP headers?)" ); |
| 151 | + ajaxOptions.err( 'ok-but-empty', |
| 152 | + 'OK response but empty result (check HTTP headers?)' ); |
143 | 153 | } else if ( result.error ) { |
144 | 154 | var code = result.error.code === undefined ? 'unknown' : result.error.code; |
145 | 155 | ajaxOptions.err( code, result ); |
146 | | - } else { |
| 156 | + } else { |
147 | 157 | ajaxOptions.ok( result ); |
148 | 158 | } |
149 | 159 | }; |
150 | 160 | |
151 | | - $j.ajax( ajaxOptions ); |
152 | | - |
| 161 | + return $.ajax( ajaxOptions ); |
153 | 162 | } |
154 | 163 | |
155 | 164 | }; |
156 | 165 | |
157 | 166 | /** |
158 | | - * This is a list of errors we might receive from the API. |
| 167 | + * @var {Array} List of errors we might receive from the API. |
159 | 168 | * For now, this just documents our expectation that there should be similar messages |
160 | 169 | * available. |
161 | 170 | */ |
162 | 171 | mw.Api.errors = [ |
163 | | - /* occurs when POST aborted - jQuery 1.4 can't distinguish abort or lost connection from 200 OK + empty result */ |
| 172 | + // occurs when POST aborted |
| 173 | + // jQuery 1.4 can't distinguish abort or lost connection from 200 OK + empty result |
164 | 174 | 'ok-but-empty', |
165 | 175 | |
166 | 176 | // timeout |
167 | 177 | 'timeout', |
168 | 178 | |
169 | | - /* really a warning, but we treat it like an error */ |
| 179 | + // really a warning, but we treat it like an error |
170 | 180 | 'duplicate', |
171 | 181 | 'duplicate-archive', |
172 | 182 | |
173 | | - /* upload succeeded, but no image info. |
174 | | - this is probably impossible, but might as well check for it */ |
| 183 | + // upload succeeded, but no image info. |
| 184 | + // this is probably impossible, but might as well check for it |
175 | 185 | 'noimageinfo', |
176 | 186 | |
177 | | - /* remote errors, defined in API */ |
| 187 | + // remote errors, defined in API |
178 | 188 | 'uploaddisabled', |
179 | 189 | 'nomodule', |
180 | 190 | 'mustbeposted', |
— | — | @@ -201,14 +211,13 @@ |
202 | 212 | ]; |
203 | 213 | |
204 | 214 | /** |
205 | | - * This is a list of warnings we might receive from the API. |
| 215 | + * @var {Array} List of warnings we might receive from the API. |
206 | 216 | * For now, this just documents our expectation that there should be similar messages |
207 | 217 | * available. |
208 | 218 | */ |
209 | | - |
210 | 219 | mw.Api.warnings = [ |
211 | 220 | 'duplicate', |
212 | 221 | 'exists' |
213 | 222 | ]; |
214 | 223 | |
215 | | -}) ( window.mediaWiki, jQuery ); |
| 224 | +})( jQuery, mediaWiki ); |
Index: trunk/phase3/resources/mediawiki/mediawiki.api.parse.js |
— | — | @@ -1,29 +1,31 @@ |
2 | | -// library to assist with action=parse, that is, get rendered HTML of wikitext |
| 2 | +/** |
| 3 | + * Additional mw.Api methods to assist with API calls related to parsing wikitext. |
| 4 | + */ |
3 | 5 | |
4 | | -( function( mw, $ ) { |
| 6 | +( function( $, mw ) { |
5 | 7 | |
6 | | - $.extend( mw.Api.prototype, { |
| 8 | + $.extend( mw.Api.prototype, { |
7 | 9 | /** |
8 | | - * Parse wikitext into HTML |
9 | | - * @param {String} wikitext |
10 | | - * @param {Function} callback to which to pass success HTML |
11 | | - * @param {Function} callback if error (optional) |
| 10 | + * Convinience method for 'action=parse'. Parses wikitext into HTML. |
| 11 | + * |
| 12 | + * @param wikiText {String} |
| 13 | + * @param success {Function} callback to which to pass success HTML |
| 14 | + * @param error {Function} callback if error (optional) |
| 15 | + * @return {jqXHR} |
12 | 16 | */ |
13 | | - parse: function( wikiText, useHtml, error ) { |
| 17 | + parse: function( wikiText, success, error ) { |
14 | 18 | var params = { |
15 | | - text: wikiText, |
16 | | - action: 'parse' |
17 | | - }; |
18 | | - var ok = function( data ) { |
19 | | - if ( data && data.parse && data.parse.text && data.parse.text['*'] ) { |
20 | | - useHtml( data.parse.text['*'] ); |
21 | | - } |
22 | | - }; |
23 | | - this.get( params, ok, error ); |
| 19 | + text: wikiText, |
| 20 | + action: 'parse' |
| 21 | + }, |
| 22 | + ok = function( data ) { |
| 23 | + if ( data && data.parse && data.parse.text && data.parse.text['*'] ) { |
| 24 | + success( data.parse.text['*'] ); |
| 25 | + } |
| 26 | + }; |
| 27 | + return this.get( params, ok, error ); |
24 | 28 | } |
25 | 29 | |
| 30 | + } ); |
26 | 31 | |
27 | | - } ); // end extend |
28 | | -} )( window.mediaWiki, jQuery ); |
29 | | - |
30 | | - |
| 32 | +} )( jQuery, mediaWiki ); |
Index: trunk/phase3/resources/mediawiki/mediawiki.api.titleblacklist.js |
— | — | @@ -1,48 +1,51 @@ |
2 | | -// library to assist with API calls on titleblacklist |
| 2 | +/** |
| 3 | + * Additional mw.Api methods to assist with API calls to the API module of the TitleBlacklist extension. |
| 4 | + */ |
3 | 5 | |
4 | | -( function( mw, $ ) { |
| 6 | +( function( $, mw, undefined ) { |
5 | 7 | |
6 | | - // cached token so we don't have to keep fetching new ones for every single post |
7 | | - var cachedToken = null; |
8 | | - |
9 | | - $.extend( mw.Api.prototype, { |
| 8 | + $.extend( mw.Api.prototype, { |
10 | 9 | /** |
11 | | - * @param {mw.Title} |
12 | | - * @param {Function} callback to pass false on Title not blacklisted, or error text when blacklisted |
13 | | - * @param {Function} optional callback to run if api error |
14 | | - * @return ajax call object |
| 10 | + * Convinience method for 'action=titleblacklist'. |
| 11 | + * Note: This action is not provided by MediaWiki core, but as part of the TitleBlacklist extension. |
| 12 | + * |
| 13 | + * @param title {mw.Title} |
| 14 | + * @param success {Function} Called on successfull request. First argument is false if title wasn't blacklisted, |
| 15 | + * object with 'reason', 'line' and 'message' properties if title was blacklisted. |
| 16 | + * @param err {Function} optional callback to run if api error |
| 17 | + * @return {jqXHR} |
15 | 18 | */ |
16 | | - isBlacklisted: function( title, callback, err ) { |
17 | | - var params = { |
18 | | - 'action': 'titleblacklist', |
19 | | - 'tbaction': 'create', |
20 | | - 'tbtitle': title.toString() |
21 | | - }; |
| 19 | + isBlacklisted: function( title, success, err ) { |
| 20 | + var params = { |
| 21 | + action: 'titleblacklist', |
| 22 | + tbaction: 'create', |
| 23 | + tbtitle: title.toString() |
| 24 | + }, |
| 25 | + ok = function( data ) { |
| 26 | + var result; |
22 | 27 | |
23 | | - var ok = function( data ) { |
24 | | - // this fails open (if nothing valid is returned by the api, allows the title) |
25 | | - // also fails open when the API is not present, which will be most of the time. |
26 | | - if ( data.titleblacklist && data.titleblacklist.result && data.titleblacklist.result == 'blacklisted') { |
27 | | - var result; |
28 | | - if ( data.titleblacklist.reason ) { |
29 | | - result = { |
30 | | - reason: data.titleblacklist.reason, |
31 | | - line: data.titleblacklist.line, |
32 | | - message: data.titleblacklist.message |
33 | | - }; |
| 28 | + // this fails open (if nothing valid is returned by the api, allows the title) |
| 29 | + // also fails open when the API is not present, which will be most of the time |
| 30 | + // as this API module is part of the TitleBlacklist extension. |
| 31 | + if ( data.titleblacklist && data.titleblacklist.result && data.titleblacklist.result === 'blacklisted') { |
| 32 | + if ( data.titleblacklist.reason ) { |
| 33 | + result = { |
| 34 | + reason: data.titleblacklist.reason, |
| 35 | + line: data.titleblacklist.line, |
| 36 | + message: data.titleblacklist.message |
| 37 | + }; |
| 38 | + } else { |
| 39 | + mw.log('mw.Api.titleblacklist::isBlacklisted> no reason data for blacklisted title', 'debug'); |
| 40 | + result = { reason: 'Blacklisted, but no reason supplied', line: 'Unknown', message: null }; |
| 41 | + } |
| 42 | + success( result ); |
34 | 43 | } else { |
35 | | - mw.log("mw.Api.titleblacklist::isBlacklisted> no reason data for blacklisted title", 'debug'); |
36 | | - result = { reason: "Blacklisted, but no reason supplied", line: "Unknown" }; |
| 44 | + success ( false ); |
37 | 45 | } |
38 | | - callback( result ); |
39 | | - } else { |
40 | | - callback ( false ); |
41 | | - } |
42 | | - }; |
| 46 | + }; |
43 | 47 | |
44 | 48 | return this.get( params, ok, err ); |
45 | | - |
46 | 49 | } |
47 | 50 | |
48 | 51 | } ); |
49 | | -} )( window.mediaWiki, jQuery ); |
| 52 | +} )( jQuery, mediaWiki ); |
Index: trunk/phase3/resources/mediawiki/mediawiki.api.category.js |
— | — | @@ -1,46 +1,46 @@ |
2 | | -// library to assist with API calls on categories |
| 2 | +/** |
| 3 | + * Additional mw.Api methods to assist with API calls related to categories. |
| 4 | + */ |
3 | 5 | |
4 | | -( function( mw, $ ) { |
| 6 | +( function( $, mw, undefined ) { |
5 | 7 | |
6 | | - $.extend( mw.Api.prototype, { |
| 8 | + $.extend( mw.Api.prototype, { |
7 | 9 | /** |
8 | | - * Determine if a category exists |
9 | | - * @param {mw.Title} |
10 | | - * @param {Function} callback to pass boolean of category's existence |
11 | | - * @param {Function} optional callback to run if api error |
| 10 | + * Determine if a category exists. |
| 11 | + * @param title {mw.Title} |
| 12 | + * @param success {Function} callback to pass boolean of category's existence |
| 13 | + * @param err {Function} optional callback to run if api error |
12 | 14 | * @return ajax call object |
13 | 15 | */ |
14 | | - isCategory: function( title, callback, err ) { |
| 16 | + isCategory: function( title, success, err ) { |
15 | 17 | var params = { |
16 | | - 'prop': 'categoryinfo', |
17 | | - 'titles': title.toString() |
18 | | - }; |
| 18 | + prop: 'categoryinfo', |
| 19 | + titles: title.toString() |
| 20 | + }, |
| 21 | + ok = function( data ) { |
| 22 | + var exists = false; |
| 23 | + if ( data.query && data.query.pages ) { |
| 24 | + $.each( data.query.pages, function( id, page ) { |
| 25 | + if ( page.categoryinfo ) { |
| 26 | + exists = true; |
| 27 | + } |
| 28 | + } ); |
| 29 | + } |
| 30 | + success( exists ); |
| 31 | + }; |
19 | 32 | |
20 | | - var ok = function( data ) { |
21 | | - var exists = false; |
22 | | - if ( data.query && data.query.pages ) { |
23 | | - $.each( data.query.pages, function( id, page ) { |
24 | | - if ( page.categoryinfo ) { |
25 | | - exists = true; |
26 | | - } |
27 | | - } ); |
28 | | - } |
29 | | - callback( exists ); |
30 | | - }; |
31 | | - |
32 | 33 | return this.get( params, { ok: ok, err: err } ); |
33 | | - |
34 | 34 | }, |
35 | 35 | |
36 | 36 | /** |
37 | | - * Get a list of categories that match a certain prefix. |
| 37 | + * Get a list of categories that match a certain prefix. |
38 | 38 | * e.g. given "Foo", return "Food", "Foolish people", "Foosball tables" ... |
39 | | - * @param {String} prefix to match |
40 | | - * @param {Function} callback to pass matched categories to |
41 | | - * @param {Function} optional callback to run if api error |
42 | | - * @return ajax call object |
| 39 | + * @param prefix {String} prefix to match |
| 40 | + * @param success {Function} callback to pass matched categories to |
| 41 | + * @param err {Function} optional callback to run if api error |
| 42 | + * @return {jqXHR} |
43 | 43 | */ |
44 | | - getCategoriesByPrefix: function( prefix, callback, err ) { |
| 44 | + getCategoriesByPrefix: function( prefix, success, err ) { |
45 | 45 | |
46 | 46 | // fetch with allpages to only get categories that have a corresponding description page. |
47 | 47 | var params = { |
— | — | @@ -51,56 +51,55 @@ |
52 | 52 | |
53 | 53 | var ok = function( data ) { |
54 | 54 | var texts = []; |
55 | | - if ( data.query && data.query.allpages ) { |
| 55 | + if ( data.query && data.query.allpages ) { |
56 | 56 | $.each( data.query.allpages, function( i, category ) { |
57 | | - texts.push( new mw.Title( category.title ).getNameText() ); |
| 57 | + texts.push( new mw.Title( category.title ).getNameText() ); |
58 | 58 | } ); |
59 | 59 | } |
60 | | - callback( texts ); |
| 60 | + success( texts ); |
61 | 61 | }; |
62 | 62 | |
63 | 63 | return this.get( params, { ok: ok, err: err } ); |
64 | | - |
65 | 64 | }, |
66 | 65 | |
67 | 66 | |
68 | 67 | /** |
69 | 68 | * Get the categories that a particular page on the wiki belongs to |
70 | | - * @param {mw.Title} |
71 | | - * @param {Function} callback to pass categories to (or false, if title not found) |
72 | | - * @param {Function} optional callback to run if api error |
73 | | - * @param {Boolean} optional asynchronousness (default = true = async) |
74 | | - * @return ajax call object |
| 69 | + * @param title {mw.Title} |
| 70 | + * @param success {Function} callback to pass categories to (or false, if title not found) |
| 71 | + * @param err {Function} optional callback to run if api error |
| 72 | + * @param async {Boolean} optional asynchronousness (default = true = async) |
| 73 | + * @return {jqXHR} |
75 | 74 | */ |
76 | | - getCategories: function( title, callback, err, async ) { |
77 | | - var params = { |
| 75 | + getCategories: function( title, success, err, async ) { |
| 76 | + var params, ok; |
| 77 | + params = { |
78 | 78 | prop: 'categories', |
79 | 79 | titles: title.toString() |
80 | 80 | }; |
81 | 81 | if ( async === undefined ) { |
82 | 82 | async = true; |
83 | 83 | } |
84 | | - |
85 | | - var ok = function( data ) { |
| 84 | + ok = function( data ) { |
86 | 85 | var ret = false; |
87 | 86 | if ( data.query && data.query.pages ) { |
88 | 87 | $.each( data.query.pages, function( id, page ) { |
89 | 88 | if ( page.categories ) { |
90 | | - if ( typeof ret !== 'object' ) { |
| 89 | + if ( typeof ret !== 'object' ) { |
91 | 90 | ret = []; |
92 | 91 | } |
93 | | - $.each( page.categories, function( i, cat ) { |
94 | | - ret.push( new mw.Title( cat.title ) ); |
| 92 | + $.each( page.categories, function( i, cat ) { |
| 93 | + ret.push( new mw.Title( cat.title ) ); |
95 | 94 | } ); |
96 | 95 | } |
97 | 96 | } ); |
98 | 97 | } |
99 | | - callback( ret ); |
| 98 | + success( ret ); |
100 | 99 | }; |
101 | 100 | |
102 | 101 | return this.get( params, { ok: ok, err: err, async: async } ); |
103 | | - |
104 | 102 | } |
105 | 103 | |
106 | 104 | } ); |
107 | | -} )( window.mediaWiki, jQuery ); |
| 105 | + |
| 106 | +} )( jQuery, mediaWiki ); |
Index: trunk/phase3/resources/mediawiki/mediawiki.api.edit.js |
— | — | @@ -1,104 +1,106 @@ |
2 | | -// library to assist with edits |
| 2 | +/** |
| 3 | + * Additional mw.Api methods to assist with API calls related to editing wiki pages. |
| 4 | + */ |
3 | 5 | |
4 | | -( function( mw, $, undefined ) { |
| 6 | +( function( $, mw, undefined ) { |
5 | 7 | |
6 | | - // cached token so we don't have to keep fetching new ones for every single post |
| 8 | + // Cache token so we don't have to keep fetching new ones for every single request. |
7 | 9 | var cachedToken = null; |
8 | 10 | |
9 | | - $.extend( mw.Api.prototype, { |
| 11 | + $.extend( mw.Api.prototype, { |
10 | 12 | |
11 | | - /* Post to API with edit token. If we have no token, get one and try to post. |
12 | | - * If we have a cached token try using that, and if it fails, blank out the |
13 | | - * cached token and start over. |
14 | | - * |
15 | | - * @param params API parameters |
16 | | - * @param ok callback for success |
17 | | - * @param err (optional) error callback |
| 13 | + /** |
| 14 | + * Post to API with edit token. If we have no token, get one and try to post. |
| 15 | + * If we have a cached token try using that, and if it fails, blank out the |
| 16 | + * cached token and start over. |
| 17 | + * |
| 18 | + * @param params {Object} API parameters |
| 19 | + * @param ok {Function} callback for success |
| 20 | + * @param err {Function} [optional] error callback |
| 21 | + * @return {jqXHR} |
18 | 22 | */ |
19 | 23 | postWithEditToken: function( params, ok, err ) { |
20 | | - var api = this; |
| 24 | + var api = this, useTokenToPost, getTokenIfBad; |
21 | 25 | if ( cachedToken === null ) { |
22 | 26 | // We don't have a valid cached token, so get a fresh one and try posting. |
23 | 27 | // We do not trap any 'badtoken' or 'notoken' errors, because we don't want |
24 | 28 | // an infinite loop. If this fresh token is bad, something else is very wrong. |
25 | | - var useTokenToPost = function( token ) { |
26 | | - params.token = token; |
| 29 | + useTokenToPost = function( token ) { |
| 30 | + params.token = token; |
27 | 31 | api.post( params, ok, err ); |
28 | 32 | }; |
29 | | - api.getEditToken( useTokenToPost, err ); |
| 33 | + return api.getEditToken( useTokenToPost, err ); |
30 | 34 | } else { |
31 | 35 | // We do have a token, but it might be expired. So if it is 'bad' then |
32 | 36 | // start over with a new token. |
33 | 37 | params.token = cachedToken; |
34 | | - var getTokenIfBad = function( code, result ) { |
35 | | - if ( code === 'badtoken' ) { |
| 38 | + getTokenIfBad = function( code, result ) { |
| 39 | + if ( code === 'badtoken' ) { |
36 | 40 | cachedToken = null; // force a new token |
37 | 41 | api.postWithEditToken( params, ok, err ); |
38 | 42 | } else { |
39 | 43 | err( code, result ); |
40 | 44 | } |
41 | 45 | }; |
42 | | - api.post( params, { 'ok' : ok, 'err' : getTokenIfBad }); |
| 46 | + return api.post( params, { 'ok' : ok, 'err' : getTokenIfBad }); |
43 | 47 | } |
44 | 48 | }, |
45 | | - |
| 49 | + |
46 | 50 | /** |
47 | 51 | * Api helper to grab an edit token |
48 | | - * |
| 52 | + * |
49 | 53 | * token callback has signature ( String token ) |
50 | 54 | * error callback has signature ( String code, Object results, XmlHttpRequest xhr, Exception exception ) |
51 | | - * Note that xhr and exception are only available for 'http_*' errors |
| 55 | + * Note that xhr and exception are only available for 'http_*' errors |
52 | 56 | * code may be any http_* error code (see mw.Api), or 'token_missing' |
53 | 57 | * |
54 | | - * @param {Function} received token callback |
55 | | - * @param {Function} error callback |
| 58 | + * @param tokenCallback {Function} received token callback |
| 59 | + * @param err {Function} error callback |
| 60 | + * @return {jqXHR} |
56 | 61 | */ |
57 | 62 | getEditToken: function( tokenCallback, err ) { |
58 | | - var api = this; |
59 | | - |
60 | | - var parameters = { |
61 | | - 'prop': 'info', |
62 | | - 'intoken': 'edit', |
63 | | - /* we need some kind of dummy page to get a token from. This will return a response |
64 | | - complaining that the page is missing, but we should also get an edit token */ |
65 | | - 'titles': 'DummyPageForEditToken' |
66 | | - }; |
67 | | - |
68 | | - var ok = function( data ) { |
69 | | - var token; |
70 | | - $.each( data.query.pages, function( i, page ) { |
71 | | - if ( page['edittoken'] ) { |
72 | | - token = page['edittoken']; |
73 | | - return false; |
| 63 | + var parameters = { |
| 64 | + prop: 'info', |
| 65 | + intoken: 'edit', |
| 66 | + // we need some kind of dummy page to get a token from. This will return a response |
| 67 | + // complaining that the page is missing, but we should also get an edit token |
| 68 | + titles: 'DummyPageForEditToken' |
| 69 | + }, |
| 70 | + ok = function( data ) { |
| 71 | + var token; |
| 72 | + $.each( data.query.pages, function( i, page ) { |
| 73 | + if ( page.edittoken ) { |
| 74 | + token = page.edittoken; |
| 75 | + return false; |
| 76 | + } |
| 77 | + } ); |
| 78 | + if ( token !== undefined ) { |
| 79 | + cachedToken = token; |
| 80 | + tokenCallback( token ); |
| 81 | + } else { |
| 82 | + err( 'token-missing', data ); |
74 | 83 | } |
75 | | - } ); |
76 | | - if ( token !== undefined ) { |
77 | | - cachedToken = token; |
78 | | - tokenCallback( token ); |
79 | | - } else { |
80 | | - err( 'token-missing', data ); |
81 | | - } |
82 | | - }; |
| 84 | + }, |
| 85 | + ajaxOptions = { |
| 86 | + ok: ok, |
| 87 | + err: err, |
| 88 | + // Due to the API assuming we're logged out if we pass the callback-parameter, |
| 89 | + // we have to disable jQuery's callback system, and instead parse JSON string, |
| 90 | + // by setting 'jsonp' to false. |
| 91 | + jsonp: false |
| 92 | + }; |
83 | 93 | |
84 | | - var ajaxOptions = { |
85 | | - 'ok': ok, |
86 | | - 'err': err, |
87 | | - // Due to the API assuming we're logged out if we pass the callback-parameter, |
88 | | - // we have to disable jQuery's callback system, and instead parse JSON string, |
89 | | - // by setting 'jsonp' to false. |
90 | | - 'jsonp': false |
91 | | - }; |
92 | | - |
93 | | - api.get( parameters, ajaxOptions ); |
| 94 | + return this.get( parameters, ajaxOptions ); |
94 | 95 | }, |
95 | 96 | |
96 | 97 | /** |
97 | 98 | * Create a new section of the page. |
98 | | - * @param {mw.Title|String} target page |
99 | | - * @param {String} header |
100 | | - * @param {String} wikitext message |
101 | | - * @param {Function} success handler |
102 | | - * @param {Function} error handler |
| 99 | + * @param title {mw.Title|String} target page |
| 100 | + * @param header {String} |
| 101 | + * @param message {String} wikitext message |
| 102 | + * @param ok {Function} success handler |
| 103 | + * @param err {Function} error handler |
| 104 | + * @return {jqXHR} |
103 | 105 | */ |
104 | 106 | newSection: function( title, header, message, ok, err ) { |
105 | 107 | var params = { |
— | — | @@ -109,9 +111,9 @@ |
110 | 112 | summary: header, |
111 | 113 | text: message |
112 | 114 | }; |
113 | | - this.postWithEditToken( params, ok, err ); |
| 115 | + return this.postWithEditToken( params, ok, err ); |
114 | 116 | } |
115 | 117 | |
116 | | - } ); // end extend |
| 118 | + } ); |
117 | 119 | |
118 | | -} )( window.mediaWiki, jQuery ); |
| 120 | +} )( jQuery, mediaWiki ); |