Index: trunk/extensions/UploadWizard/resources/mw.Api.parse.js |
— | — | @@ -1,29 +0,0 @@ |
2 | | -// library to assist with action=parse, that is, get rendered HTML of wikitext |
3 | | - |
4 | | -( function( mw, $ ) { |
5 | | - |
6 | | - $.extend( mw.Api.prototype, { |
7 | | - /** |
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) |
12 | | - */ |
13 | | - parse: function( wikiText, useHtml, error ) { |
14 | | - 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 ); |
24 | | - } |
25 | | - |
26 | | - |
27 | | - } ); // end extend |
28 | | -} )( window.mediaWiki, jQuery ); |
29 | | - |
30 | | - |
Index: trunk/extensions/UploadWizard/resources/mw.Api.js |
— | — | @@ -1,208 +0,0 @@ |
2 | | -/* mw.Api objects represent the API of a particular MediaWiki server. */ |
3 | | - |
4 | | -( function( mw, $j, undefined ) { |
5 | | - |
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 | | - * ajax options can also be overriden on every get() or post() |
17 | | - * |
18 | | - * @param options {Mixed} can take many options, but must include at minimum the API url. |
19 | | - */ |
20 | | - mw.Api = function( options ) { |
21 | | - |
22 | | - // make sure we at least have a URL endpoint for the API |
23 | | - if ( options.url === undefined ) { |
24 | | - throw new Error( 'Configuration error - needs url property' ); |
25 | | - } |
26 | | - |
27 | | - this.url = options.url; |
28 | | - |
29 | | - /* We allow people to omit these default parameters from API requests */ |
30 | | - // there is very customizable error handling here, on a per-call basis |
31 | | - // wondering, would it be simpler to make it easy to clone the api object, change error handling, and use that instead? |
32 | | - this.defaults = { |
33 | | - parameters: { |
34 | | - action: 'query', |
35 | | - format: 'json' |
36 | | - }, |
37 | | - |
38 | | - ajax: { |
39 | | - // force toString if we got a mw.Uri object |
40 | | - url: new String( this.url ), |
41 | | - |
42 | | - /* default function for success and no API error */ |
43 | | - ok: function() {}, |
44 | | - |
45 | | - // caller can supply handlers for http transport error or api errors |
46 | | - err: function( code, result ) { |
47 | | - mw.log( "mw.Api error: " + code, 'debug' ); |
48 | | - }, |
49 | | - |
50 | | - timeout: 30000, /* 30 seconds */ |
51 | | - |
52 | | - dataType: 'json' |
53 | | - |
54 | | - } |
55 | | - }; |
56 | | - |
57 | | - |
58 | | - if ( options.parameters ) { |
59 | | - $j.extend( this.defaults.parameters, options.parameters ); |
60 | | - } |
61 | | - |
62 | | - if ( options.ajax ) { |
63 | | - $j.extend( this.defaults.ajax, options.ajax ); |
64 | | - } |
65 | | - }; |
66 | | - |
67 | | - mw.Api.prototype = { |
68 | | - |
69 | | - /** |
70 | | - * For api queries, in simple cases the caller just passes a success callback. |
71 | | - * In complex cases they pass an object with a success property as callback and probably other options. |
72 | | - * Normalize the argument so that it's always the latter case. |
73 | | - * |
74 | | - * @param {Object|Function} ajax properties, or just a success function |
75 | | - * @return Function |
76 | | - */ |
77 | | - normalizeAjaxOptions: function( arg ) { |
78 | | - if ( typeof arg === 'function' ) { |
79 | | - var ok = arg; |
80 | | - arg = { 'ok': ok }; |
81 | | - } |
82 | | - if (! arg.ok ) { |
83 | | - throw Error( "ajax options must include ok callback" ); |
84 | | - } |
85 | | - return arg; |
86 | | - }, |
87 | | - |
88 | | - /** |
89 | | - * Perform API get request |
90 | | - * |
91 | | - * @param {Object} request parameters |
92 | | - * @param {Object|Function} ajax properties, or just a success function |
93 | | - */ |
94 | | - get: function( parameters, ajaxOptions ) { |
95 | | - ajaxOptions = this.normalizeAjaxOptions( ajaxOptions ); |
96 | | - ajaxOptions.type = 'GET'; |
97 | | - this.ajax( parameters, ajaxOptions ); |
98 | | - }, |
99 | | - |
100 | | - /** |
101 | | - * Perform API post request |
102 | | - * TODO post actions for nonlocal will need proxy |
103 | | - * |
104 | | - * @param {Object} request parameters |
105 | | - * @param {Object|Function} ajax properties, or just a success function |
106 | | - */ |
107 | | - post: function( parameters, ajaxOptions ) { |
108 | | - ajaxOptions = this.normalizeAjaxOptions( ajaxOptions ); |
109 | | - ajaxOptions.type = 'POST'; |
110 | | - this.ajax( parameters, ajaxOptions ); |
111 | | - }, |
112 | | - |
113 | | - /** |
114 | | - * Perform the API call. |
115 | | - * |
116 | | - * @param {Object} request parameters |
117 | | - * @param {Object} ajax properties |
118 | | - */ |
119 | | - ajax: function( parameters, ajaxOptions ) { |
120 | | - parameters = $j.extend( {}, this.defaults.parameters, parameters ); |
121 | | - ajaxOptions = $j.extend( {}, this.defaults.ajax, ajaxOptions ); |
122 | | - |
123 | | - // Some deployed MediaWiki >= 1.17 forbid periods in URLs, due to an IE XSS bug |
124 | | - // So let's escape them here. See bug #28235 |
125 | | - // This works because jQuery accepts data as a query string or as an Object |
126 | | - ajaxOptions.data = $j.param( parameters ).replace( /\./g, '%2E' ); |
127 | | - |
128 | | - ajaxOptions.error = function( xhr, textStatus, exception ) { |
129 | | - ajaxOptions.err( 'http', { xhr: xhr, textStatus: textStatus, exception: exception } ); |
130 | | - }; |
131 | | - |
132 | | - |
133 | | - /* success just means 200 OK; also check for output and API errors */ |
134 | | - ajaxOptions.success = function( result ) { |
135 | | - if ( result === undefined || result === null || result === '' ) { |
136 | | - ajaxOptions.err( "ok-but-empty", "OK response but empty result (check HTTP headers?)" ); |
137 | | - } else if ( result.error ) { |
138 | | - var code = result.error.code === undefined ? 'unknown' : result.error.code; |
139 | | - ajaxOptions.err( code, result ); |
140 | | - } else { |
141 | | - ajaxOptions.ok( result ); |
142 | | - } |
143 | | - }; |
144 | | - |
145 | | - $j.ajax( ajaxOptions ); |
146 | | - |
147 | | - } |
148 | | - |
149 | | - }; |
150 | | - |
151 | | - /** |
152 | | - * This is a list of errors we might receive from the API. |
153 | | - * For now, this just documents our expectation that there should be similar messages |
154 | | - * available. |
155 | | - */ |
156 | | - mw.Api.errors = [ |
157 | | - /* occurs when POST aborted - jQuery 1.4 can't distinguish abort or lost connection from 200 OK + empty result */ |
158 | | - 'ok-but-empty', |
159 | | - |
160 | | - // timeout |
161 | | - 'timeout', |
162 | | - |
163 | | - /* really a warning, but we treat it like an error */ |
164 | | - 'duplicate', |
165 | | - 'duplicate-archive', |
166 | | - |
167 | | - /* upload succeeded, but no image info. |
168 | | - this is probably impossible, but might as well check for it */ |
169 | | - 'noimageinfo', |
170 | | - |
171 | | - /* remote errors, defined in API */ |
172 | | - 'uploaddisabled', |
173 | | - 'nomodule', |
174 | | - 'mustbeposted', |
175 | | - 'badaccess-groups', |
176 | | - 'stashfailed', |
177 | | - 'missingresult', |
178 | | - 'missingparam', |
179 | | - 'invalid-file-key', |
180 | | - 'copyuploaddisabled', |
181 | | - 'mustbeloggedin', |
182 | | - 'empty-file', |
183 | | - 'file-too-large', |
184 | | - 'filetype-missing', |
185 | | - 'filetype-banned', |
186 | | - 'filename-tooshort', |
187 | | - 'illegal-filename', |
188 | | - 'verification-error', |
189 | | - 'hookaborted', |
190 | | - 'unknown-error', |
191 | | - 'internal-error', |
192 | | - 'overwrite', |
193 | | - 'badtoken', |
194 | | - 'fetchfileerror', |
195 | | - 'fileexists-shared-forbidden' |
196 | | - ]; |
197 | | - |
198 | | - /** |
199 | | - * This is a list of warnings we might receive from the API. |
200 | | - * For now, this just documents our expectation that there should be similar messages |
201 | | - * available. |
202 | | - */ |
203 | | - |
204 | | - mw.Api.warnings = [ |
205 | | - 'duplicate', |
206 | | - 'exists' |
207 | | - ]; |
208 | | - |
209 | | -}) ( window.mediaWiki, jQuery ); |
Index: trunk/extensions/UploadWizard/resources/mw.Title.js |
— | — | @@ -1,259 +0,0 @@ |
2 | | -/** |
3 | | - * Represents a "title", or some piece of content, tracked by MediaWiki. |
4 | | - * There are numerous ways of representing the title, so this bundles them all together so you |
5 | | - * don't have to write conversion functions between human-readable version, api version, local filename... |
6 | | - * |
7 | | - * Let's learn how MediaWiki thinks of all this (see Title.php). |
8 | | - * |
9 | | - * MEDIAWIKI'S TERMINOLOGY |
10 | | - * 'text' form means that underscores are changed to spaces. human-readable. |
11 | | - * |
12 | | - * Title = PrefixedDb "User_talk:Foo_bar.jpg" |
13 | | - * PrefixedText = "User talk:Foo bar.jpg" |
14 | | - * - Prefix = "User_talk" (also called namespace, this is a controlled list of namespaces (see wg* globals)) |
15 | | - * - Main = "Foo_bar.jpg" |
16 | | - * - MainText = "Foo bar.jpg" |
17 | | - * - Name = "Foo_bar" |
18 | | - * - NameText = "Foo bar" |
19 | | - * - Extension "jpg" |
20 | | - * |
21 | | - * all of the above are implemented as 'get' functions, i.e |
22 | | - * getPrefixedDb(), getPrefixedText(), etc. |
23 | | - * |
24 | | - * in addition: |
25 | | - * .toString(), and therefore all string coercions, are the same as getPrefixedDb(); |
26 | | - * .toText() gives you the most common human-readable representation (getPrefixedText()). |
27 | | - * |
28 | | - * n.b. this class does not handle URI-escaping |
29 | | - * |
30 | | - * n.b. this class relies on the existence of the globals: |
31 | | - * wgFormattedNamespaces - array of id numbers (as strings) to localized namespace names |
32 | | - * wgArticlePath |
33 | | - */ |
34 | | - |
35 | | -/** |
36 | | - * Constructor |
37 | | - */ |
38 | | -( function( $j, mw, undefined ) { |
39 | | - mw.Title = function( title, namespace ) { |
40 | | - // integer namespace id |
41 | | - var ns = 0; |
42 | | - |
43 | | - // should be '' if ns == 0, or namespace name plus ':' |
44 | | - var prefix = ''; |
45 | | - |
46 | | - // name in canonical 'database' form |
47 | | - var name = null; |
48 | | - |
49 | | - // extension |
50 | | - var ext = null; |
51 | | - |
52 | | - /** |
53 | | - * strip some illegal chars: control chars, colon, less than, greater than, brackets, braces, pipe, whitespace |
54 | | - * yes, I know this leaves other insanity intact, like unicode bidi chars, but let's start someplace |
55 | | - * @return {String} |
56 | | - */ |
57 | | - function clean( s ) { |
58 | | - if ( s !== undefined ) { |
59 | | - return s.replace( /[\x00-\x1f\x23\x3a\x3c\x3e\x5b\x5d\x7b\x7c\x7d\x7f\s]+/g, '_' ); |
60 | | - } |
61 | | - } |
62 | | - |
63 | | - /** |
64 | | - * Convenience method: return string like ".jpg", or "" if no extension |
65 | | - * @return {String} |
66 | | - */ |
67 | | - function getDotExtension() { |
68 | | - return ext ? '.' + ext : ''; |
69 | | - } |
70 | | - |
71 | | - function text( s ) { |
72 | | - if ( typeof s === 'string' ) { |
73 | | - return s.replace( /_/g, ' ' ); |
74 | | - } else { |
75 | | - return ''; |
76 | | - } |
77 | | - } |
78 | | - |
79 | | - /** |
80 | | - * Get in prefixed DB form = File:Foo_bar.jpg |
81 | | - * most useful for API calls, anything that must id the "title" |
82 | | - */ |
83 | | - this.toString = this.getPrefixedDb = function() { |
84 | | - return prefix + this.getMain(); |
85 | | - }; |
86 | | - |
87 | | - /** |
88 | | - * Get in a form similar to how it's displayed in heading on MediaWiki: "File:Foo bar.jpg" |
89 | | - * @return {String} |
90 | | - */ |
91 | | - this.toText = this.getPrefixedText = function() { |
92 | | - return text( this.toString() ); |
93 | | - }; |
94 | | - |
95 | | - /** |
96 | | - * The file without namespace, "Foo_bar.jpg" |
97 | | - * @return {String} |
98 | | - */ |
99 | | - this.getMain = function() { |
100 | | - return name + getDotExtension(); |
101 | | - }; |
102 | | - |
103 | | - /** |
104 | | - * The "text" form "Foo bar.jpg" |
105 | | - * @return {String} |
106 | | - */ |
107 | | - this.getMainText = function() { |
108 | | - return text( this.getMain() ); |
109 | | - }; |
110 | | - |
111 | | - /** |
112 | | - * the name, as "Foo bar" |
113 | | - * @return {String} |
114 | | - */ |
115 | | - this.getNameText = function() { |
116 | | - return text( name ); |
117 | | - }; |
118 | | - |
119 | | - /** |
120 | | - * Set the "name" portion, removing illegal characters and canonicalizing with first character uppercased. |
121 | | - * @param {String} s: name |
122 | | - * @return {mw.Title} this |
123 | | - */ |
124 | | - this.setName = function( s ) { |
125 | | - name = mw.ucfirst( $j.trim( clean ( s ) ) ); |
126 | | - return this; |
127 | | - }; |
128 | | - |
129 | | - /** |
130 | | - * Set the name portion from human readable text, e.g. "foo bar" -> "Foo_bar" |
131 | | - * @param {String} s: name |
132 | | - * @return {mw.Title} this |
133 | | - */ |
134 | | - this.setNameText = function( s ) { |
135 | | - name = mw.ucfirst( $j.trim( clean ( s ) ) ).replace( / /g, '_' ); |
136 | | - return this; |
137 | | - }; |
138 | | - |
139 | | - /** |
140 | | - * Set namespace by canonical namespace id (integer) |
141 | | - * This global is an object of string key-vals, so we make sure to look up "-2" not -2 |
142 | | - * @param id |
143 | | - * @return {mw.Title} this |
144 | | - */ |
145 | | - this.setNamespaceById = function( id ) { |
146 | | - ns = id; |
147 | | - prefix = wgFormattedNamespaces[ "" + id ].replace( / /g, '_' ) + ':'; |
148 | | - return this; |
149 | | - }; |
150 | | - |
151 | | - /** |
152 | | - * Set namespace by canonical name like 'file'; |
153 | | - * @param namespace name |
154 | | - * @return {mw.Title} this |
155 | | - */ |
156 | | - this.setNamespace = function( s ) { |
157 | | - if ( mw.Title.ns[s] === undefined ) { |
158 | | - throw new Error( 'unrecognized namespace: ' + s ); |
159 | | - } |
160 | | - return this.setNamespaceById( mw.Title.ns[s] ); |
161 | | - }; |
162 | | - |
163 | | - /** |
164 | | - * Given a localized prefix like "File" set the namespace id |
165 | | - * Note that for most wikis, "" is a valid prefix, will set namespace to 0 |
166 | | - * @param localized namespace name |
167 | | - * @return {mw.Title} this |
168 | | - */ |
169 | | - this.setPrefix = function( s ) { |
170 | | - var found = false; |
171 | | - var _this = this; |
172 | | - $j.each( wgFormattedNamespaces, function( k, v ) { |
173 | | - if ( s === v ) { |
174 | | - found = true; |
175 | | - _this.setNamespaceById( parseInt( k, 10 ) ); |
176 | | - return false; |
177 | | - } |
178 | | - } ); |
179 | | - if ( !found ) { |
180 | | - throw new Error( "unrecognized namespace prefix" ); |
181 | | - } |
182 | | - return this; |
183 | | - }; |
184 | | - |
185 | | - /** |
186 | | - * Set the "extension" portion, removing illegal characters |
187 | | - * @param {String} s: name |
188 | | - * @return {mw.Title} this |
189 | | - */ |
190 | | - this.setExtension = function(s) { |
191 | | - ext = clean( s.toLowerCase() ); |
192 | | - return this; |
193 | | - }; |
194 | | - |
195 | | - |
196 | | - /** |
197 | | - * Get the extension (returns null if there was none) |
198 | | - * @return {String|null} extension |
199 | | - */ |
200 | | - this.getExtension = function() { |
201 | | - return ext; |
202 | | - }; |
203 | | - |
204 | | - |
205 | | - /** |
206 | | - * Return the URL to this title |
207 | | - * returns null if there is no wgArticlePath |
208 | | - * @return {String|null} |
209 | | - */ |
210 | | - this.getUrl = function() { |
211 | | - return wgArticlePath ? wgArticlePath.replace( '$1', this.toString() ) : null; |
212 | | - }; |
213 | | - |
214 | | - // initialization |
215 | | - var matches = title.match( /^(?:([^:]+):)?(.*?)(?:\.(\w{1,5}))?$/ ); |
216 | | - if ( matches.length ) { |
217 | | - matches[1] && this.setPrefix( matches[1] ); |
218 | | - matches[2] && this.setName( matches[2] ); |
219 | | - matches[3] && this.setExtension( matches[3] ); |
220 | | - } else { |
221 | | - throw new Error( "couldn't parse title '" + title + "'" ); |
222 | | - } |
223 | | - |
224 | | - if ( namespace !== undefined ) { |
225 | | - this.setNamespace( namespace ); |
226 | | - } |
227 | | - |
228 | | - }; |
229 | | - |
230 | | - // This is similar to the NS_* constants in MediaWiki. |
231 | | - mw.Title.ns = { |
232 | | - 'main': 0, |
233 | | - 'talk': 1, |
234 | | - 'user': 2, |
235 | | - 'user_talk': 3, |
236 | | - 'project': 4, |
237 | | - 'project_talk': 5, |
238 | | - 'file': 6, |
239 | | - 'file_talk': 7, |
240 | | - 'mediawiki': 8, |
241 | | - 'mediawiki_talk': 9, |
242 | | - 'template': 10, |
243 | | - 'template_talk': 11, |
244 | | - 'help': 12, |
245 | | - 'help_talk': 13, |
246 | | - 'category': 14, |
247 | | - 'category_talk': 15 |
248 | | - }; |
249 | | - |
250 | | - /** |
251 | | - * Upper-case the first letter of a string. |
252 | | - * @param {string} |
253 | | - * @return {string} with first letter uppercased. |
254 | | - */ |
255 | | - mw.ucfirst = function( s ) { |
256 | | - return s.substring(0,1).toUpperCase() + s.substr(1); |
257 | | - }; |
258 | | - |
259 | | -} )( jQuery, mediaWiki ); |
260 | | - |
Index: trunk/extensions/UploadWizard/resources/mw.Api.titleblacklist.js |
— | — | @@ -1,48 +0,0 @@ |
2 | | -// library to assist with API calls on titleblacklist |
3 | | - |
4 | | -( function( mw, $ ) { |
5 | | - |
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, { |
10 | | - /** |
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 |
15 | | - */ |
16 | | - isBlacklisted: function( title, callback, err ) { |
17 | | - var params = { |
18 | | - 'action': 'titleblacklist', |
19 | | - 'tbaction': 'create', |
20 | | - 'tbtitle': title.toString() |
21 | | - }; |
22 | | - |
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 | | - }; |
34 | | - } 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" }; |
37 | | - } |
38 | | - callback( result ); |
39 | | - } else { |
40 | | - callback ( false ); |
41 | | - } |
42 | | - }; |
43 | | - |
44 | | - return this.get( params, ok, err ); |
45 | | - |
46 | | - } |
47 | | - |
48 | | - } ); |
49 | | -} )( window.mediaWiki, jQuery ); |
Index: trunk/extensions/UploadWizard/resources/mw.Feedback.js |
— | — | @@ -1,138 +0,0 @@ |
2 | | -( function( mw, $, undefined ) { |
3 | | - |
4 | | - /** |
5 | | - * Thingy for collecting user feedback on a wiki page |
6 | | - * @param {mw.Api} api properly configured to talk to this wiki |
7 | | - * @param {mw.Title} the title of the page where you collect feedback |
8 | | - * @param {id} a string identifying this feedback form to separate it from others on the same page |
9 | | - */ |
10 | | - mw.Feedback = function( api, feedbackTitle ) { |
11 | | - var _this = this; |
12 | | - this.api = api; |
13 | | - this.feedbackTitle = feedbackTitle; |
14 | | - this.setup(); |
15 | | - }; |
16 | | - |
17 | | - mw.Feedback.prototype = { |
18 | | - setup: function() { |
19 | | - var _this = this; |
20 | | - |
21 | | - // Set up buttons for dialog box. We have to do it the hard way since the json keys are localized |
22 | | - _this.buttons = {}; |
23 | | - _this.buttons[ gM( 'mwe-upwiz-feedback-cancel' ) ] = function() { _this.cancel(); }; |
24 | | - _this.buttons[ gM( 'mwe-upwiz-feedback-submit' ) ] = function() { _this.submit(); }; |
25 | | - |
26 | | - var $feedbackPageLink = $j( '<a></a>' ).attr( { 'href': _this.feedbackTitle.getUrl(), 'target': '_blank' } ); |
27 | | - this.$dialog = |
28 | | - $( '<div style="position:relative;"></div>' ).append( |
29 | | - $( '<div class="mwe-upwiz-feedback-mode mwe-upwiz-feedback-form"></div>' ).append( |
30 | | - $( '<div style="margin-top:0.4em;"></div>' ).append( |
31 | | - $( '<small></small>' ).msg( 'mwe-upwiz-feedback-note', |
32 | | - _this.feedbackTitle.getNameText(), |
33 | | - $feedbackPageLink ) |
34 | | - ), |
35 | | - $( '<div style="margin-top:1em;"></div>' ).append( |
36 | | - gM( 'mwe-upwiz-feedback-subject' ), |
37 | | - $( '<br/>' ), |
38 | | - $( '<input type="text" class="mwe-upwiz-feedback-subject" name="subject" maxlength="60" style="width:99%;"/>' ) |
39 | | - ), |
40 | | - $( '<div style="margin-top:0.4em;"></div>' ).append( |
41 | | - gM( 'mwe-upwiz-feedback-message' ), |
42 | | - $( '<br/>' ), |
43 | | - $( '<textarea name="message" class="mwe-upwiz-feedback-message" style="width:99%;" rows="5" cols="60"></textarea>' ) |
44 | | - ) |
45 | | - ), |
46 | | - $( '<div class="mwe-upwiz-feedback-mode mwe-upwiz-feedback-submitting" style="text-align:center;margin:3em 0;"></div>' ).append( |
47 | | - gM( 'mwe-upwiz-feedback-adding' ), |
48 | | - $( '<br/>' ), |
49 | | - $( '<img src="http://upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif" />' ) |
50 | | - ), |
51 | | - $( '<div class="mwe-upwiz-feedback-mode mwe-upwiz-feedback-error" style="position:relative;"></div>' ).append( |
52 | | - $( '<div class="mwe-upwiz-feedback-error-msg style="color:#990000;margin-top:0.4em;"></div>' ) |
53 | | - |
54 | | - ) |
55 | | - ).dialog({ |
56 | | - width: 500, |
57 | | - autoOpen: false, |
58 | | - title: gM( 'mwe-upwiz-feedback-title' ), |
59 | | - modal: true, |
60 | | - buttons: _this.buttons |
61 | | - }); |
62 | | - |
63 | | - this.subjectInput = this.$dialog.find( 'input.mwe-upwiz-feedback-subject' ).get(0); |
64 | | - this.messageInput = this.$dialog.find( 'textarea.mwe-upwiz-feedback-message' ).get(0); |
65 | | - this.displayForm(); |
66 | | - }, |
67 | | - |
68 | | - display: function( s ) { |
69 | | - this.$dialog.dialog( { buttons:{} } ); // hide the buttons |
70 | | - this.$dialog.find( '.mwe-upwiz-feedback-mode' ).hide(); // hide everything |
71 | | - this.$dialog.find( '.mwe-upwiz-feedback-' + s ).show(); // show the desired div |
72 | | - }, |
73 | | - |
74 | | - displaySubmitting: function() { |
75 | | - this.display( 'submitting' ); |
76 | | - }, |
77 | | - |
78 | | - displayForm: function( contents ) { |
79 | | - this.subjectInput.value = (contents && contents.subject) ? contents.subject : ''; |
80 | | - this.messageInput.value = (contents && contents.message) ? contents.message : ''; |
81 | | - |
82 | | - this.display( 'form' ); |
83 | | - this.$dialog.dialog( { buttons: this.buttons } ); // put the buttons back |
84 | | - }, |
85 | | - |
86 | | - displayError: function( message ) { |
87 | | - this.display( 'error' ); |
88 | | - this.$dialog.find( '.mwe-upwiz-feedback-error-msg' ).msg( message ); |
89 | | - }, |
90 | | - |
91 | | - cancel: function() { |
92 | | - this.$dialog.dialog( 'close' ); |
93 | | - }, |
94 | | - |
95 | | - submit: function() { |
96 | | - var _this = this; |
97 | | - |
98 | | - // get the values to submit |
99 | | - var subject = this.subjectInput.value; |
100 | | - |
101 | | - var message = "<small>User agent: " + navigator.userAgent + "</small>\n\n" |
102 | | - + this.messageInput.value; |
103 | | - if ( message.indexOf( '~~~' ) == -1 ) { |
104 | | - message += " ~~~~"; |
105 | | - } |
106 | | - |
107 | | - this.displaySubmitting(); |
108 | | - |
109 | | - var ok = function( result ) { |
110 | | - if ( result.edit !== undefined ) { |
111 | | - if ( result.edit.result === 'Success' ) { |
112 | | - _this.$dialog.dialog( 'close' ); // edit complete, close dialog box |
113 | | - } else { |
114 | | - _this.displayError( 'mwe-upwiz-feedback-error1' ); // unknown API result |
115 | | - } |
116 | | - } else { |
117 | | - displayError( 'mwe-upwiz-feedback-error2' ); // edit failed |
118 | | - } |
119 | | - }; |
120 | | - |
121 | | - var err = function( code, info ) { |
122 | | - displayError( 'mwe-upwiz-feedback-error3' ); // ajax request failed |
123 | | - }; |
124 | | - |
125 | | - this.api.newSection( this.feedbackTitle, subject, message, ok, err ); |
126 | | - |
127 | | - }, // close submit button function |
128 | | - |
129 | | - |
130 | | - launch: function( contents ) { |
131 | | - this.displayForm( contents ); |
132 | | - this.$dialog.dialog( 'open' ); |
133 | | - this.subjectInput.focus(); |
134 | | - } |
135 | | - |
136 | | - }; |
137 | | - |
138 | | - |
139 | | -} )( window.mediaWiki, jQuery ); |
Index: trunk/extensions/UploadWizard/resources/mw.Api.category.js |
— | — | @@ -1,106 +0,0 @@ |
2 | | -// library to assist with API calls on categories |
3 | | - |
4 | | -( function( mw, $ ) { |
5 | | - |
6 | | - $.extend( mw.Api.prototype, { |
7 | | - /** |
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 |
12 | | - * @return ajax call object |
13 | | - */ |
14 | | - isCategory: function( title, callback, err ) { |
15 | | - var params = { |
16 | | - 'prop': 'categoryinfo', |
17 | | - 'titles': title.toString() |
18 | | - }; |
19 | | - |
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 | | - return this.get( params, { ok: ok, err: err } ); |
33 | | - |
34 | | - }, |
35 | | - |
36 | | - /** |
37 | | - * Get a list of categories that match a certain prefix. |
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 |
43 | | - */ |
44 | | - getCategoriesByPrefix: function( prefix, callback, err ) { |
45 | | - |
46 | | - // fetch with allpages to only get categories that have a corresponding description page. |
47 | | - var params = { |
48 | | - 'list': 'allpages', |
49 | | - 'apprefix': prefix, |
50 | | - 'apnamespace': mw.config.get('wgNamespaceIds').category |
51 | | - }; |
52 | | - |
53 | | - var ok = function( data ) { |
54 | | - var texts = []; |
55 | | - if ( data.query && data.query.allpages ) { |
56 | | - $.each( data.query.allpages, function( i, category ) { |
57 | | - texts.push( new mw.Title( category.title ).getNameText() ); |
58 | | - } ); |
59 | | - } |
60 | | - callback( texts ); |
61 | | - }; |
62 | | - |
63 | | - return this.get( params, { ok: ok, err: err } ); |
64 | | - |
65 | | - }, |
66 | | - |
67 | | - |
68 | | - /** |
69 | | - * 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 |
75 | | - */ |
76 | | - getCategories: function( title, callback, err, async ) { |
77 | | - var params = { |
78 | | - prop: 'categories', |
79 | | - titles: title.toString() |
80 | | - }; |
81 | | - if ( async === undefined ) { |
82 | | - async = true; |
83 | | - } |
84 | | - |
85 | | - var ok = function( data ) { |
86 | | - var ret = false; |
87 | | - if ( data.query && data.query.pages ) { |
88 | | - $.each( data.query.pages, function( id, page ) { |
89 | | - if ( page.categories ) { |
90 | | - if ( typeof ret !== 'object' ) { |
91 | | - ret = []; |
92 | | - } |
93 | | - $.each( page.categories, function( i, cat ) { |
94 | | - ret.push( new mw.Title( cat.title ) ); |
95 | | - } ); |
96 | | - } |
97 | | - } ); |
98 | | - } |
99 | | - callback( ret ); |
100 | | - }; |
101 | | - |
102 | | - return this.get( params, { ok: ok, err: err, async: async } ); |
103 | | - |
104 | | - } |
105 | | - |
106 | | - } ); |
107 | | -} )( window.mediaWiki, jQuery ); |
Index: trunk/extensions/UploadWizard/resources/mw.Api.edit.js |
— | — | @@ -1,117 +0,0 @@ |
2 | | -// library to assist with edits |
3 | | - |
4 | | -( function( mw, $, undefined ) { |
5 | | - |
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, { |
10 | | - |
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 |
18 | | - */ |
19 | | - postWithEditToken: function( params, ok, err ) { |
20 | | - var api = this; |
21 | | - if ( cachedToken === null ) { |
22 | | - // We don't have a valid cached token, so get a fresh one and try posting. |
23 | | - // We do not trap any 'badtoken' or 'notoken' errors, because we don't want |
24 | | - // an infinite loop. If this fresh token is bad, something else is very wrong. |
25 | | - var useTokenToPost = function( token ) { |
26 | | - params.token = token; |
27 | | - api.post( params, ok, err ); |
28 | | - }; |
29 | | - api.getEditToken( useTokenToPost, err ); |
30 | | - } else { |
31 | | - // We do have a token, but it might be expired. So if it is 'bad' then |
32 | | - // start over with a new token. |
33 | | - params.token = cachedToken; |
34 | | - var getTokenIfBad = function( code, result ) { |
35 | | - if ( code === 'badtoken' ) { |
36 | | - cachedToken = null; // force a new token |
37 | | - api.postWithEditToken( params, ok, err ); |
38 | | - } else { |
39 | | - err( code, result ); |
40 | | - } |
41 | | - }; |
42 | | - api.post( params, { 'ok' : ok, 'err' : getTokenIfBad }); |
43 | | - } |
44 | | - }, |
45 | | - |
46 | | - /** |
47 | | - * Api helper to grab an edit token |
48 | | - * |
49 | | - * token callback has signature ( String token ) |
50 | | - * error callback has signature ( String code, Object results, XmlHttpRequest xhr, Exception exception ) |
51 | | - * Note that xhr and exception are only available for 'http_*' errors |
52 | | - * code may be any http_* error code (see mw.Api), or 'token_missing' |
53 | | - * |
54 | | - * @param {Function} received token callback |
55 | | - * @param {Function} error callback |
56 | | - */ |
57 | | - 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; |
74 | | - } |
75 | | - } ); |
76 | | - if ( token !== undefined ) { |
77 | | - cachedToken = token; |
78 | | - tokenCallback( token ); |
79 | | - } else { |
80 | | - err( 'token-missing', data ); |
81 | | - } |
82 | | - }; |
83 | | - |
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 | | - }, |
95 | | - |
96 | | - /** |
97 | | - * 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 |
103 | | - */ |
104 | | - newSection: function( title, header, message, ok, err ) { |
105 | | - var params = { |
106 | | - action: 'edit', |
107 | | - section: 'new', |
108 | | - format: 'json', |
109 | | - title: title.toString(), |
110 | | - summary: header, |
111 | | - text: message |
112 | | - }; |
113 | | - this.postWithEditToken( params, ok, err ); |
114 | | - } |
115 | | - |
116 | | - } ); // end extend |
117 | | - |
118 | | -} )( window.mediaWiki, jQuery ); |