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