mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 02:23:58 +00:00
Follow redirects in the category widgets
Display the redirects nicely in the UI, etc. Bug: 52414 Change-Id: Ib62144cb90899d0c525d6f08f6b5f1159b7d2a86
This commit is contained in:
parent
8d99aa88c8
commit
9c2e1d8048
|
@ -38,6 +38,7 @@ ve.ui.MWCategoryInputWidget = function VeUiMWCategoryInputWidget( categoryWidget
|
|||
// Initialization
|
||||
this.$element.addClass( 've-ui-mwCategoryInputWidget' );
|
||||
this.lookupMenu.$element.addClass( 've-ui-mwCategoryInputWidget-menu' );
|
||||
this.categoryRedirects = [];
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -67,7 +68,8 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupRequest = function () {
|
|||
'action': 'query',
|
||||
'prop': 'pageprops',
|
||||
'titles': ( data[1] || [] ).join( '|' ),
|
||||
'ppprop': 'hiddencat'
|
||||
'ppprop': 'hiddencat',
|
||||
'redirects': ''
|
||||
} );
|
||||
return propsJqXhr;
|
||||
} ).promise( { abort: function () {
|
||||
|
@ -86,18 +88,31 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupRequest = function () {
|
|||
* @param {Mixed} data Response from server
|
||||
*/
|
||||
ve.ui.MWCategoryInputWidget.prototype.getLookupCacheItemFromData = function ( data ) {
|
||||
var categoryWidget = this.categoryWidget, result = {};
|
||||
var categoryInputWidget = this, result = {};
|
||||
if ( data.query && data.query.pages ) {
|
||||
$.each( data.query.pages, function ( pageId, pageInfo ) {
|
||||
var title = mw.Title.newFromText( pageInfo.title );
|
||||
if ( title ) {
|
||||
result[title.getMainText()] = !!( pageInfo.pageprops && pageInfo.pageprops.hiddencat !== undefined );
|
||||
categoryWidget.categoryHiddenStatus[pageInfo.title] = result[title.getMainText()];
|
||||
categoryInputWidget.categoryWidget.categoryHiddenStatus[pageInfo.title] = result[title.getMainText()];
|
||||
} else {
|
||||
mw.log.warning( '"' + pageInfo.title + '" is an invalid title!' );
|
||||
}
|
||||
} );
|
||||
}
|
||||
if ( data.query && data.query.redirects ) {
|
||||
$.each( data.query.redirects, function ( index, redirectInfo ) {
|
||||
var foundIdentical = false;
|
||||
$.each( categoryInputWidget.categoryRedirects, function ( index, existingRedirectInfo ) {
|
||||
if ( existingRedirectInfo.from === redirectInfo.from && existingRedirectInfo.to === redirectInfo.to ) {
|
||||
foundIdentical = true;
|
||||
}
|
||||
} );
|
||||
if ( !foundIdentical ) {
|
||||
categoryInputWidget.categoryRedirects.push( redirectInfo );
|
||||
}
|
||||
} );
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
@ -119,7 +134,20 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
|||
category = this.getCategoryItemFromValue( this.value ),
|
||||
existingCategories = this.categoryWidget.getCategories(),
|
||||
matchingCategories = [],
|
||||
hiddenCategories = [];
|
||||
hiddenCategories = [],
|
||||
redirectStorage = {},
|
||||
itemTitle,
|
||||
searchForQueryWithinRedirectInfo = function ( element ) {
|
||||
return element.lastIndexOf( new mw.Title( 'Category:' + category.value ).getPrefixedText(), 0 ) === 0;
|
||||
};
|
||||
|
||||
$.each( this.categoryRedirects, function () {
|
||||
if ( redirectStorage.hasOwnProperty( this.to ) && redirectStorage[this.to].indexOf( this.from ) === -1 ) {
|
||||
redirectStorage[this.to].push( this.from );
|
||||
} else {
|
||||
redirectStorage[this.to] = [this.from];
|
||||
}
|
||||
} );
|
||||
|
||||
$.each( data, function ( title, hiddenStatus ) {
|
||||
if ( hiddenStatus ) {
|
||||
|
@ -140,14 +168,22 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
|||
existingCategoryItems.push( item );
|
||||
}
|
||||
}
|
||||
|
||||
// Matching categories
|
||||
for ( i = 0, len = matchingCategories.length; i < len; i++ ) {
|
||||
item = matchingCategories[i];
|
||||
itemTitle = new mw.Title( 'Category:' + item ).getPrefixedText();
|
||||
if (
|
||||
ve.indexOf( item, existingCategories ) === -1 &&
|
||||
item.lastIndexOf( category.value, 0 ) === 0
|
||||
item.lastIndexOf( category.value, 0 ) === 0 || (
|
||||
redirectStorage[itemTitle] !== undefined &&
|
||||
$.grep( redirectStorage[itemTitle], searchForQueryWithinRedirectInfo ).length
|
||||
)
|
||||
) {
|
||||
if ( item === category.value ) {
|
||||
if ( ( item === category.value ) || (
|
||||
redirectStorage[itemTitle] !== undefined &&
|
||||
redirectStorage[itemTitle].indexOf( new mw.Title( 'Category:' + category.value ).getPrefixedText() ) !== -1
|
||||
) ) {
|
||||
exactMatch = true;
|
||||
}
|
||||
matchingCategoryItems.push( item );
|
||||
|
@ -156,16 +192,24 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
|||
// Hidden categories
|
||||
for ( i = 0, len = hiddenCategories.length; i < len; i++ ) {
|
||||
item = hiddenCategories[i];
|
||||
itemTitle = new mw.Title( 'Category:' + item ).getPrefixedText();
|
||||
if (
|
||||
ve.indexOf( item, existingCategories ) === -1 &&
|
||||
item.lastIndexOf( category.value, 0 ) === 0
|
||||
item.lastIndexOf( category.value, 0 ) === 0 || (
|
||||
redirectStorage[itemTitle] !== undefined &&
|
||||
$.grep( redirectStorage[itemTitle], searchForQueryWithinRedirectInfo ).length
|
||||
)
|
||||
) {
|
||||
if ( item === category.value ) {
|
||||
if ( ( item === category.value ) || (
|
||||
redirectStorage[itemTitle] !== undefined &&
|
||||
redirectStorage[itemTitle].indexOf( new mw.Title( 'Category:' + category.value ).getPrefixedText() ) !== -1
|
||||
) ) {
|
||||
exactMatch = true;
|
||||
}
|
||||
hiddenCategoryItems.push( item );
|
||||
}
|
||||
}
|
||||
|
||||
// New category
|
||||
if ( !exactMatch ) {
|
||||
newCategoryItems.push( category.value );
|
||||
|
@ -196,7 +240,7 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
|||
) );
|
||||
for ( i = 0, len = matchingCategoryItems.length; i < len; i++ ) {
|
||||
item = matchingCategoryItems[i];
|
||||
items.push( new OO.ui.MenuItemWidget( item, { '$': menu$, 'label': item } ) );
|
||||
items.push( this.getMenuItemWidgetFromCategoryName( item, menu$ ) );
|
||||
}
|
||||
}
|
||||
if ( hiddenCategoryItems.length ) {
|
||||
|
@ -205,13 +249,41 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da
|
|||
) );
|
||||
for ( i = 0, len = hiddenCategoryItems.length; i < len; i++ ) {
|
||||
item = hiddenCategoryItems[i];
|
||||
items.push( new OO.ui.MenuItemWidget( item, { '$': menu$, 'label': item } ) );
|
||||
items.push( this.getMenuItemWidgetFromCategoryName( item, menu$ ) );
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a OO.ui.MenuSectionItemWidget object for a given category name.
|
||||
* Deals with redirects.
|
||||
*
|
||||
* @method
|
||||
* @param {string} item Category name
|
||||
* @param {jQuery} menu$ Lookup menu jQuery
|
||||
* @returns {OO.ui.MenuSectionItemWidget} Menu item
|
||||
*/
|
||||
ve.ui.MWCategoryInputWidget.prototype.getMenuItemWidgetFromCategoryName = function ( item, menu$ ) {
|
||||
var itemTitle = new mw.Title( 'Category:' + item ).getPrefixedText(),
|
||||
redirectInfo = $.grep( this.categoryRedirects, function ( redirectInfo ) {
|
||||
return redirectInfo.to === itemTitle;
|
||||
} );
|
||||
if ( redirectInfo.length ) {
|
||||
return new OO.ui.MenuItemWidget( item, {
|
||||
'$': menu$,
|
||||
'autoFitLabel': false,
|
||||
'label': this.$( '<span>' )
|
||||
.text( new mw.Title( redirectInfo[0].from ).getMainText() )
|
||||
.append( '<br>↳ ' )
|
||||
.append( $( '<span>' ).text( new mw.Title( item ).getMainText() ) )
|
||||
} );
|
||||
} else {
|
||||
return new OO.ui.MenuItemWidget( item, { '$': menu$, 'label': item } );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a category item.
|
||||
*
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* @param {Object} [config] Configuration options
|
||||
* @cfg {Object} [item] Category item
|
||||
* @cfg {boolean} [hidden] Whether the category is hidden or not
|
||||
* @cfg {string} [redirectTo] The name of the category this category's page redirects to.
|
||||
*/
|
||||
ve.ui.MWCategoryItemWidget = function VeUiMWCategoryItemWidget( config ) {
|
||||
// Config intialization
|
||||
|
@ -47,7 +48,7 @@ ve.ui.MWCategoryItemWidget = function VeUiMWCategoryItemWidget( config ) {
|
|||
// Initialization
|
||||
this.$label
|
||||
.addClass( 've-ui-mwCategoryItemWidget-label' )
|
||||
.text( this.value );
|
||||
.text( config.redirectTo || this.value );
|
||||
this.$categoryItem
|
||||
.addClass( 've-ui-mwCategoryItemWidget-button' )
|
||||
.append( this.$label, this.$indicator );
|
||||
|
|
|
@ -29,6 +29,7 @@ ve.ui.MWCategoryWidget = function VeUiMWCategoryWidget( config ) {
|
|||
// Properties
|
||||
this.categories = {};
|
||||
this.categoryHiddenStatus = {};
|
||||
this.categoryRedirects = {}; // Source -> target
|
||||
this.popupState = false;
|
||||
this.savedPopupState = false;
|
||||
this.popup = new ve.ui.MWCategoryPopupWidget( {
|
||||
|
@ -215,7 +216,8 @@ ve.ui.MWCategoryWidget.prototype.queryCategoryHiddenStatus = function ( category
|
|||
action: 'query',
|
||||
prop: 'pageprops',
|
||||
titles: categoryNamesToQuery.join( '|' ),
|
||||
ppprop: 'hiddencat'
|
||||
ppprop: 'hiddencat',
|
||||
redirects: ''
|
||||
} ).then( function ( result ) {
|
||||
if ( result && result.query && result.query.pages ) {
|
||||
$.each( result.query.pages, function ( index, pageInfo ) {
|
||||
|
@ -223,6 +225,11 @@ ve.ui.MWCategoryWidget.prototype.queryCategoryHiddenStatus = function ( category
|
|||
categoryWidget.categoryHiddenStatus[pageInfo.title] = hiddenStatus;
|
||||
} );
|
||||
}
|
||||
if ( result && result.query && result.query.redirects ) {
|
||||
$.each( result.query.redirects, function ( index, redirectInfo ) {
|
||||
categoryWidget.categoryRedirects[redirectInfo.from] = redirectInfo.to;
|
||||
} );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
|
@ -244,15 +251,24 @@ ve.ui.MWCategoryWidget.prototype.addItems = function ( items, index ) {
|
|||
categoryWidget = this;
|
||||
|
||||
return this.queryCategoryHiddenStatus( categoryNames ).then( function () {
|
||||
var itemTitle, config;
|
||||
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||
item = items[i];
|
||||
|
||||
itemTitle = new mw.Title( item.name, mw.config.get( 'wgNamespaceIds' ).category ).getPrefixedText();
|
||||
// Create a widget using the item data
|
||||
categoryItem = new ve.ui.MWCategoryItemWidget( {
|
||||
config = {
|
||||
'$': categoryWidget.$,
|
||||
'item': item,
|
||||
'hidden': categoryWidget.categoryHiddenStatus[item.name]
|
||||
} );
|
||||
};
|
||||
if ( Object.prototype.hasOwnProperty.call( categoryWidget.categoryRedirects, itemTitle ) ) {
|
||||
config.redirectTo = new mw.Title(
|
||||
categoryWidget.categoryRedirects[itemTitle],
|
||||
mw.config.get( 'wgNamespaceIds' ).category
|
||||
).getMainText();
|
||||
}
|
||||
categoryItem = new ve.ui.MWCategoryItemWidget( config );
|
||||
categoryItem.connect( categoryWidget, {
|
||||
'savePopupState': 'onSavePopupState',
|
||||
'togglePopupMenu': 'onTogglePopupMenu'
|
||||
|
|
Loading…
Reference in a new issue