2 * MediaWiki Widgets - CategoryCapsuleItemWidget class.
4 * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
5 * @license The MIT License (MIT); see LICENSE.txt
10 * @class mw.widgets.PageExistenceCache
12 * @param {mw.Api} [api]
14 function PageExistenceCache( api
) {
15 this.api
= api
|| new mw
.Api();
16 this.processExistenceCheckQueueDebounced
= OO
.ui
.debounce( this.processExistenceCheckQueue
);
17 this.currentRequest
= null;
18 this.existenceCache
= {};
19 this.existenceCheckQueue
= {};
23 * Check for existence of pages in the queue.
27 PageExistenceCache
.prototype.processExistenceCheckQueue = function () {
29 if ( this.currentRequest
) {
30 // Don't fire off a million requests at the same time
31 this.currentRequest
.always( function () {
32 this.currentRequest
= null;
33 this.processExistenceCheckQueueDebounced();
37 queue
= this.existenceCheckQueue
;
38 this.existenceCheckQueue
= {};
39 titles
= Object
.keys( queue
).filter( function ( title
) {
40 if ( this.existenceCache
.hasOwnProperty( title
) ) {
41 queue
[ title
].resolve( this.existenceCache
[ title
] );
43 return !this.existenceCache
.hasOwnProperty( title
);
45 if ( !titles
.length
) {
48 this.currentRequest
= this.api
.get( {
53 } ).done( function ( response
) {
54 $.each( response
.query
.pages
, function ( index
, page
) {
55 var title
= new ForeignTitle( page
.title
).getPrefixedText();
56 this.existenceCache
[ title
] = !page
.missing
;
57 queue
[ title
].resolve( this.existenceCache
[ title
] );
63 * Register a request to check whether a page exists.
66 * @param {mw.Title} title
67 * @return {jQuery.Promise} Promise resolved with true if the page exists or false otherwise
69 PageExistenceCache
.prototype.checkPageExistence = function ( title
) {
70 var key
= title
.getPrefixedText();
71 if ( !this.existenceCheckQueue
[ key
] ) {
72 this.existenceCheckQueue
[ key
] = $.Deferred();
74 this.processExistenceCheckQueueDebounced();
75 return this.existenceCheckQueue
[ key
].promise();
79 * @class mw.widgets.ForeignTitle
86 function ForeignTitle() {
87 ForeignTitle
.parent
.apply( this, arguments
);
89 OO
.inheritClass( ForeignTitle
, mw
.Title
);
90 ForeignTitle
.prototype.getNamespacePrefix = function () {
91 // We only need to handle categories here...
92 return 'Category:'; // HACK
96 * @class mw.widgets.CategoryCapsuleItemWidget
98 * Category selector capsule item widget. Extends OO.ui.CapsuleItemWidget with the ability to link
99 * to the given page, and to show its existence status (i.e., whether it is a redlink).
102 * @extends OO.ui.CapsuleItemWidget
105 * @param {Object} config Configuration options
106 * @cfg {mw.Title} title Page title to use (required)
107 * @cfg {string} [apiUrl] API URL, if not the current wiki's API
109 mw
.widgets
.CategoryCapsuleItemWidget
= function MWWCategoryCapsuleItemWidget( config
) {
110 // Parent constructor
111 mw
.widgets
.CategoryCapsuleItemWidget
.parent
.call( this, $.extend( {
112 data
: config
.title
.getMainText(),
113 label
: config
.title
.getMainText()
117 this.title
= config
.title
;
118 this.apiUrl
= config
.apiUrl
|| '';
119 this.$link
= $( '<a>' )
121 .attr( 'target', '_blank' )
122 .on( 'click', function ( e
) {
123 // CapsuleMultiSelectWidget really wants to prevent you from clicking the link, don't let it
128 this.setMissing( false );
129 this.$label
.replaceWith( this.$link
);
130 this.setLabelElement( this.$link
);
133 if ( !this.constructor.static.pageExistenceCaches
[ this.apiUrl
] ) {
134 this.constructor.static.pageExistenceCaches
[ this.apiUrl
] =
135 new PageExistenceCache( new mw
.ForeignApi( this.apiUrl
) );
137 this.constructor.static.pageExistenceCaches
[ this.apiUrl
]
138 .checkPageExistence( new ForeignTitle( this.title
.getPrefixedText() ) )
139 .done( function ( exists
) {
140 this.setMissing( !exists
);
147 OO
.inheritClass( mw
.widgets
.CategoryCapsuleItemWidget
, OO
.ui
.CapsuleItemWidget
);
149 /* Static Properties */
153 * Map of API URLs to PageExistenceCache objects.
159 mw
.widgets
.CategoryCapsuleItemWidget
.static.pageExistenceCaches
= {
160 '': new PageExistenceCache()
167 * Update label link href and CSS classes to reflect page existence status.
170 * @param {boolean} missing Whether the page is missing (does not exist)
172 mw
.widgets
.CategoryCapsuleItemWidget
.prototype.setMissing = function ( missing
) {
174 title
= new ForeignTitle( this.title
.getPrefixedText() ), // HACK
175 prefix
= this.apiUrl
.replace( '/w/api.php', '' ); // HACK
177 this.missing
= missing
;
181 .attr( 'href', prefix
+ title
.getUrl() )
182 .attr( 'title', title
.getPrefixedText() )
183 .removeClass( 'new' );
186 .attr( 'href', prefix
+ title
.getUrl( { action
: 'edit', redlink
: 1 } ) )
187 .attr( 'title', mw
.msg( 'red-link-title', title
.getPrefixedText() ) )
192 }( jQuery
, mediaWiki
) );