diff options
Diffstat (limited to 'resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js')
-rw-r--r-- | resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js | 109 |
1 files changed, 109 insertions, 0 deletions
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 ) ); |