r105646 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r105645‎ | r105646 | r105647 >
Date:04:48, 9 December 2011
Author:neilk
Status:ok (Comments)
Tags:
Comment:
add JS api, feedback libs from UW into core.
Modified paths:
  • /trunk/phase3/resources/Resources.php (modified) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.api.category.js (added) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.api.edit.js (added) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.api.js (added) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.api.parse.js (added) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.api.titleblacklist.js (added) (history)
  • /trunk/phase3/resources/mediawiki/mediawiki.feedback.js (added) (history)

Diff [purge]

Index: trunk/phase3/resources/Resources.php
@@ -497,10 +497,45 @@
498498 'debugScripts' => 'resources/mediawiki/mediawiki.log.js',
499499 'debugRaw' => false,
500500 ),
 501+ 'mediawiki.api' => array(
 502+ 'scripts' => 'resources/mediawiki/mediawiki.api.js',
 503+ ),
 504+ 'mediawiki.api.category' => array(
 505+ 'scripts' => 'resources/mediawiki/mediawiki.api.category.js',
 506+ 'dependencies' => array(
 507+ 'mediawiki.api',
 508+ 'mediawiki.Title'
 509+ ),
 510+ ),
 511+ 'mediawiki.api.edit' => array(
 512+ 'scripts' => 'resources/mediawiki/mediawiki.api.edit.js',
 513+ 'dependencies' => array(
 514+ 'mediawiki.api',
 515+ 'mediawiki.Title'
 516+ ),
 517+ ),
 518+ 'mediawiki.api.parse' => array(
 519+ 'scripts' => 'resources/mediawiki/mediawiki.api.parse.js',
 520+ 'dependencies' => 'mediawiki.api',
 521+ ),
 522+ 'mediawiki.api.titleblacklist' => array(
 523+ 'scripts' => 'resources/mediawiki/mediawiki.api.titleblacklist.js',
 524+ 'dependencies' => array(
 525+ 'mediawiki.api',
 526+ 'mediawiki.Title'
 527+ ),
 528+ ),
501529 'mediawiki.debug' => array(
502530 'scripts' => 'resources/mediawiki/mediawiki.debug.js',
503531 'styles' => 'resources/mediawiki/mediawiki.debug.css',
504532 ),
 533+ 'mediawiki.feedback' => array(
 534+ 'scripts' => 'resources/mediawiki/mediawiki.feedback.js',
 535+ 'dependencies' => array(
 536+ 'mediawiki.api.edit',
 537+ 'mediawiki.Title'
 538+ ),
 539+ ),
505540 'mediawiki.htmlform' => array(
506541 'scripts' => 'resources/mediawiki/mediawiki.htmlform.js',
507542 ),
Index: trunk/phase3/resources/mediawiki/mediawiki.api.parse.js
@@ -0,0 +1,29 @@
 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+
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.api.parse.js
___________________________________________________________________
Added: svn:eol-style
131 + native
Index: trunk/phase3/resources/mediawiki/mediawiki.api.titleblacklist.js
@@ -0,0 +1,48 @@
 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 );
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.api.titleblacklist.js
___________________________________________________________________
Added: svn:eol-style
150 + native
Index: trunk/phase3/resources/mediawiki/mediawiki.feedback.js
@@ -0,0 +1,138 @@
 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 );
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.feedback.js
___________________________________________________________________
Added: svn:eol-style
1140 + native
Index: trunk/phase3/resources/mediawiki/mediawiki.api.category.js
@@ -0,0 +1,106 @@
 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 );
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.api.category.js
___________________________________________________________________
Added: svn:eol-style
1108 + native
Index: trunk/phase3/resources/mediawiki/mediawiki.api.js
@@ -0,0 +1,208 @@
 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 );
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.api.js
___________________________________________________________________
Added: svn:eol-style
1210 + native
Index: trunk/phase3/resources/mediawiki/mediawiki.api.edit.js
@@ -0,0 +1,117 @@
 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 );
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.api.edit.js
___________________________________________________________________
Added: svn:eol-style
1119 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r105648remove libs now redundant with core JS resourcesneilk04:51, 9 December 2011
r106062merging extensions/VisualEditor....neilk18:47, 13 December 2011
r107011[mediawiki.api] clean up...krinkle23:52, 21 December 2011

Comments

#Comment by Reedy (talk | contribs)   14:51, 12 December 2011

I'm guessing this is still work in progress, but this leaves mediawiki.Feedback directly dependent on UW for gM, see bug 32979...

Seems to be part of bug 29099... Is jQueryMsg (from the extension or UW) coming into core soon? :)

#Comment by NeilK (talk | contribs)   19:21, 12 December 2011

for simple cases jQueryMsg is compatible with mediawiki.msg. The idea is that it should be a drop-in replacement when you want fancier processing for pluralized or grammar-ified arguments.

There are a few bugs in it and missing features which made me hold off on integrating it into core but I might do it anyway. It really should have gone out with the last release. Should try for next.

#Comment by NeilK (talk | contribs)   19:22, 12 December 2011

anyway as noted in bug #32979 I don't need jQueryMsg for feedback.js, so fixed it

Status & tagging log