mediawiki-extensions-Popups/resources/ext.popups/processLinks.js
Sam Smith 0d300867ab Make API request after 500 ms
If the user has abandoned the link or dwelled on a different link, then
don't make the API request.

Changes:
* Fix a bug in the linkDwell reducer where the activeLink was always
  being set to undefined.
* Add the private fetch action creator.
* Make the linkDwell action dispatch the result of the fetch action
  creator after 500ms.

Supporting changes:
* Make the link* action creators take DOM elements rather than jQuery
  instances so that:
  1. Testing whether the state tree has changed is an identity
     comparison.
  2. jQuery instances are constructed only when required.
* Document the ext.popups.Gateway type.
* Document the Redux.Store type.
* Rename the "previews-page-title" data attribute to
  "page-previews-title" to avoid confusion.

Change-Id: I0b1cf3337a6f8d6450ad2bd127cb292ebb73af4f
2016-11-17 13:20:11 +00:00

94 lines
2.5 KiB
JavaScript

( function ( mw, $ ) {
/**
* @private
*
* Gets the title of a local page from an href given some configuration.
*
* @param {String} href
* @param {mw.Map} config
* @return {String|undefined}
*/
function getTitle( href, config ) {
var linkHref,
matches,
queryLength,
titleRegex = new RegExp( mw.RegExp.escape( config.get( 'wgArticlePath' ) )
.replace( '\\$1', '(.+)' ) );
// Skip every URI that mw.Uri cannot parse
try {
linkHref = new mw.Uri( href );
} catch ( e ) {
return undefined;
}
// External links
if ( linkHref.host !== location.hostname ) {
return undefined;
}
queryLength = Object.keys( linkHref.query ).length;
// No query params (pretty URL)
if ( !queryLength ) {
matches = titleRegex.exec( linkHref.path );
return matches ? decodeURIComponent( matches[ 1 ] ) : undefined;
} else if ( queryLength === 1 && linkHref.query.hasOwnProperty( 'title' ) ) {
// URL is not pretty, but only has a `title` parameter
return linkHref.query.title;
}
return undefined;
}
/**
* Processes and returns link elements (or "`<a>`s") that are eligible for
* previews in a given container.
*
* An `<a>` is eligible for a preview if:
*
* * It has an href and a title, i.e. `<a href="/wiki/Foo" title="Foo" />`.
* * It doesn't have any blacklisted CSS classes.
* * Its href is a valid URI of a page on the local wiki.
*
* If an `<a>` is eligible, then the title of the page on the local wiki is
* stored in the `data-previews-page-title` attribute for later reuse.
*
* @param {jQuery} $container
* @param {String[]} blacklist If an `<a>` has one or more of these CSS
* classes, then it will be ignored.
* @param {mw.Map} [config] defaults to the value of mediaWiki.config
*
* @return {jQuery}
*/
mw.popups.processLinks = function ( $container, blacklist, config ) {
var contentNamespaces;
if ( typeof config === 'undefined' ) {
config = mw.config;
}
contentNamespaces = config.get( 'wgContentNamespaces' );
return $container
.find( 'a[href][title]:not(' + blacklist.join( ', ' ) + ')' )
.filter( function () {
var title,
titleText = getTitle( this.href, config );
if ( !titleText ) {
return false;
}
// Is titleText in a content namespace?
title = mw.Title.newFromText( titleText );
if ( title && ( $.inArray( title.namespace, contentNamespaces ) >= 0 ) ) {
$( this ).data( 'page-previews-title', titleText );
return true;
}
} );
};
}( mediaWiki, jQuery ) );