Add parameter to API modules to apply change tags to log entries
[lhc/web/wiklou.git] / resources / src / mediawiki.messagePoster / mediawiki.messagePoster.factory.js
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 }
12
13 OO.initClass( MessagePosterFactory );
14
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 }
28
29 this.contentModelToClass[ contentModel ] = constructor;
30 };
31
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 };
41
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();
64
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 ];
77
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 };
93
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 };
106
107 mw.messagePoster = {
108 factory: new MessagePosterFactory()
109 };
110 }( mediaWiki, jQuery ) );