mw.widgets.CategoryMultiselectWidget use TagMultiselectWidget
authorPrateek Saxena <prtksxna@gmail.com>
Thu, 8 Mar 2018 06:09:07 +0000 (11:39 +0530)
committerVolkerE <volker.e@wikimedia.org>
Wed, 27 Jun 2018 07:36:56 +0000 (07:36 +0000)
…also rename mw.widgets.CategoryCapsuleItemWidget to
mw.widgets.CategoryTagItemWidget.

Bug: T183299
Depends-on: Ia0732faff2d98f1ca07da5fbe1f2abc27f71a617
Change-Id: I2146d8ce6505dae55750b4b12bd806b83796c1c5

resources/Resources.php
resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js [deleted file]
resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js
resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js [new file with mode: 0644]

index 0595bb0..15669e2 100644 (file)
@@ -2607,7 +2607,7 @@ return [
        ],
        'mediawiki.widgets.CategoryMultiselectWidget' => [
                'scripts' => [
-                       'resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js',
+                       'resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js',
                ],
                'dependencies' => [
diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js b/resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js
deleted file mode 100644 (file)
index 17da7d8..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*!
- * MediaWiki Widgets - CategoryCapsuleItemWidget class.
- *
- * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-( function ( $, mw ) {
-
-       var hasOwn = Object.prototype.hasOwnProperty;
-
-       /**
-        * @class mw.widgets.PageExistenceCache
-        * @private
-        * @param {mw.Api} [api]
-        */
-       function PageExistenceCache( api ) {
-               this.api = api || new mw.Api();
-               this.processExistenceCheckQueueDebounced = OO.ui.debounce( this.processExistenceCheckQueue );
-               this.currentRequest = null;
-               this.existenceCache = {};
-               this.existenceCheckQueue = {};
-       }
-
-       /**
-        * Check for existence of pages in the queue.
-        *
-        * @private
-        */
-       PageExistenceCache.prototype.processExistenceCheckQueue = function () {
-               var queue, titles,
-                       cache = this;
-               if ( this.currentRequest ) {
-                       // Don't fire off a million requests at the same time
-                       this.currentRequest.always( function () {
-                               cache.currentRequest = null;
-                               cache.processExistenceCheckQueueDebounced();
-                       } );
-                       return;
-               }
-               queue = this.existenceCheckQueue;
-               this.existenceCheckQueue = {};
-               titles = Object.keys( queue ).filter( function ( title ) {
-                       if ( hasOwn.call( cache.existenceCache, title ) ) {
-                               queue[ title ].resolve( cache.existenceCache[ title ] );
-                       }
-                       return !hasOwn.call( cache.existenceCache, title );
-               } );
-               if ( !titles.length ) {
-                       return;
-               }
-               this.currentRequest = this.api.get( {
-                       formatversion: 2,
-                       action: 'query',
-                       prop: [ 'info' ],
-                       titles: titles
-               } ).done( function ( response ) {
-                       var
-                               normalized = {},
-                               pages = {};
-                       $.each( response.query.normalized || [], function ( index, data ) {
-                               normalized[ data.fromencoded ? decodeURIComponent( data.from ) : data.from ] = data.to;
-                       } );
-                       $.each( response.query.pages, function ( index, page ) {
-                               pages[ page.title ] = !page.missing;
-                       } );
-                       titles.forEach( function ( title ) {
-                               var normalizedTitle = title;
-                               while ( hasOwn.call( normalized, normalizedTitle ) ) {
-                                       normalizedTitle = normalized[ normalizedTitle ];
-                               }
-                               cache.existenceCache[ title ] = pages[ normalizedTitle ];
-                               queue[ title ].resolve( cache.existenceCache[ title ] );
-                       } );
-               } );
-       };
-
-       /**
-        * Register a request to check whether a page exists.
-        *
-        * @private
-        * @param {mw.Title} title
-        * @return {jQuery.Promise} Promise resolved with true if the page exists or false otherwise
-        */
-       PageExistenceCache.prototype.checkPageExistence = function ( title ) {
-               var key = title.getPrefixedText();
-               if ( !hasOwn.call( this.existenceCheckQueue, key ) ) {
-                       this.existenceCheckQueue[ key ] = $.Deferred();
-               }
-               this.processExistenceCheckQueueDebounced();
-               return this.existenceCheckQueue[ key ].promise();
-       };
-
-       /**
-        * @class mw.widgets.ForeignTitle
-        * @private
-        * @extends mw.Title
-        *
-        * @constructor
-        * @param {string} title
-        * @param {number} [namespace]
-        */
-       function ForeignTitle( title, namespace ) {
-               // We only need to handle categories here... but we don't know the target language.
-               // So assume that any namespace-like prefix is the 'Category' namespace...
-               title = title.replace( /^(.+?)_*:_*(.*)$/, 'Category:$2' ); // HACK
-               ForeignTitle.parent.call( this, title, namespace );
-       }
-       OO.inheritClass( ForeignTitle, mw.Title );
-       ForeignTitle.prototype.getNamespacePrefix = function () {
-               // We only need to handle categories here...
-               return 'Category:'; // HACK
-       };
-
-       /**
-        * Category selector capsule item widget. Extends OO.ui.CapsuleItemWidget with the ability to link
-        * to the given page, and to show its existence status (i.e., whether it is a redlink).
-        *
-        * @class mw.widgets.CategoryCapsuleItemWidget
-        * @uses mw.Api
-        * @extends OO.ui.CapsuleItemWidget
-        *
-        * @constructor
-        * @param {Object} config Configuration options
-        * @cfg {mw.Title} title Page title to use (required)
-        * @cfg {string} [apiUrl] API URL, if not the current wiki's API
-        */
-       mw.widgets.CategoryCapsuleItemWidget = function MWWCategoryCapsuleItemWidget( config ) {
-               var widget = this;
-               // Parent constructor
-               mw.widgets.CategoryCapsuleItemWidget.parent.call( this, $.extend( {
-                       data: config.title.getMainText(),
-                       label: config.title.getMainText()
-               }, config ) );
-
-               // Properties
-               this.title = config.title;
-               this.apiUrl = config.apiUrl || '';
-               this.$link = $( '<a>' )
-                       .text( this.label )
-                       .attr( 'target', '_blank' )
-                       .on( 'click', function ( e ) {
-                               // CapsuleMultiselectWidget really wants to prevent you from clicking the link, don't let it
-                               e.stopPropagation();
-                       } );
-
-               // Initialize
-               this.setMissing( false );
-               this.$label.replaceWith( this.$link );
-               this.setLabelElement( this.$link );
-
-               if ( !this.constructor.static.pageExistenceCaches[ this.apiUrl ] ) {
-                       this.constructor.static.pageExistenceCaches[ this.apiUrl ] =
-                               new PageExistenceCache( new mw.ForeignApi( this.apiUrl ) );
-               }
-               this.constructor.static.pageExistenceCaches[ this.apiUrl ]
-                       .checkPageExistence( new ForeignTitle( this.title.getPrefixedText() ) )
-                       .done( function ( exists ) {
-                               widget.setMissing( !exists );
-                       } );
-       };
-
-       /* Setup */
-
-       OO.inheritClass( mw.widgets.CategoryCapsuleItemWidget, OO.ui.CapsuleItemWidget );
-
-       /* Static Properties */
-
-       /**
-        * Map of API URLs to PageExistenceCache objects.
-        *
-        * @static
-        * @inheritable
-        * @property {Object}
-        */
-       mw.widgets.CategoryCapsuleItemWidget.static.pageExistenceCaches = {
-               '': new PageExistenceCache()
-       };
-
-       /* Methods */
-
-       /**
-        * Update label link href and CSS classes to reflect page existence status.
-        *
-        * @private
-        * @param {boolean} missing Whether the page is missing (does not exist)
-        */
-       mw.widgets.CategoryCapsuleItemWidget.prototype.setMissing = function ( missing ) {
-               var
-                       title = new ForeignTitle( this.title.getPrefixedText() ), // HACK
-                       prefix = this.apiUrl.replace( '/w/api.php', '' ); // HACK
-
-               this.missing = missing;
-
-               if ( !missing ) {
-                       this.$link
-                               .attr( 'href', prefix + title.getUrl() )
-                               .attr( 'title', title.getPrefixedText() )
-                               .removeClass( 'new' );
-               } else {
-                       this.$link
-                               .attr( 'href', prefix + title.getUrl( { action: 'edit', redlink: 1 } ) )
-                               .attr( 'title', mw.msg( 'red-link-title', title.getPrefixedText() ) )
-                               .addClass( 'new' );
-               }
-       };
-
-}( jQuery, mediaWiki ) );
index 354fcd9..c506379 100644 (file)
@@ -9,7 +9,7 @@
                NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
 
        /**
-        * Category selector widget. Displays an OO.ui.CapsuleMultiselectWidget
+        * Category selector widget. Displays an OO.ui.MenuTagMultiselectWidget
         * and autocompletes with available categories.
         *
         *     mw.loader.using( 'mediawiki.widgets.CategoryMultiselectWidget', function () {
@@ -27,7 +27,7 @@
         *
         * @class mw.widgets.CategoryMultiselectWidget
         * @uses mw.Api
-        * @extends OO.ui.CapsuleMultiselectWidget
+        * @extends OO.ui.MenuTagMultiselectWidget
         * @mixins OO.ui.mixin.PendingElement
         *
         * @constructor
@@ -62,7 +62,7 @@
                OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) );
 
                // Event handler to call the autocomplete methods
-               this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
+               this.input.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
 
                // Initialize
                this.api = config.api || new mw.Api();
@@ -71,7 +71,7 @@
 
        /* Setup */
 
-       OO.inheritClass( mw.widgets.CategoryMultiselectWidget, OO.ui.CapsuleMultiselectWidget );
+       OO.inheritClass( mw.widgets.CategoryMultiselectWidget, OO.ui.MenuTagMultiselectWidget );
        OO.mixinClass( mw.widgets.CategoryMultiselectWidget, OO.ui.mixin.PendingElement );
 
        /* Methods */
         */
        mw.widgets.CategoryMultiselectWidget.prototype.updateMenuItems = function () {
                this.getMenu().clearItems();
-               this.getNewMenuItems( this.$input.val() ).then( function ( items ) {
+               this.getNewMenuItems( this.input.$input.val() ).then( function ( items ) {
                        var existingItems, filteredItems,
                                menu = this.getMenu();
 
                        // Never show the menu if the input lost focus in the meantime
-                       if ( !this.$input.is( ':focus' ) ) {
+                       if ( !this.input.$input.is( ':focus' ) ) {
                                return;
                        }
 
        /**
         * @inheritdoc
         */
-       mw.widgets.CategoryMultiselectWidget.prototype.createItemWidget = function ( data ) {
+       mw.widgets.CategoryMultiselectWidget.prototype.createTagItemWidget = function ( data ) {
                var title = mw.Title.makeTitle( NS_CATEGORY, data );
-               if ( !title ) {
-                       return null;
-               }
-               return new mw.widgets.CategoryCapsuleItemWidget( {
+
+               return new mw.widgets.CategoryTagItemWidget( {
                        apiUrl: this.api.apiUrl || undefined,
                        title: title
                } );
         */
        mw.widgets.CategoryMultiselectWidget.prototype.findItemFromData = function ( data ) {
                // This is a bit of a hack... We have to canonicalize the data in the same way that
-               // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
+               // #createItemWidget and CategoryTagItemWidget will do, otherwise we won't find duplicates.
                var title = mw.Title.makeTitle( NS_CATEGORY, data );
                if ( !title ) {
                        return null;
diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js b/resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js
new file mode 100644 (file)
index 0000000..f0b2d44
--- /dev/null
@@ -0,0 +1,209 @@
+/*!
+ * MediaWiki Widgets - CategoryTagItemWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function ( $, mw ) {
+
+       var hasOwn = Object.prototype.hasOwnProperty;
+
+       /**
+        * @class mw.widgets.PageExistenceCache
+        * @private
+        * @param {mw.Api} [api]
+        */
+       function PageExistenceCache( api ) {
+               this.api = api || new mw.Api();
+               this.processExistenceCheckQueueDebounced = OO.ui.debounce( this.processExistenceCheckQueue );
+               this.currentRequest = null;
+               this.existenceCache = {};
+               this.existenceCheckQueue = {};
+       }
+
+       /**
+        * Check for existence of pages in the queue.
+        *
+        * @private
+        */
+       PageExistenceCache.prototype.processExistenceCheckQueue = function () {
+               var queue, titles,
+                       cache = this;
+               if ( this.currentRequest ) {
+                       // Don't fire off a million requests at the same time
+                       this.currentRequest.always( function () {
+                               cache.currentRequest = null;
+                               cache.processExistenceCheckQueueDebounced();
+                       } );
+                       return;
+               }
+               queue = this.existenceCheckQueue;
+               this.existenceCheckQueue = {};
+               titles = Object.keys( queue ).filter( function ( title ) {
+                       if ( hasOwn.call( cache.existenceCache, title ) ) {
+                               queue[ title ].resolve( cache.existenceCache[ title ] );
+                       }
+                       return !hasOwn.call( cache.existenceCache, title );
+               } );
+               if ( !titles.length ) {
+                       return;
+               }
+               this.currentRequest = this.api.get( {
+                       formatversion: 2,
+                       action: 'query',
+                       prop: [ 'info' ],
+                       titles: titles
+               } ).done( function ( response ) {
+                       var
+                               normalized = {},
+                               pages = {};
+                       $.each( response.query.normalized || [], function ( index, data ) {
+                               normalized[ data.fromencoded ? decodeURIComponent( data.from ) : data.from ] = data.to;
+                       } );
+                       $.each( response.query.pages, function ( index, page ) {
+                               pages[ page.title ] = !page.missing;
+                       } );
+                       titles.forEach( function ( title ) {
+                               var normalizedTitle = title;
+                               while ( hasOwn.call( normalized, normalizedTitle ) ) {
+                                       normalizedTitle = normalized[ normalizedTitle ];
+                               }
+                               cache.existenceCache[ title ] = pages[ normalizedTitle ];
+                               queue[ title ].resolve( cache.existenceCache[ title ] );
+                       } );
+               } );
+       };
+
+       /**
+        * Register a request to check whether a page exists.
+        *
+        * @private
+        * @param {mw.Title} title
+        * @return {jQuery.Promise} Promise resolved with true if the page exists or false otherwise
+        */
+       PageExistenceCache.prototype.checkPageExistence = function ( title ) {
+               var key = title.getPrefixedText();
+               if ( !hasOwn.call( this.existenceCheckQueue, key ) ) {
+                       this.existenceCheckQueue[ key ] = $.Deferred();
+               }
+               this.processExistenceCheckQueueDebounced();
+               return this.existenceCheckQueue[ key ].promise();
+       };
+
+       /**
+        * @class mw.widgets.ForeignTitle
+        * @private
+        * @extends mw.Title
+        *
+        * @constructor
+        * @param {string} title
+        * @param {number} [namespace]
+        */
+       function ForeignTitle( title, namespace ) {
+               // We only need to handle categories here... but we don't know the target language.
+               // So assume that any namespace-like prefix is the 'Category' namespace...
+               title = title.replace( /^(.+?)_*:_*(.*)$/, 'Category:$2' ); // HACK
+               ForeignTitle.parent.call( this, title, namespace );
+       }
+       OO.inheritClass( ForeignTitle, mw.Title );
+       ForeignTitle.prototype.getNamespacePrefix = function () {
+               // We only need to handle categories here...
+               return 'Category:'; // HACK
+       };
+
+       /**
+        * Category selector capsule item widget. Extends OO.ui.CapsuleItemWidget with the ability to link
+        * to the given page, and to show its existence status (i.e., whether it is a redlink).
+        *
+        * @class mw.widgets.CategoryTagItemWidget
+        * @uses mw.Api
+        * @extends OO.ui.TagItemWidget
+        *
+        * @constructor
+        * @param {Object} config Configuration options
+        * @cfg {mw.Title} title Page title to use (required)
+        * @cfg {string} [apiUrl] API URL, if not the current wiki's API
+        */
+       mw.widgets.CategoryTagItemWidget = function MWWCategoryTagItemWidget( config ) {
+               var widget = this;
+               // Parent constructor
+               mw.widgets.CategoryTagItemWidget.parent.call( this, $.extend( {
+                       data: config.title.getMainText(),
+                       label: config.title.getMainText()
+               }, config ) );
+
+               // Properties
+               this.title = config.title;
+               this.apiUrl = config.apiUrl || '';
+               this.$link = $( '<a>' )
+                       .text( this.label )
+                       .attr( 'target', '_blank' )
+                       .on( 'click', function ( e ) {
+                               // TagMultiselectWidget really wants to prevent you from clicking the link, don't let it
+                               e.stopPropagation();
+                       } );
+
+               // Initialize
+               this.setMissing( false );
+               this.$label.replaceWith( this.$link );
+               this.setLabelElement( this.$link );
+
+               if ( !this.constructor.static.pageExistenceCaches[ this.apiUrl ] ) {
+                       this.constructor.static.pageExistenceCaches[ this.apiUrl ] =
+                               new PageExistenceCache( new mw.ForeignApi( this.apiUrl ) );
+               }
+               this.constructor.static.pageExistenceCaches[ this.apiUrl ]
+                       .checkPageExistence( new ForeignTitle( this.title.getPrefixedText() ) )
+                       .done( function ( exists ) {
+                               widget.setMissing( !exists );
+                       } );
+       };
+
+       /* Setup */
+
+       OO.inheritClass( mw.widgets.CategoryTagItemWidget, OO.ui.TagItemWidget );
+
+       /* Static Properties */
+
+       /**
+        * Map of API URLs to PageExistenceCache objects.
+        *
+        * @static
+        * @inheritable
+        * @property {Object}
+        */
+       mw.widgets.CategoryTagItemWidget.static.pageExistenceCaches = {
+               '': new PageExistenceCache()
+       };
+
+       /* Methods */
+
+       /**
+        * Update label link href and CSS classes to reflect page existence status.
+        *
+        * @private
+        * @param {boolean} missing Whether the page is missing (does not exist)
+        */
+       mw.widgets.CategoryTagItemWidget.prototype.setMissing = function ( missing ) {
+               var
+                       title = new ForeignTitle( this.title.getPrefixedText() ), // HACK
+                       prefix = this.apiUrl.replace( '/w/api.php', '' ); // HACK
+
+               this.missing = missing;
+
+               if ( !missing ) {
+                       this.$link
+                               .attr( 'href', prefix + title.getUrl() )
+                               .attr( 'title', title.getPrefixedText() )
+                               .removeClass( 'new' );
+               } else {
+                       this.$link
+                               .attr( 'href', prefix + title.getUrl( { action: 'edit', redlink: 1 } ) )
+                               .attr( 'title', mw.msg( 'red-link-title', title.getPrefixedText() ) )
+                               .addClass( 'new' );
+               }
+       };
+
+       // For backwards compatibility. See T183299.
+       mw.widgets.CategoryCapsuleItemWidget = mw.widgets.CategoryTagItemWidget;
+}( jQuery, mediaWiki ) );