diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2015-06-04 07:31:04 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2015-06-04 07:58:39 +0200 |
commit | f6d65e533c62f6deb21342d4901ece24497b433e (patch) | |
tree | f28adf0362d14bcd448f7b65a7aaf38650f923aa /resources/src/mediawiki.messagePoster | |
parent | c27b2e832fe25651ef2410fae85b41072aae7519 (diff) |
Update to MediaWiki 1.25.1
Diffstat (limited to 'resources/src/mediawiki.messagePoster')
3 files changed, 200 insertions, 0 deletions
diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js new file mode 100644 index 00000000..91366ff5 --- /dev/null +++ b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js @@ -0,0 +1,38 @@ +/*global OO*/ +( function ( mw ) { + /** + * This is the abstract base class for MessagePoster implementations. + * + * @abstract + * @class + * + * @constructor + * @param {mw.Title} title Title to post to + */ + mw.messagePoster.MessagePoster = function MwMessagePoster() {}; + + OO.initClass( mw.messagePoster.MessagePoster ); + + /** + * Post a message (with subject and body) to a talk page. + * + * @param {string} subject Subject/topic title; plaintext only (no wikitext or HTML) + * @param {string} body Body, as wikitext. Signature code will automatically be added + * by MessagePosters that require one, unless the message already contains the string + * ~~~. + * @return {jQuery.Promise} Promise completing when the post succeeds or fails. + * For failure, will be rejected with three arguments: + * + * - primaryError - Primary error code. For a mw.Api failure, + * this should be 'api-fail'. + * - secondaryError - Secondary error code. For a mw.Api failure, + * this, should be mw.Api's code, e.g. 'http', 'ok-but-empty', or the error passed through + * from the server. + * - details - Further details about the error + * + * @localdoc + * The base class currently does nothing, but could be used for shared analytics or + * something. + */ + mw.messagePoster.MessagePoster.prototype.post = function () {}; +}( mediaWiki ) ); diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js new file mode 100644 index 00000000..296576b4 --- /dev/null +++ b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js @@ -0,0 +1,53 @@ +/*global OO*/ +( function ( mw, $ ) { + /** + * This is an implementation of MessagePoster for wikitext talk pages. + * + * @class mw.messagePoster.WikitextMessagePoster + * @extends mw.messagePoster.MessagePoster + * + * @constructor + * @param {mw.Title} title Wikitext page in a talk namespace, to post to + */ + function WikitextMessagePoster( title ) { + this.api = new mw.Api(); + this.title = title; + } + + OO.inheritClass( + WikitextMessagePoster, + mw.messagePoster.MessagePoster + ); + + /** + * @inheritdoc + */ + WikitextMessagePoster.prototype.post = function ( subject, body ) { + mw.messagePoster.WikitextMessagePoster.parent.prototype.post.call( this, subject, body ); + + // Add signature if needed + if ( body.indexOf( '~~~' ) === -1 ) { + body += '\n\n~~~~'; + } + + return this.api.newSection( + this.title, + subject, + body, + { redirect: true } + ).then( function ( resp, jqXHR ) { + if ( resp.edit.result === 'Success' ) { + return $.Deferred().resolve( resp, jqXHR ); + } else { + // mediawiki.api.js checks for resp.error. Are there actually cases where the + // request fails, but it's not caught there? + return $.Deferred().reject( 'api-unexpected' ); + } + }, function ( code, details ) { + return $.Deferred().reject( 'api-fail', code, details ); + } ).promise(); + }; + + mw.messagePoster.factory.register( 'wikitext', WikitextMessagePoster ); + mw.messagePoster.WikitextMessagePoster = WikitextMessagePoster; +}( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js new file mode 100644 index 00000000..9d280800 --- /dev/null +++ b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js @@ -0,0 +1,109 @@ +/*global OO*/ +( function ( mw, $ ) { + /** + * This is a factory for MessagePoster objects, which allows a pluggable to way to script leaving a + * talk page message. + * + * @class mw.messagePoster.factory + * @singleton + */ + function MwMessagePosterFactory() { + this.api = new mw.Api(); + this.contentModelToClass = {}; + } + + OO.initClass( MwMessagePosterFactory ); + + // Note: This registration scheme is currently not compatible with LQT, since that doesn't + // have its own content model, just islqttalkpage. LQT pages will be passed to the wikitext + // MessagePoster. + /** + * Registers a MessagePoster subclass for a given content model. + * + * @param {string} contentModel Content model of pages this MessagePoster can post to + * @param {Function} messagePosterConstructor Constructor for MessagePoster + */ + MwMessagePosterFactory.prototype.register = function ( contentModel, messagePosterConstructor ) { + if ( this.contentModelToClass[contentModel] !== undefined ) { + throw new Error( 'The content model \'' + contentModel + '\' is already registered.' ); + } + + this.contentModelToClass[contentModel] = messagePosterConstructor; + }; + + /** + * Unregisters a given content model + * This is exposed for testing and should not normally be needed. + * + * @param {string} contentModel Content model to unregister + */ + MwMessagePosterFactory.prototype.unregister = function ( contentModel ) { + delete this.contentModelToClass[contentModel]; + }; + + /** + * Creates a MessagePoster, given a title. A promise for this is returned. + * This works by determining the content model, then loading the corresponding + * module (which will register the MessagePoster class), and finally constructing it. + * + * This does not require the message and should be called as soon as possible, so it does the + * API and ResourceLoader requests in the background. + * + * @param {mw.Title} title Title that will be posted to + * @return {jQuery.Promise} Promise resolving to a mw.messagePoster.MessagePoster. + * For failure, rejected with up to three arguments: + * + * - errorCode Error code string + * - error Error explanation + * - details Further error details + */ + MwMessagePosterFactory.prototype.create = function ( title ) { + var pageId, page, contentModel, moduleName, + factory = this; + + return this.api.get( { + action: 'query', + prop: 'info', + indexpageids: 1, + titles: title.getPrefixedDb() + } ).then( function ( result ) { + if ( result.query.pageids.length > 0 ) { + pageId = result.query.pageids[0]; + page = result.query.pages[pageId]; + + contentModel = page.contentmodel; + moduleName = 'mediawiki.messagePoster.' + contentModel; + return mw.loader.using( moduleName ).then( function () { + return factory.createForContentModel( + contentModel, + title + ); + }, function () { + return $.Deferred().reject( 'failed-to-load-module', 'Failed to load the \'' + moduleName + '\' module' ); + } ); + } else { + return $.Deferred().reject( 'unexpected-response', 'Unexpected API response' ); + } + }, function ( errorCode, details ) { + return $.Deferred().reject( 'content-model-query-failed', errorCode, details ); + } ).promise(); + }; + + /** + * Creates a MessagePoster instance, given a title and content model + * + * @private + * + * @param {string} contentModel Content model of title + * @param {mw.Title} title Title being posted to + * @return {mw.messagePoster.MessagePoster} + * + */ + MwMessagePosterFactory.prototype.createForContentModel = function ( contentModel, title ) { + return new this.contentModelToClass[contentModel]( title ); + }; + + mw.messagePoster = { + factory: new MwMessagePosterFactory() + }; +}( mediaWiki, jQuery ) ); |