diff --git a/modules/ve-mw/init/ve.init.mw.LinkCache.js b/modules/ve-mw/init/ve.init.mw.LinkCache.js index 364ca6bd86..07bba4821b 100644 --- a/modules/ve-mw/init/ve.init.mw.LinkCache.js +++ b/modules/ve-mw/init/ve.init.mw.LinkCache.js @@ -51,6 +51,26 @@ return this.cache[name].promise(); }; + /** + * Look up data about a page in the cache. If the data about this page is already in the cache, + * this returns that data. Otherwise, it returns undefined. + * + * @param {string} name Normalized page title + * @returns {Object} Cache data for this name. + */ + ve.init.mw.LinkCache.prototype.getCached = function ( name ) { + var res; + if ( + Object.prototype.hasOwnProperty.call( this.cache, name ) && + this.cache[name].state() === 'resolved' + ) { + this.cache[name].done( function ( data ) { + res = data; + } ); + return res; + } + }; + /** * Add entries to the cache. * @param {Object} entries Object keyed by page title, with the values being data objects diff --git a/modules/ve-mw/ui/widgets/ve.ui.MWCategoryInputWidget.js b/modules/ve-mw/ui/widgets/ve.ui.MWCategoryInputWidget.js index 14af21b65a..623664f61f 100644 --- a/modules/ve-mw/ui/widgets/ve.ui.MWCategoryInputWidget.js +++ b/modules/ve-mw/ui/widgets/ve.ui.MWCategoryInputWidget.js @@ -69,14 +69,16 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupRequest = function () { * @param {Mixed} data Response from server */ ve.ui.MWCategoryInputWidget.prototype.getLookupCacheItemFromData = function ( data ) { - var result = []; + var result = [], linkCacheUpdate = {}; data.query = data.query || {}; $.each( data.query.allcategories || [], function ( index, category ) { result.push( category['*'] ); - this.categoryWidget.categoryHiddenStatus[category['*']] = category.hasOwnProperty( 'hidden' ); + linkCacheUpdate['Category:' + category['*']] = { missing: false, hidden: category.hasOwnProperty( 'hidden' ) }; }.bind( this ) ); + ve.init.platform.linkCache.set( linkCacheUpdate ); + return result; }; @@ -91,7 +93,6 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da itemWidgets = [], existingCategoryItems = [], matchingCategoryItems = [], hiddenCategoryItems = [], newCategoryItems = [], - category = this.getCategoryItemFromValue( this.value ), existingCategories = this.categoryWidget.getCategories(), linkCacheUpdate = {}, canonicalQueryValue = mw.Title.newFromText( this.value ); @@ -101,12 +102,18 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da } // Invalid titles just end up with canonicalQueryValue being null. $.each( data, function ( index, suggestedCategory ) { + var suggestedCacheEntry = ve.init.platform.linkCache.getCached( 'Category:' + suggestedCategory ); if ( canonicalQueryValue === suggestedCategory ) { exactMatch = true; } - linkCacheUpdate['Category:' + suggestedCategory] = { missing: false }; - if ( ve.indexOf( suggestedCategory, existingCategories ) === -1 && suggestedCategory.lastIndexOf( canonicalQueryValue, 0 ) === 0 ) { - if ( this.categoryWidget.categoryHiddenStatus[suggestedCategory] ) { + if ( !suggestedCacheEntry ) { + linkCacheUpdate['Category:' + suggestedCategory] = { missing: false }; + } + if ( + ve.indexOf( suggestedCategory, existingCategories ) === -1 && + suggestedCategory.lastIndexOf( canonicalQueryValue, 0 ) === 0 + ) { + if ( suggestedCacheEntry && suggestedCacheEntry.hidden ) { hiddenCategoryItems.push( suggestedCategory ); } else { matchingCategoryItems.push( suggestedCategory ); @@ -128,7 +135,7 @@ ve.ui.MWCategoryInputWidget.prototype.getLookupMenuItemsFromData = function ( da // New category if ( !exactMatch ) { newCategoryItems.push( canonicalQueryValue ); - linkCacheUpdate['Category:' + category.value] = { missing: true }; + linkCacheUpdate['Category:' + canonicalQueryValue] = { missing: true }; } ve.init.platform.linkCache.set( linkCacheUpdate ); diff --git a/modules/ve-mw/ui/widgets/ve.ui.MWCategoryWidget.js b/modules/ve-mw/ui/widgets/ve.ui.MWCategoryWidget.js index 151ede838a..f76bf0fbb3 100644 --- a/modules/ve-mw/ui/widgets/ve.ui.MWCategoryWidget.js +++ b/modules/ve-mw/ui/widgets/ve.ui.MWCategoryWidget.js @@ -28,7 +28,6 @@ ve.ui.MWCategoryWidget = function VeUiMWCategoryWidget( config ) { // Properties this.categories = {}; - this.categoryHiddenStatus = {}; this.categoryRedirects = {}; // Source -> target this.popupState = false; this.savedPopupState = false; @@ -193,7 +192,7 @@ ve.ui.MWCategoryWidget.prototype.getCategories = function () { }; /** - * Starts a request to update categoryHiddenStatus for the given titles. + * Starts a request to update the link cache's hidden status for the given titles. * The returned promise will be resolved with an API result if an API call was made, * or no arguments if it was unnecessary. * @@ -204,7 +203,8 @@ ve.ui.MWCategoryWidget.prototype.queryCategoryHiddenStatus = function ( category var categoryWidget = this, categoryNamesToQuery = []; // Get rid of any we already know the hidden status of. categoryNamesToQuery = $.grep( categoryNames, function ( categoryTitle ) { - return !Object.prototype.hasOwnProperty.call( categoryWidget.categoryHiddenStatus, categoryTitle ); + var cacheEntry = ve.init.platform.linkCache.getCached( categoryTitle ); + return !( cacheEntry && cacheEntry.hidden ); } ); if ( !categoryNamesToQuery.length ) { @@ -218,10 +218,13 @@ ve.ui.MWCategoryWidget.prototype.queryCategoryHiddenStatus = function ( category ppprop: 'hiddencat', redirects: '' } ).then( function ( result ) { + var linkCacheUpdate = {}; if ( result && result.query && result.query.pages ) { $.each( result.query.pages, function ( index, pageInfo ) { - var hiddenStatus = !!( pageInfo.pageprops && pageInfo.pageprops.hiddencat !== undefined ); - categoryWidget.categoryHiddenStatus[pageInfo.title] = hiddenStatus; + linkCacheUpdate[pageInfo.title] = { + missing: false, + hidden: Object.prototype.hasOwnProperty( pageInfo.pageprops, 'hiddencat' ) + }; } ); } if ( result && result.query && result.query.redirects ) { @@ -229,6 +232,7 @@ ve.ui.MWCategoryWidget.prototype.queryCategoryHiddenStatus = function ( category categoryWidget.categoryRedirects[redirectInfo.from] = redirectInfo.to; } ); } + ve.init.platform.linkCache.set( linkCacheUpdate ); } ); }; @@ -259,14 +263,14 @@ ve.ui.MWCategoryWidget.prototype.addItems = function ( items, index ) { config = { $: categoryWidget.$, item: item, - hidden: categoryWidget.categoryHiddenStatus[item.name] + hidden: ve.init.platform.linkCache.getCached( item.name ).hidden }; if ( Object.prototype.hasOwnProperty.call( categoryWidget.categoryRedirects, itemTitle ) ) { config.redirectTo = new mw.Title( categoryWidget.categoryRedirects[itemTitle], mw.config.get( 'wgNamespaceIds' ).category ).getMainText(); - config.hidden = categoryWidget.categoryHiddenStatus[categoryWidget.categoryRedirects[itemTitle]]; + config.hidden = ve.init.platform.linkCache.getCached( categoryWidget.categoryRedirects[itemTitle] ).hidden; } categoryItem = new ve.ui.MWCategoryItemWidget( config ); categoryItem.connect( categoryWidget, {