Localisation updates from https://translatewiki.net.
[mediawiki.git] / resources / src / mediawiki.messagePoster / factory.js
blobd1801629b253776bc241cc3aa0f19467667958aa
1 ( function () {
2         /**
3          * @classdesc Factory for MessagePoster objects. This provides a pluggable to way to script the
4          * action of adding a message to someone's talk page.
5          *
6          * The constructor is not publicly accessible; use [mw.messagePoster.factory]{@link mw.messagePoster} instead.
7          *
8          * @class MessagePosterFactory
9          * @singleton
10          * @hideconstructor
11          */
12         function MessagePosterFactory() {
13                 this.contentModelToClass = Object.create( null );
14         }
16         OO.initClass( MessagePosterFactory );
18         // Note: This registration scheme is currently not compatible with LQT, since that doesn't
19         // have its own content model, just islqttalkpage. LQT pages will be passed to the wikitext
20         // MessagePoster.
21         /**
22          * Register a MessagePoster subclass for a given content model.
23          *
24          * Usage example:
25          *
26          * ```js
27          *   function MyExamplePoster() {}
28          *   OO.inheritClass( MyExamplePoster, mw.messagePoster.MessagePoster );
29          *
30          *   mw.messagePoster.factory.register( 'mycontentmodel', MyExamplePoster );
31          * ```
32          *
33          * The JavaScript files(s) that register message posters for additional content
34          * models must be registered with MediaWiki via the `MessagePosterModule`
35          * extension attribute, like follows:
36          *
37          * ```json
38          *    "MessagePosterModule": {
39          *         "localBasePath": "", // (required)
40          *         "scripts": [], // relative file path(s) (required)
41          *         "dependencies": [], // module name(s) (optional)
42          *    }
43          * ```
44          *
45          * @memberof MessagePosterFactory
46          * @param {string} contentModel Content model of pages this MessagePoster can post to
47          * @param {Function} constructor Constructor of a MessagePoster subclass
48          */
49         MessagePosterFactory.prototype.register = function ( contentModel, constructor ) {
50                 if ( this.contentModelToClass[ contentModel ] ) {
51                         throw new Error( 'Content model "' + contentModel + '" is already registered' );
52                 }
54                 this.contentModelToClass[ contentModel ] = constructor;
55         };
57         /**
58          * Unregister a given content model.
59          * This is exposed for testing and should not normally be used.
60          *
61          * @memberof MessagePosterFactory
62          * @param {string} contentModel Content model to unregister
63          */
64         MessagePosterFactory.prototype.unregister = function ( contentModel ) {
65                 delete this.contentModelToClass[ contentModel ];
66         };
68         /**
69          * Create a MessagePoster for given a title.
70          *
71          * A promise for this is returned. It works by determining the content model, then loading
72          * the corresponding module (which registers the MessagePoster class), and finally constructing
73          * an object for the given title.
74          *
75          * This does not require the message and should be called as soon as possible, so that the
76          * API and ResourceLoader requests run in the background.
77          *
78          * @memberof MessagePosterFactory
79          * @param {mw.Title} title Title that will be posted to
80          * @param {string} [apiUrl] api.php URL if the title is on another wiki
81          * @return {jQuery.Promise} Promise resolving to a mw.messagePoster.MessagePoster.
82          *   For failure, rejected with up to three arguments:
83          *
84          *   - errorCode Error code string
85          *   - error Error explanation
86          *   - details Further error details
87          */
88         MessagePosterFactory.prototype.create = function ( title, apiUrl ) {
89                 const api = apiUrl ? new mw.ForeignApi( apiUrl ) : new mw.Api();
91                 return api.get( {
92                         formatversion: 2,
93                         action: 'query',
94                         prop: 'info',
95                         titles: title.getPrefixedDb()
96                 } ).then( ( data ) => {
97                         const page = data.query.pages[ 0 ];
98                         if ( !page ) {
99                                 return $.Deferred().reject( 'unexpected-response', 'Unexpected API response' );
100                         }
101                         const contentModel = page.contentmodel;
102                         if ( !this.contentModelToClass[ contentModel ] ) {
103                                 return $.Deferred().reject( 'content-model-unknown', 'No handler for "' + contentModel + '"' );
104                         }
105                         return new this.contentModelToClass[ contentModel ]( title, api );
106                 }, ( error, details ) => $.Deferred().reject( 'content-model-query-failed', error, details ) );
107         };
109         /**
110          * Library for posting messages to talk pages.
111          *
112          * @namespace mw.messagePoster
113          */
114         mw.messagePoster = {
115                 /** @type {MessagePosterFactory} */
116                 factory: new MessagePosterFactory()
117         };
118 }() );