mediawiki-extensions-Visual.../modules/ve-mw/init/ve.init.mw.LinkCache.js
James D. Forrester 8463524e18 MWSaveDialog: Run links through a render function for preview & visual diff
Provide a utility funcition in ve.init.mw.LinkCache to do this.

Also use this in ve.ce.MWTransclusionNode/ve.ui.MWPreviewElement, and
introduce to ve.ce.MWExtenionNode

Bug: T73900
Bug: T153535
Change-Id: Ieb9a0274b8c5ae1932c431546f09d18000fa6dd9
2017-03-31 10:51:35 +01:00

195 lines
5.4 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-2017 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
*/
ve.init.mw.LinkCache = function VeInitMwLinkCache() {
ve.init.mw.LinkCache.super.call( this );
// 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,
imageUrl: ve.getProp( page, 'thumbnail', 'source' ),
description: ve.getProp( page, 'terms', '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
*/
ve.init.mw.LinkCache.prototype.styleElement = function ( title, $element ) {
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 ( 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.
*
* @chainable
* @param {jQuery} $element Elements to style
* @param {HTMLDocument} doc Base document to use for normalisation
* @return {jQuery} The elements, now styled
*/
ve.init.mw.LinkCache.prototype.styleParsoidElements = function ( $elements, doc ) {
// 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 = ve.init.platform.linkCache.constructor.static.normalizeTitle(
ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref( href, doc ).title
);
ve.init.platform.linkCache.styleElement( title, $( this ) );
} );
}
return $elements;
};
/**
* 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 new mw.Api().get( {
action: 'query',
prop: 'info|pageprops|pageimages|pageterms',
pithumbsize: 80,
pilimit: subqueue.length,
wbptterms: 'description',
ppprop: 'disambiguation',
titles: subqueue,
'continue': ''
} );
};