Page MenuHomePhabricator
Paste P2797

Faster authority control
ActivePublic

Authored by hoo on Mar 21 2016, 12:31 PM.
Referenced Files
F3843938: Faster authority control
Apr 7 2016, 2:28 PM
F3843864: Faster authority control
Apr 7 2016, 2:20 PM
F3685295: Faster authority control
Mar 21 2016, 2:29 PM
F3684810: Faster authority control
Mar 21 2016, 12:31 PM
Subscribers
/* 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, $ ) {
'use strict';
if ( ( mw.config.get( 'wgNamespaceNumber' ) !== 0 && mw.config.get( 'wgNamespaceNumber' ) !== 120 ) || !mw.config.exists( 'wbEntityId' ) ) {
// Only item pages feature appropriate statements.
return;
}
var PROPERTIES = {},
specialHandlingProperties = [
'P213', // ISNI
'P345', // IMDb
'P426', // aircraft registration
'P502', // HURDAT
'P628', // E Number
'P882', // FIPS
'P1323', // TA98
'P2698' // CricketArchive
];
/*
*/
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 345: // IMDb
linkValue = '/' + value;
switch ( value.substring( 0, 2 ) ) {
case 'nm':
linkValue = 'name' + linkValue + '/';
break;
case 'tt':
linkValue = 'title' + linkValue + '/';
break;
case 'ch':
linkValue = 'character' + linkValue + '/';
break;
case 'ev':
linkValue = 'event' + linkValue;
break;
case 'co':
linkValue = 'company' + linkValue + '/';
break;
}
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;
case 1323: // TA98
linkValue = value.substring( 1, 16 ); // Skip initial letter
break;
case 2698: // CricketArchive
if ( isNaN( value ) ) {
break;
}
var trunc = (Number(value)/1000).toFixed(0);
linkValue = trunc + '/' + value + '/' + value;
break;
default:
linkValue = value;
}
return linkValue;
}
function makeLink( numericPropertyId, linkValue, displayText ) {
var linkTemplate = PROPERTIES[ numericPropertyId ];
switch ( Number( numericPropertyId ) ) {
case 426:
if ( linkValue.substring( 0, 1 ) === 'N' ) {
linkTemplate = 'http://registry.faa.gov/aircraftinquiry/NNum_Results.aspx?NNumbertxt=$1';
} else if ( linkValue.substring( 0, 2 ) === 'G-' ) {
linkTemplate = 'https://www.caa.co.uk/application.aspx?catid=60&pagetype=65&appid=1&mode=detailnosummary&fullregmark=$1';
linkValue = linkValue.substring( 2 );
} else {
return linkValue;
}
break;
case 791:
if ( linkValue.substring( 0, 3 ) === 'DE-' ) {
linkTemplate = 'http://dispatch.opac.d-nb.de/DB=1.2/CMD?ACT=SRCHA&IKT=8529&TRM=$1';
} else {
return linkValue;
}
break;
case 2698:
linkTemplate = 'http://www.cricketarchive.com/Archive/Players/$1.html';
break;
default:
linkTemplate = PROPERTIES[ numericPropertyId ];
}
return $( '<a>' )
.text( displayText )
.attr( 'href', linkTemplate.replace( /\$1/g, linkValue ) )
// Show the 'external link' icon:
.addClass( 'external' );
}
function createLinkForString( numericPropertyId, value ) {
var linkValue = getLinkValueForString( numericPropertyId, value );
return makeLink( numericPropertyId, linkValue, value );
}
function createLinkForSnakValue( numericPropertyId, dataValue, displayText ) {
var dataValueType = dataValue.getType(),
value = dataValue.toJSON();
// @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 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 );
}
}
}
function handleSnak( snak, snakView ) {
if ( !( snak instanceof wikibase.datamodel.PropertyValueSnak ) ) {
return;
}
var numericPropertyId = snak.getPropertyId().slice( 1 );
if ( !( PROPERTIES.hasOwnProperty( numericPropertyId ) ) ) {
return;
}
var $snakValue = $( snakView ).find( '.wikibase-snakview-value' ),
displayText = $snakValue.text(),
snakLink = createLinkForSnakValue( numericPropertyId, snak.getValue(), displayText );
$snakValue.html( snakLink );
}
/**
* Initializes the gadget.
* This procedure needs to be performed as good as possible. jQuery selector usage should be limited
* to a minimum.
*/
function initGadget() {
if ( $.isEmptyObject( PROPERTIES ) ) {
return;
}
$( ':wikibase-statementview' ).each( function () {
var statementview = $.data( this, 'statementview' ),
statement = statementview.value(),
claim = statement.getClaim(),
qualifierGroups = claim.getQualifiers().getGroupedSnakLists();
handleSnak( claim.getMainSnak(), statementview.$mainSnak[0] );
$( '.wikibase-statementview-qualifiers .wikibase-snaklistview', this ).each( function( i ) {
var qualifiers = qualifierGroups[i].toArray();
$( '.wikibase-snakview', this ).each( function( n ) {
handleSnak( qualifiers[n], this );
} );
} );
} );
$( '.wikibase-referenceview .wikibase-snaklistview-listview' ).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,
propertyIds = [],
alreadyLinkedPropertyIds = [],
entity = JSON.parse( mw.config.get( 'wbEntity' ) );
function addSnak( snak ) {
var snakPropertyId = snak.property;
if ( snak.snaktype !== 'value' ||
( snak.datavalue.type !== 'string' && snak.datavalue.type !== 'globecoordinate' ) ) {
return;
}
if ( propertyIds.hasOwnProperty( snakPropertyId ) ) {
return;
}
if ( !specialHandlingProperties.hasOwnProperty( snakPropertyId ) ) {
if ( alreadyLinkedPropertyIds.hasOwnProperty( snakPropertyId ) ) {
return;
}
if ( $( '#' + snakPropertyId ).find( '.wikibase-snakview-variation-valuesnak:first > a' ).length > 0 ) {
alreadyLinkedPropertyIds.push( snakPropertyId );
return;
}
}
propertyIds.push( snakPropertyId );
}
for ( claim in entity.claims ) {
$.each( entity.claims[ claim ], function ( i, cl ) {
addSnak( cl.mainsnak );
$.each( cl.references || [], function ( i, ref ) {
for ( claim in ref.snaks ) {
addSnak( ref.snaks[ claim ] );
}
} );
for ( claim in cl.qualifiers || {} ) {
addSnak( cl.qualifiers[ claim ] );
}
} );
}
if ( !propertyIds.length ) {
return $.Deferred().resolve();
}
return repoApi.getEntities( propertyIds, 'claims' )
.done( function ( data ) {
$.each( data.entities, function ( entityId, entity ) {
if ( entity.datatype === "external-id" && $.inArray( entity.id, specialHandlingProperties ) === -1 ) {
// No need to format these
return true;
}
$.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 ) );