1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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 ) );
|