mediawiki-extensions-Visual.../modules/ve-mw/init/ve.init.mw.LinkCache.js
David Lynch 5d19272aa1 ArticleTarget: Change rendering of category preview
Just generate the standard wiki skin markup for categories. Adjust linkcache to always know
whether links are hidden categories. (It previously knew *sometimes*,
depending on whether a MWCategoryWidget had interacted with that category.)

Make the save dialog preview use the same method as the bottom-of-editor preview.

Bug: T194092
Change-Id: I37fea15eaef0a5847f27ce41dd92370a4bf353b6
2018-05-13 16:40:59 -05:00

200 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* VisualEditor MediaWiki Initialization LinkCache class.
*
* @copyright 2011-2018 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Caches information about titles.
*
* @class
* @extends ve.init.mw.ApiResponseCache
* @constructor
* @param {mw.Api} [api]
*/
ve.init.mw.LinkCache = function VeInitMwLinkCache() {
// Parent constructor
ve.init.mw.LinkCache.super.apply( this, arguments );
// Keys are page names, values are link data objects
// This is kept for synchronous retrieval of cached values via #getCached
this.cacheValues = {};
};
/* Inheritance */
OO.inheritClass( ve.init.mw.LinkCache, ve.init.mw.ApiResponseCache );
/* Static methods */
/**
* Get the icon name to use for a particular link type
*
* @param {Object} linkData Link data
* @return {string} Icon name
*/
ve.init.mw.LinkCache.static.getIconForLink = function ( linkData ) {
if ( linkData.missing ) {
return 'page-not-found';
}
if ( linkData.redirect ) {
return 'page-redirect';
}
if ( linkData.disambiguation ) {
return 'page-disambiguation';
}
return 'page-existing';
};
/**
* @inheritdoc
*/
ve.init.mw.LinkCache.static.processPage = function ( page ) {
return {
missing: page.missing !== undefined,
known: page.known !== undefined,
redirect: page.redirect !== undefined,
disambiguation: ve.getProp( page, 'pageprops', 'disambiguation' ) !== undefined,
hidden: ve.getProp( page, 'pageprops', 'hiddencat' ) !== undefined,
imageUrl: ve.getProp( page, 'thumbnail', 'source' ),
description: page.description
};
};
/* Methods */
/**
* Requests information about the title, then adds classes to the provided element as appropriate.
*
* @param {string} title
* @param {jQuery} $element Element to style
* @param {boolean} hasFragment Whether the link goes to a fragment
*/
ve.init.mw.LinkCache.prototype.styleElement = function ( title, $element, hasFragment ) {
var promise,
cache = this,
cachedMissingData = this.getCached( '_missing/' + title );
// Use the synchronous missing link cache data if it exists
if ( cachedMissingData ) {
promise = $.Deferred().resolve( cachedMissingData ).promise();
} else {
promise = this.get( title );
}
promise.done( function ( data ) {
if ( data.missing && !data.known ) {
$element.addClass( 'new' );
} else {
// Provided by core MediaWiki, styled like a <strong> element by default.
if ( !hasFragment && cache.constructor.static.normalizeTitle( title ) === cache.constructor.static.normalizeTitle( mw.config.get( 'wgRelevantPageName' ) ) ) {
$element.addClass( 'mw-selflink' );
}
// Provided by core MediaWiki, no styles by default.
if ( data.redirect ) {
$element.addClass( 'mw-redirect' );
}
// Provided by the Disambiguator extension, no styles by default.
if ( data.disambiguation ) {
$element.addClass( 'mw-disambig' );
}
}
} );
};
/**
* Given a chunk of Parsoid HTML, requests information about each link's title, then adds classes
* to each such element as appropriate.
*
* TODO: Most/all of this code should be done upstream, either by Parsoid itself or by an
* intermediary service see T64803 and others.
*
* @param {jQuery} $element Elements to style
* @param {HTMLDocument} doc Base document to use for normalisation
*/
ve.init.mw.LinkCache.prototype.styleParsoidElements = function ( $elements, doc ) {
var cache = this;
if ( ve.dm.MWLanguageVariantNode ) {
// Render the user's preferred variant in language converter markup
ve.dm.MWLanguageVariantNode.static.processVariants( $elements );
}
// TODO: Remove when fixed upstream in Parsoid (T58756)
$elements
.find( 'a[rel~="mw:ExtLink"]' ).addBack( 'a[rel~="mw:ExtLink"]' )
.addClass( 'external' );
// TODO: Remove when moved upstream into Parsoid or another service (T64803)
// If the element isn't attached, doc will be null, so we don't know how to normalise titles
if ( doc ) {
$elements
.find( 'a[rel~="mw:WikiLink"]' ).addBack( 'a[rel~="mw:WikiLink"]' )
.each( function () {
var title,
href = this.href || mw.config.get( 'wgArticlePath' );
title = cache.constructor.static.normalizeTitle(
ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref( href, doc ).title
);
cache.styleElement( title, $( this ), href.indexOf( '#' ) !== -1 );
} );
}
};
/**
* Enable or disable automatic assumption of existence.
*
* While enabled, any get() for a title that's not already in the cache will return
* { missing: false } and write that to the cache.
*
* @param {boolean} assume Assume all uncached titles exist
*/
ve.init.mw.LinkCache.prototype.setAssumeExistence = function ( assume ) {
this.assumeExistence = !!assume;
};
/**
* Set link missing data
*
* Stored separately from the full link data cache
*
* @param {Object} entries Object keyed by page title, with the values being data objects
*/
ve.init.mw.LinkCache.prototype.setMissing = function ( entries ) {
var name, missingEntries = {};
for ( name in entries ) {
missingEntries[ '_missing/' + name ] = entries[ name ];
}
this.set( missingEntries );
};
/**
* @inheritdoc
*/
ve.init.mw.LinkCache.prototype.get = function ( title ) {
var data = {};
if ( this.assumeExistence ) {
data[ this.constructor.static.normalizeTitle( title ) ] = { missing: false };
this.setMissing( data );
}
// Parent method
return ve.init.mw.LinkCache.super.prototype.get.call( this, title );
};
/**
* @inheritdoc
*/
ve.init.mw.LinkCache.prototype.getRequestPromise = function ( subqueue ) {
return this.api.get( {
action: 'query',
prop: 'info|pageprops|pageimages|description',
pithumbsize: 80,
pilimit: subqueue.length,
ppprop: 'disambiguation|hiddencat',
titles: subqueue,
'continue': ''
} );
};