Avoid pointless use of isset() in LBFactoryMulti()
[mediawiki.git] / resources / src / mediawiki.messagePoster / mediawiki.messagePoster.factory.js
blobb069d4ab4d1997ca27572548d5c42f568c34af1a
1 ( function ( mw, $ ) {
2         /**
3          * Factory for MessagePoster objects. This provides a pluggable to way to script the action
4          * of adding a message to someone's talk page.
5          *
6          * @class mw.messagePoster.factory
7          * @singleton
8          */
9         function MessagePosterFactory() {
10                 this.contentModelToClass = {};
11         }
13         OO.initClass( MessagePosterFactory );
15         // Note: This registration scheme is currently not compatible with LQT, since that doesn't
16         // have its own content model, just islqttalkpage. LQT pages will be passed to the wikitext
17         // MessagePoster.
18         /**
19          * Register a MessagePoster subclass for a given content model.
20          *
21          * @param {string} contentModel Content model of pages this MessagePoster can post to
22          * @param {Function} constructor Constructor of a MessagePoster subclass
23          */
24         MessagePosterFactory.prototype.register = function ( contentModel, constructor ) {
25                 if ( this.contentModelToClass[ contentModel ] !== undefined ) {
26                         throw new Error( 'Content model "' + contentModel + '" is already registered' );
27                 }
29                 this.contentModelToClass[ contentModel ] = constructor;
30         };
32         /**
33          * Unregister a given content model.
34          * This is exposed for testing and should not normally be used.
35          *
36          * @param {string} contentModel Content model to unregister
37          */
38         MessagePosterFactory.prototype.unregister = function ( contentModel ) {
39                 delete this.contentModelToClass[ contentModel ];
40         };
42         /**
43          * Create a MessagePoster for given a title.
44          *
45          * A promise for this is returned. It works by determining the content model, then loading
46          * the corresponding module (which registers the MessagePoster class), and finally constructing
47          * an object for the given title.
48          *
49          * This does not require the message and should be called as soon as possible, so that the
50          * API and ResourceLoader requests run in the background.
51          *
52          * @param {mw.Title} title Title that will be posted to
53          * @param {string} [apiUrl] api.php URL if the title is on another wiki
54          * @return {jQuery.Promise} Promise resolving to a mw.messagePoster.MessagePoster.
55          *   For failure, rejected with up to three arguments:
56          *
57          *   - errorCode Error code string
58          *   - error Error explanation
59          *   - details Further error details
60          */
61         MessagePosterFactory.prototype.create = function ( title, apiUrl ) {
62                 var factory = this,
63                         api = apiUrl ? new mw.ForeignApi( apiUrl ) : new mw.Api();
65                 return api.get( {
66                         action: 'query',
67                         prop: 'info',
68                         indexpageids: true,
69                         titles: title.getPrefixedDb()
70                 } ).then( function ( data ) {
71                         var pageId, page, contentModel, moduleName;
72                         if ( !data.query.pageids[ 0 ] ) {
73                                 return $.Deferred().reject( 'unexpected-response', 'Unexpected API response' );
74                         }
75                         pageId = data.query.pageids[ 0 ];
76                         page = data.query.pages[ pageId ];
78                         contentModel = page.contentmodel;
79                         moduleName = 'mediawiki.messagePoster.' + contentModel;
80                         return mw.loader.using( moduleName ).then( function () {
81                                 return factory.createForContentModel(
82                                         contentModel,
83                                         title,
84                                         api
85                                 );
86                         }, function () {
87                                 return $.Deferred().reject( 'failed-to-load-module', 'Failed to load "' + moduleName + '"' );
88                         } );
89                 }, function ( error, details ) {
90                         return $.Deferred().reject( 'content-model-query-failed', error, details );
91                 } );
92         };
94         /**
95          * Creates a MessagePoster instance, given a title and content model
96          *
97          * @private
98          * @param {string} contentModel Content model of title
99          * @param {mw.Title} title Title being posted to
100          * @param {mw.Api} api mw.Api instance that the instance should use
101          * @return {mw.messagePoster.MessagePoster}
102          */
103         MessagePosterFactory.prototype.createForContentModel = function ( contentModel, title, api ) {
104                 return new this.contentModelToClass[ contentModel ]( title, api );
105         };
107         mw.messagePoster = {
108                 factory: new MessagePosterFactory()
109         };
110 }( mediaWiki, jQuery ) );