MediaWiki:Gadget-AuthorityControl.js: Difference between revisions

From Wikidata
Jump to navigation Jump to search
Content deleted Content added
Fomafix (talk | contribs)
$( ... ).find( ... ) is already a jQuery object. Use $ in the name of the variable to indicate this.
Ricordisamoa (talk | contribs)
Line 168: Line 168:
for ( claim in entity.claims ) {
for ( claim in entity.claims ) {
claims.push( claim );
claims.push( claim );
$.each( entity.claims[claim], function ( i, cl ) {
$.each( cl.references || [], function ( i, ref ) {
for ( claim in ref.snaks ) {
if ( $.inArray( claim, claims ) === -1 ) {
claims.push( claim );
}
}
} );
for ( claim in cl.qualifiers || {} ) {
if ( $.inArray( claim, claims ) === -1 ) {
claims.push( claim );
}
}
} );
}
}
if ( !claims.length ) {
if ( !claims.length ) {

Revision as of 14:38, 23 August 2015

/* AuthorityControl.js
 * Provides a link to various Authority Control tools (VIAF, GND, etc.) for Wikidata statements that
 * feature certain properties.
 *
 * Original gadget coded by [[User:Ricordisamoa]]
 */
( function ( mw, wb, $ ) {

if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 || !mw.config.exists( 'wbEntityId' ) ) {
	// Only item pages feature appropriate statements.
	return;
}

var PROPERTIES = {};

/*
*/
function getGeoHackParams( coord ) {
	// TODO: individual scale for every precision

	var globes = {
		'Q2': 'earth',
		'Q111': 'mars',
		'Q308': 'mercury',
		'Q313': 'venus',
		'Q405': 'moon',
		'Q15034': 'mimas'
	};

	/* BUG: .getGlobe() returns Q2 always */
	var globeQKey = coord.globe.replace( 'http://www.wikidata.org/entity/', '' );
	var globe = globes[globeQKey];

	return coord.latitude + '_N_' + coord.longitude + '_E_globe:' + globe;
}

/**
 * Get the snak value formatted with a link.
 *
 * @param {number} numericPropertyId Refers to PROPERTIES.
 * @param {string} value
 */
function getLinkValueForString( numericPropertyId, value ) {
	var linkValue;

	switch ( Number( numericPropertyId ) ) {
	case 213: // ISNI
		linkValue = value.replace( / /g, '' );
		break;
	case 502: // HURDAT
		linkValue = value.substring( 4, 8 ); // year
		if ( Number( linkValue ) <= 2005 ) {
			linkValue += '/'; // Brings a list for that year
			// For direct link, would need to append <name of hurricane>.[s]htlm
			// ex: http://www.nhc.noaa.gov/archive/2004/ALEX.shtml or 2001/ALLISON.html
		} else { // after 2005
			linkValue += '/' + value.substring( 0, 4 ).toLowerCase() + '/';
		}
		break;
	case 628: // E Number
		linkValue = value.substring( 1, 16 ); // Skip initial letter
		break;
	case 882: // FIPS
		linkValue = value;
		linkValue = linkValue.substr( 0, 2 ) + '/' + linkValue;
		break;
	default:
		linkValue = value;
	}

	return linkValue;
}

function createLinkForString( numericPropertyId, value ) {
	var linkValue = getLinkValueForString( numericPropertyId, value );
	return makeLink( numericPropertyId, linkValue, value );
}

function createLinkForSnakValue( numericPropertyId, datavalue, displayText ) {
	var dataValueType = datavalue.type,
		value = datavalue.value;

	// @fixme shouldn't happen but in case of any unexpected data value types,
	// then there should be better error handling here.
	var linkValue = '';

	if ( dataValueType === 'string' ) {
		linkValue = getLinkValueForString( numericPropertyId, value );
	}
	else if ( dataValueType === 'globecoordinate' ) {
		linkValue = getGeoHackParams( value );
	}

	return makeLink( numericPropertyId, linkValue, displayText );
}

function makeLink( numericPropertyId, linkValue, displayText ) {
	var linkTemplate = PROPERTIES[numericPropertyId];

	return $( '<a>' )
		.text( displayText )
		.attr( 'href', linkTemplate.replace( '$1', linkValue ) )
		// Show the 'external link' icon:
		.addClass( 'external' );
}

function linkSnakView( el, propertySelector, valueSelector ) {
	var $propLink = $( el ).find( propertySelector );

	var title = $propLink.attr( 'title' );

	if ( title ) {
		var titleParts = title.split( ':P' ),
			numericPropertyId = titleParts[1];

		if ( PROPERTIES.hasOwnProperty( numericPropertyId ) ) {
			var $value = $( el ).find( valueSelector ).first(),
				$link = createLinkForString( numericPropertyId, $value.text() );

			$value.html( $link );
		}
	}
}

/**
 * Initializes the gadget.
 * This procedure needs to be performed as good as possible. jQuery selector usage should be limited
 * to a minimum.
 */
function initGadget() {
	$( ':wikibase-statementview' ).each( function () {
		var statementview = $.data( this, 'statementview' ),
			statement = statementview.value(),
			mainSnak = statement.getClaim().getMainSnak(),
			numericPropertyId = mainSnak.getPropertyId().slice( 1 ),
			snakview = statementview.$mainSnak.data( 'snakview' ),
			datavalue = snakview.value().datavalue;

			if ( datavalue && PROPERTIES.hasOwnProperty( numericPropertyId ) ) {
				var displayText = snakview.$snakValue.text(),
					snakLink = createLinkForSnakValue( numericPropertyId, datavalue, displayText );

				snakview.$snakValue.html( snakLink );
			}
	} );

/*
	@fixme this works for main snak, except for coordinates which need the data value
	$( '.wikibase-statementgroupview' ).each( function () {
		linkSnakView( this, '.wikibase-statementgroupview-property-label > a', '.wikibase-snakview-value' );
	} );
*/
	$( '.wikibase-statementview-qualifiers' ).each( function () {
		linkSnakView( this, '.wikibase-snakview-property > a', '.wikibase-snakview-value' );
	} );

	$( '.wikibase-referenceview' ).each( function () {
		linkSnakView( this, '.wikibase-snakview-property > a', '.wikibase-snakview-value' );
	} );
}

function getProperties() {
	var api = new mw.Api(),
		repoApi = new wb.api.RepoApi( api ),
		claim,
		claims = [],
		entity = JSON.parse( mw.config.get( 'wbEntity' ) );
	for ( claim in entity.claims ) {
		claims.push( claim );
		$.each( entity.claims[claim], function ( i, cl ) {
			$.each( cl.references || [], function ( i, ref ) {
				for ( claim in ref.snaks ) {
					if ( $.inArray( claim, claims ) === -1 ) {
						claims.push( claim );
					}
				}
			} );
			for ( claim in cl.qualifiers || {} ) {
				if ( $.inArray( claim, claims ) === -1 ) {
					claims.push( claim );
				}
			}
		} );
	}
	if ( !claims.length ) {
		return $.Deferred().resolve();
	}
	return repoApi.getEntities( claims, 'claims' )
	.done( function ( data ) {
		$.each( data.entities, function ( entityId, entity ) {
			if ( entity.claims ) {
				$.each( entity.claims, function ( claimId, claim ) {
					if ( claimId === 'P1630' ) {
						PROPERTIES[entityId.slice( 1 )] = claim[0].mainsnak.datavalue.value;
					}
				} );
			}
		} );
	} );
}

getProperties().done( function () {
	$( initGadget );
} );

}( mediaWiki, wikibase, jQuery ) );