/**
* This script is a hack to make popups on items work.
*
* @author [[User:Bene*]]
*/
( function( $, mw ) {
'use strict';
/**
* Property which is used to find the thumbnail of an item.
*/
var imageProperty = 'P18';
// dont enable popups for all users, only add it when it is already loaded
var state = mw.loader.getState( 'ext.popups.desktop' );
if ( !state || !state.match( /loading|loaded|ready/ ) ) {
return;
}
mw.loader.using( [ 'ext.popups.desktop' ], function() {
var newLineIdentifier = '[br-' + Math.random() + ']',
beforeIdIdentifier = '[before-id-' + Math.random() + ']',
afterIdIdentifier = '[after-id-' + Math.random() + ']';
/**
* Creates a Wikidata specific popup.
*
* @param {jQuery.Promise} deferred
* @param {string} title
* @param {string} href
*/
function popupWikidata( deferred, title, href ) {
var id = title.replace( 'Property:', '' ),
lang = mw.config.get( 'wgUserLanguage' );
// first request to get the entity's labels, descriptions and claims
mw.popups.render.currentRequest = mw.popups.api.get( {
action: 'wbgetentities',
props: 'labels|descriptions|claims',
redirects: 'yes',
languages: lang,
languagefallback: true,
ids: id
} );
mw.popups.render.currentRequest.fail( deferred.reject );
mw.popups.render.currentRequest.done( function ( re ) {
mw.popups.render.currentRequest = undefined;
if (
!re.success ||
!re.entities ||
!re.entities[id] ||
!re.entities[id].labels ||
!re.entities[id].labels[lang] ||
!re.entities[id].descriptions ||
!re.entities[id].descriptions[lang]
) {
deferred.reject();
return;
}
var entity = re.entities[id];
// hack: fake request because of bad api design
var fakedRe = {
extract: entity.labels[lang].value + beforeIdIdentifier + id + afterIdIdentifier +
newLineIdentifier + entity.descriptions[lang].value,
title: entity.labels[lang].value
};
var file = '';
if ( entity.claims && entity.claims[imageProperty] ) {
file = '|File:' + entity.claims[imageProperty][0].mainsnak.datavalue.value;
}
// second request to get the revision of the entity and the thumbnail if an image was found
mw.popups.render.currentRequest = mw.popups.api.get( {
action: 'query',
prop: 'imageinfo|revisions',
iiprop: 'url|size',
iilimit: 1,
iiurlwidth: 300 * $.bracketedDevicePixelRatio(), // scaledThumbSize
rvprop: 'timestamp',
rvlimit: 1,
titles: title + file
} );
mw.popups.render.currentRequest.fail( deferred.reject );
mw.popups.render.currentRequest.done( function ( re ) {
mw.popups.render.currentRequest = undefined;
if (
!re.query ||
!re.query.pages
) {
deferred.reject();
return;
}
var pageId;
for ( var i in re.query.pages ) {
if ( i > 0 ) {
pageId = i;
}
}
fakedRe.revisions = re.query.pages[pageId].revisions;
if ( re.query.pages[-1] && re.query.pages[-1].imageinfo ) {
fakedRe.thumbnail = {
source: re.query.pages[-1].imageinfo[0].thumburl,
width: re.query.pages[-1].imageinfo[0].thumbwidth,
height: re.query.pages[-1].imageinfo[0].thumbheight
};
}
mw.popups.render.cache[ href ] = {};
mw.popups.render.cache[ href ].popup = mw.popups.render.renderers.article.createPopup( fakedRe, href );
mw.popups.render.cache[ href ].getOffset = mw.popups.render.renderers.article.getOffset;
mw.popups.render.cache[ href ].getClasses = mw.popups.render.renderers.article.getClasses;
mw.popups.render.cache[ href ].process = mw.popups.render.renderers.article.processPopup;
deferred.resolve();
} );
} );
}
/**
* Code stolen from the popup extension itself to create the default popup.
*
* @param {jQuery.Promise} deferred
* @param {string} title
* @param {string} href
*/
function popupDefault( deferred, title, href ) {
mw.popups.render.currentRequest = mw.popups.api.get( {
action: 'query',
prop: 'extracts|pageimages|revisions',
formatversion: 2,
redirects: true,
exintro: true,
exsentences: 2,
// there is an added geometric limit on .mwe-popups-extract
// so that text does not overflow from the card
explaintext: true,
piprop: 'thumbnail',
pithumbsize: 300 * $.bracketedDevicePixelRatio(), // scaledThumbSize
rvprop: 'timestamp',
titles: title,
smaxage: 300,
maxage: 300,
uselang: 'content'
} );
mw.popups.render.currentRequest.fail( deferred.reject );
mw.popups.render.currentRequest.done( function ( re ) {
mw.popups.render.currentRequest = undefined;
if (
!re.query ||
!re.query.pages ||
!re.query.pages[0].extract ||
re.query.pages[0].extract === ''
) {
// Restore the title attribute and set flag
if ( link.data( 'dont-empty-title' ) !== true ) {
link
.attr( 'title', link.data( 'title' ) )
.removeData( 'title' )
.data( 'dont-empty-title', true );
}
deferred.reject();
return;
}
mw.popups.render.cache[ href ] = {};
mw.popups.render.cache[ href ].popup = mw.popups.render.renderers.article.createPopup( re.query.pages[0], href );
mw.popups.render.cache[ href ].getOffset = mw.popups.render.renderers.article.getOffset;
mw.popups.render.cache[ href ].getClasses = mw.popups.render.renderers.article.getClasses;
mw.popups.render.cache[ href ].process = mw.popups.render.renderers.article.processPopup;
deferred.resolve();
} );
}
/**
* Send an API request and cache the jQuery element
*
* @param {jQuery} link
* @return {jQuery.Promise}
*/
mw.popups.render.renderers.article.init = function ( link ) {
var href = link.attr( 'href' ),
title = mw.popups.getTitle( href ),
deferred = $.Deferred();
if ( !title ) {
return deferred.reject().promise();
}
if ( title.match( /^Q[0-9]+/ ) || title.match( /^Property:P[0-9]+/ ) ) {
popupWikidata( deferred, title, href );
} else {
popupDefault( deferred, title, href );
}
return deferred.promise();
};
var getProcessedElements = mw.popups.render.renderers.article.getProcessedElements;
mw.popups.render.renderers.article.getProcessedElements = function( extract, title ) {
var elements = getProcessedElements.apply( this, [ extract, title ] );
var html = $( '<span>' ).append( elements ).html()
.replace( newLineIdentifier, '</p><p>' )
.replace( beforeIdIdentifier, ' <small>(' )
.replace( afterIdIdentifier, ')</small>');
return '<p>' + html + '</p>';
};
mw.hook( 'wikipage.content').add( function( $content ) {
var $elements = $content.find( 'a[href^="/wiki/Property:"]' );
mw.popups.removeTooltip( $elements );
mw.popups.setupTriggers( $elements );
} );
} );
} )( jQuery, mediaWiki );