MediaWiki:Gadget-wikidataInfoboxExport.js
Zur Navigation springen
Zur Suche springen
Hinweis: Leere nach dem Speichern den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Internet Explorer: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
- Opera: Gehe zu Menü → Einstellungen (Opera → Einstellungen auf dem Mac) und dann auf Datenschutz & Sicherheit → Browserdaten löschen → Gespeicherte Bilder und Dateien.
/**
* Быстрый экспорт информации из карточек в Викиданные.
* Вызов окна экспорта по двойному клику.
*/
( function ( mw, $ ) {
var wdeConfig = {
version: '1.14.3',
languages: [ 'en' ],
references: {
// взято из = русская Википедия
P143: [ {
snaktype: 'value',
property: 'P143',
datavalue: {
type: 'wikibase-entityid',
value: { id: 'Q206855' }
}
} ]
},
units: {
Q531: { search: [ 'св(?:\\.|етовых)\\s*(?:лет|года?)' ] },
Q4916: { search: [ '^€', '^EUR' ] },
Q4917: { search: [ '^(?:-|US)?\\$', 'долларов(?:\\sСША)?', 'долл.' ] },
Q7727: { search: [ 'минут' ] },
Q8146: { search: [ 'иен' ] },
Q11573: { search: [ 'метр(?:а|ов)' ] },
Q25344: { search: [ '^CHF' ] },
Q41044: { search: [ 'рублей' ] },
Q81292: { search: [ 'акр(?:а|ов)' ] }
},
reCirca: '(?:~|ок(?:оло)?|прим(?:ерно)?)\\.?'
};
var api;
var wdApi;
var wdeBaseRevId;
var wdePropertyIds = [ 'P2076', 'P2077' ]; // температура и давление для квалификаторов
var wdeTypesMapping = {
'commonsMedia': 'string',
'external-id': 'string',
'url': 'string',
'wikibase-item': 'wikibase-entityid'
};
var wdeAlreadyExistingItems = {};
var wdeWindowManager;
var centuries = [ 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII',
'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV',
'XVI', 'XVII', 'XVIII', 'XIX', 'XX', 'XXI', 'XXII' ];
/**
* Сравнивает значение из карточки и в Викиданных
*/
var wdeCanExportValue = function ( $field, claims, callbackIfCan ) {
if ( !claims || !( claims.length ) ) {
// не можем экспортировать только если это крупное изображение из ru-wiki
if ( !( $field.find( '.image img[src*="/wikipedia/' + wdeConfig.language + '/"]' ).width() >= 80 ) ) {
callbackIfCan();
}
return;
}
switch ( claims[ 0 ].mainsnak.datatype ) {
case 'quantity':
for ( var i = 0; i < claims.length; i++ ) {
var parsedTime = wdeCreateTimeSnak( ( $field.text().match( /\(([^)]*\d\d\d\d)[,)\s]/ ) || [] )[ 1 ] );
if ( parsedTime && ( claims[ i ].qualifiers || {} ).P585 ) {
var claimPrecision = claims[ i ].qualifiers.P585[ 0 ].datavalue.value.precision;
if ( parsedTime.precision < claimPrecision ) {
claims[ i ].qualifiers.P585[ 0 ].datavalue.value.precision = parsedTime.precision;
} else if ( parsedTime.precision > claimPrecision ) { // FIXME: потом уточнить в wd дату
parsedTime.precision = claimPrecision;
}
var p585 = parsedTime ? wdeFormatDataValue( {
type: 'time',
value: parsedTime
} )[ 0 ].innerText : '';
if ( wdeFormatDataValue( claims[ i ].qualifiers.P585[ 0 ].datavalue )[ 0 ].innerText !== p585 ) {
claims[ i ].qualifiers.P585[ 0 ].datavalue.value.precision = claimPrecision;
continue;
}
}
return;
}
callbackIfCan();
break;
case 'wikibase-item':
value = wdeParseItems( $field, function ( values ) {
var duplicates = [];
for ( var i = 0; i < values.length; i++ ) {
for ( var j = 0; j < claims.length; j++ ) {
if ( values[ i ].wd.value.id === claims[ j ].mainsnak.datavalue.value.id ) {
duplicates.push( values[ i ].wd.value.id );
}
}
}
if ( duplicates.length < values.length ) {
if ( duplicates.length > 0 ) {
var propertyId = claims[ 0 ].mainsnak.property;
wdeAlreadyExistingItems[ propertyId ] = duplicates;
if ( propertyId === 'P166' && values.length === claims.length )
return;
}
if ( claims.length > 0 ) {
if ( claims[ 0 ].mainsnak.property === 'P19' || claims[ 0 ].mainsnak.property === 'P20' )
return;
}
callbackIfCan();
}
} );
}
// По умолчанию, если есть claims, то экспортировать нельзя
};
/**
* Генерация ID утверждения
*/
var wdeClaimGuid = function ( entityId ) {
var getRandomHex = function ( min, max ) {
return ( Math.floor( Math.random() * ( max - min + 1 ) ) + min ).toString( 16 );
};
var template = 'xx-x-x-x-xxx';
var guid = '';
for ( var i = 0; i < template.length; i++ ) {
if ( template.charAt( i ) === '-' ) {
guid += '-';
continue;
}
var hex;
if ( i === 3 ) {
hex = getRandomHex( 16384, 20479 );
} else if ( i === 4 ) {
hex = getRandomHex( 32768, 49151 );
} else {
hex = getRandomHex( 0, 65535 );
}
while ( hex.length < 4 ) {
hex = '0' + hex;
}
guid += hex;
}
return entityId + '$' + guid;
};
/**
* Форматирование дат в datavalue для викиданных
*/
var wdeCreateTimeSnak = function ( timestamp, forceJulian ) {
if ( !timestamp ) {
return;
}
var months = [ 'январь', 'февраль', 'март', 'апрель', 'май', 'июнь',
'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь' ];
var monthsGen = [ 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' ];
var result = { timezone: 0, before: 0, after: 0 };
var isoDate;
var dateParts;
if ( dateParts = timestamp.match( /^([ivx]{1,5})(\sвека?)?$/i ) ) {
isoDate = new Date( 0 );
isoDate.setFullYear( centuries.indexOf( dateParts[ 1 ].toUpperCase() ) * 100 + 1 );
result.precision = 7;
} else if ( dateParts = timestamp.match( new RegExp( '^(' + months.join( '|' ) + ')\\s+([12]\\d{3})$' ) ) ) {
isoDate = new Date( Date.UTC( dateParts[ 2 ], months.indexOf( dateParts[ 1 ] ) ) );
result.precision = 10;
} else if ( dateParts = timestamp.match( new RegExp( '(\\d{1,2})\\s+(' + monthsGen.join( '|' ) + ')[,\\s]+([12]\\d{3})(?:\\sгод|\.?$)' ) ) ) {
isoDate = new Date( Date.UTC( dateParts[ 3 ], monthsGen.indexOf( dateParts[ 2 ] ), dateParts[ 1 ] ) );
result.precision = 11;
} else if ( dateParts = timestamp.match( /^(\d{1,2})\.(\d{1,2})\.(\d{2,4})$/ ) ) {
isoDate = new Date( Date.UTC( dateParts[ 3 ] < 100 ? 1900 + parseInt( dateParts[ 3 ] ) : dateParts[ 3 ], dateParts[ 2 ] - 1, dateParts[ 1 ] ) );
result.precision = 11;
} else if ( dateParts = timestamp.match( /^(\d{4})-(\d{1,2})-(\d{1,2})/ ) ) {
isoDate = new Date( Date.UTC( dateParts[ 1 ] < 100 ? 1900 + parseInt( dateParts[ 1 ] ) : dateParts[ 1 ], dateParts[ 2 ] - 1, dateParts[ 3 ] ) );
result.precision = 11;
} else if ( dateParts = timestamp.match( /(\d{3,4})-е/ ) ) {
isoDate = new Date( Date.UTC( dateParts[ 1 ], 0 ) );
result.precision = 8;
} else if ( dateParts = timestamp.match( /(\d{3,4})/ ) ) {
isoDate = new Date( Date.UTC( dateParts[ 1 ], 0 ) );
result.precision = 9;
} else if ( timestamp.match( /^(наст\.|настоящее|наше)\s+время$/ ) ) {
return 'novalue';
} else if ( timestamp.match( /^(\?|неизвестно)$/ ) ) {
return 'somevalue';
} else return;
try {
result.time = '+' + isoDate.toISOString().replace( /\.000Z/, 'Z' );
} catch ( e ) {
return;
}
if ( result.precision < 11 ) {
result.time = result.time.replace( /-\d\dT/, '-00T' );
}
if ( result.precision < 10 ) {
result.time = result.time.replace( /-\d\d-/, '-00-' );
}
result.calendarmodel = 'http://www.wikidata.org/entity/Q' +
( forceJulian || isoDate < new Date( Date.UTC( 1582, 9, 15 ) ) ? '1985786' : '1985727' );
return result;
};
/**
* Отображение ошибки
*/
var wdeErrorDialog = function ( title, message ) {
var errorDialog = new OO.ui.MessageDialog();
wdeWindowManager.addWindows( [ errorDialog ] );
wdeWindowManager.openWindow( errorDialog, {
title: title,
message: message
} );
};
/**
* Достаем url сноски
*/
var wdeGetReference = function ( $field ) {
var references = [];
var $notes = $field.find( 'sup.reference a' );
for ( var i = 0; i < $notes.length; i++ ) {
var $externalLinks = $( $notes[ i ].hash.replace( /[!"$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, '\\$&' ) + ' a[rel="nofollow"]' );
for ( var j = 0; j < $externalLinks.length; j++ ) {
var $externalLink = $( $externalLinks.get( j ) );
if ( !$externalLink.attr( 'href' ).match( /(wikipedia.org|webcitation.org|archive.is)/ ) ) {
var source = {
snaks: {
P854: [ {
property: 'P854',
datatype: 'url',
snaktype: 'value',
datavalue: {
type: 'string',
value: $externalLink.attr( 'href' )
}
} ]
}
};
// P813
var $accessed = $externalLinks.parent().find( 'small:contains("Проверено")' );
if ( $accessed.length ) {
var accessDate = wdeCreateTimeSnak( $accessed.first().text() );
if ( accessDate ) {
source.snaks.P813 = [ {
property: 'P813',
datatype: 'time',
snaktype: 'value',
datavalue: {
type: 'time',
value: accessDate
}
} ];
}
}
// P1065 + P2960
var $archiveLinks = $externalLinks.filter( 'a:contains("Архивировано")' );
if ( $archiveLinks.length ) {
var $archiveLink = $archiveLinks.first();
source.snaks.P1065 = [ {
property: 'P1065',
datatype: 'url',
snaktype: 'value',
datavalue: {
type: 'string',
value: $archiveLink.attr( 'href' )
}
} ];
var archiveDate = wdeCreateTimeSnak( $archiveLink.parent().text().replace( 'Архивировано', '' ).trim() );
if ( archiveDate ) {
source.snaks.P2960 = [ {
property: 'P2960',
datatype: 'time',
snaktype: 'value',
datavalue: {
type: 'time',
value: archiveDate
}
} ];
}
}
references.push( source );
break;
}
}
}
references.push( { snaks: wdeConfig.references } );
return references;
};
/**
* Отформатировать источники для показа
*/
var wdeFormatDomains = function ( references ) {
var $result = $( '<sup>' );
for ( var i = 0; i < references.length; i++ ) {
var p854 = references[ i ].snaks.P854;
if ( p854 ) {
var domain = p854[ 0 ].datavalue.value.replace( 'http://', '' ).replace( 'https://', '' ).replace( 'www.', '' );
if ( domain.indexOf( '/' ) > 0 ) {
domain = domain.substr( 0, domain.indexOf( '/' ) );
}
$result.append( $( '<a>' ).attr( 'href', p854[ 0 ].datavalue.value ).text( '[' + domain + ']' ) );
}
}
return $result;
};
/**
* Форматирование wikidata values для показа пользователю
*/
var wdeFormatDataValue = function ( datavalue ) {
var $label = $( '<span>' );
switch ( datavalue.type ) {
case 'time':
if ( datavalue.value.precision === 7 ) {
$label.text( centuries[ Math.floor( (datavalue.value.time.substr( 1, 4 ) - 1) / 100 ) ] + ' век' );
break;
}
var options = {};
if ( datavalue.value.precision > 7 ) {
options.year = 'numeric';
}
if ( datavalue.value.precision > 9 ) {
options.month = 'long';
}
if ( datavalue.value.precision > 10 ) {
options.day = 'numeric';
}
var parsedDate = new Date( Date.parse( datavalue.value.time.substring( 1 ).replace( /-00/g, '-01' ) ) );
$label.text( parsedDate.toLocaleString( 'ru-ru', options ) + ( datavalue.value.precision === 8 ? '-е' : '' ) );
break;
case 'quantity':
$label.append( $( '<strong>' ).text( datavalue.value.amount ) );
if ( datavalue.value.bound ) {
$label.append( $( '<span>' ).text( ' ± ' + datavalue.value.bound ) );
}
if ( datavalue.value.unit !== '1' ) {
var unitId = datavalue.value.unit.substr( datavalue.value.unit.indexOf( 'Q' ) );
var name = ( ( wdeConfig.units[ unitId ] || {} ).label || {} ).value || unitId;
var description = ( ( wdeConfig.units[ unitId ] || {} ).description || {} ).value || 'Невозможно подгрузить описание';
$label.append( ' ' ).append( $( '<abbr>' ).attr( 'title', description ).text( name ) );
}
break;
case 'wikibase-entityid':
$label.append( $( '<strong>' ).text( datavalue.value.label ? datavalue.value.label : datavalue.value.id ) )
.append( datavalue.value.description ? ' — ' + datavalue.value.description : '' );
break;
}
for ( var propertyId in datavalue.qualifiers ) {
if ( !datavalue.qualifiers.hasOwnProperty( propertyId ) ) {
continue;
}
if ( propertyId === 'P1480' && datavalue.qualifiers[ propertyId ][ 0 ].datavalue.value.id === 'Q5727902' ) {
$label.prepend( $( '<abbr>' ).attr( 'title', 'обстоятельства источника = около' ).text( 'ок.' ), ' ' );
}
var formatted = wdeFormatDataValue( datavalue.qualifiers[ propertyId ][ 0 ].datavalue );
if ( formatted && $( '<span>' ).append( formatted ).text() ) {
$label.append( $( '<span>' ).text( ' (' ).append( formatted ).append( ')' ) );
}
}
return $label;
};
var wdeParseItems = function ( $content, callback ) {
var titles = [];
var ProcessWbGetItems = function ( data ) {
if ( data.success ) {
var values = [];
for ( var entityId in data.entities ) {
if ( !data.entities.hasOwnProperty( entityId ) || !entityId.match( /^Q/ ) ) {
continue;
}
var entity = data.entities[ entityId ];
var label = entity.labels.ru || entity.labels.en || entity.labels[ Object.keys( entity.labels )[ 0 ] ];
var description = entity.descriptions.ru || entity.descriptions.en || entity.descriptions[ Object.keys( entity.descriptions )[ 0 ] ];
if ( ( ( ( ( ( ( ( entity || {} ).claims || {} ).P31 || [] )[ 0 ] || {} ).mainsnak || {} ).datavalue || {} ).value || {} ).id === 'Q4167410' ) {
continue; //пропускаем неоднозначности
}
var subclassFound = false;
var subclassEntity = null;
for ( var candidateId in data.entities ) {
if ( !data.entities.hasOwnProperty( candidateId ) || !candidateId.match( /^Q/ ) || entityId === candidateId ) {
continue;
}
subclassFound = [ 'P17', 'P31', 'P131', 'P279', 'P361' ].find( function ( propertyId ) {
var values = ( ( ( data.entities[ candidateId ] || {} ).claims || {} )[ propertyId ] || [] );
return values.find( function ( statement ) {
var result = ( ( ( statement.mainsnak || {} ).datavalue || {} ).value || {} ).id === entityId;
if ( result ) {
subclassEntity = data.entities[ candidateId ];
}
return result;
} );
} );
if ( subclassFound ) {
break;
}
}
if ( subclassFound ) {
if ( subclassEntity ) {
var subclassLabel = subclassEntity.labels.ru || subclassEntity.labels.en || subclassEntity.labels[ Object.keys( subclassEntity.labels )[ 0 ] ];
mw.notify( 'Значение «' + label.value + '» исключено, уже имеется более точное: «' + subclassLabel.value + '»', {
type: 'warn',
tag: 'wikidataInfoboxExport-warn-precise'
} );
}
continue; //пропускаем записи для которых есть более точные
}
var value = {
wd: {
type: 'wikibase-entityid',
value: {
id: entityId,
label: label ? label.value : label,
description: description ? description.value : description
}
}
};
if ( label ) {
var results = titles.filter( function ( item ) {
return item.label.toLowerCase() === label.value.toLowerCase();
} );
if ( results.length === 1 ) {
value.wd.qualifiers = results[ 0 ].qualifiers;
}
}
value.label = wdeFormatDataValue( value.wd );
values.push( value );
}
if ( callback ) {
callback( values );
}
}
};
var fixedValues = [
{ property: 'P21', regexp: /жен/, item: 'Q6581072', label: 'женский' },
{ property: 'P21', regexp: /муж/, item: 'Q6581097', label: 'мужской' },
{ property: 'P552', regexp: /прав/, item: 'Q3039938', label: 'правша' },
{ property: 'P552', regexp: /лев/, item: 'Q789447', label: 'левша' },
{ property: 'P423', regexp: /прав/, item: 'Q10927630', label: 'праворукий удар' },
{ property: 'P423', regexp: /лев/, item: 'Q10927615', label: 'леворукий удар' }
];
for ( var k = 0; k < fixedValues.length; k++ ) {
if ( $content.attr( 'data-wikidata-property-id' ) === fixedValues[ k ].property && $content.text().match( fixedValues[ k ].regexp ) ) {
var result = { success: true, entities: {} };
result.entities[ fixedValues[ k ].item ] = {
labels: { ru: { value: fixedValues[ k ].label } },
descriptions: {}
};
ProcessWbGetItems( result );
return;
}
}
var sites = [];
var languages = [];
var $links = $content.find( 'a[title][class!=image][class!=new]' );
var redirects = [];
if ( !$links.length && $content.text().trim() ) {
// Если ссылок не нашлось, то пробуем искать статью по тексту
var parts = $content.text().split( /[\n,;]+/ );
for ( var i in parts ) {
var year = '';
var articleTitle = parts[ i ].replace( /\([^)]*\)/, function ( match ) {
year = match.replace( /\(\)/, '' );
return '';
} ).trim();
if ( articleTitle ) {
var value = {
label: articleTitle.charAt( 0 ).toUpperCase() + articleTitle.substr( 1, articleTitle.length - 1 ),
qualifiers: {}
};
if ( wdeCreateTimeSnak( year ) ) {
value.qualifiers.P585 = [ {
datatype: 'time', snaktype: 'value', property: 'P585',
datavalue: {
type: 'time',
value: wdeCreateTimeSnak( year )
}
} ];
}
titles.push( value );
}
}
titles = $.unique( titles );
languages.push( wdeConfig.language );
sites.push( wdeConfig.project );
} else {
for ( var j = 0; j < $links.length; j++ ) {
var extractedUrl = decodeURIComponent( $links[ j ].getAttribute( 'href' ) ).replace( /^.*\/wiki\//, '' );
if ( extractedUrl ) {
extractedUrl = extractedUrl.replace( /_/g, ' ' ).trim();
var value = {
label: extractedUrl.charAt( 0 ).toUpperCase() + extractedUrl.substr( 1, extractedUrl.length - 1 ),
qualifiers: {}
};
var match = $links[ j ].innerHTML.match( /(\d\d\d\d)\s*(?:год|г\.?)/ );
if ( !match ) {
match = $links[ j ].innerHTML.match( / — (\d\d\d\d)/ );
}
var extractedYear = match ? wdeCreateTimeSnak( match[ 1 ] ) : wdeCreateTimeSnak( ( $links[ j ].nextSibling || {} ).textContent );
if ( extractedYear ) {
value.qualifiers.P585 = [ {
datatype: 'time', snaktype: 'value', property: 'P585',
datavalue: {
type: 'time',
value: extractedYear
}
} ];
}
titles.push( value );
var language = wdeConfig.language;
var project = wdeConfig.project;
switch ( $links[ j ].getAttribute( 'class' ) ) {
case 'extiw': // Интервики
var m = $links[ j ].getAttribute( 'href' ).match( /^https:\/\/([a-z\-]+)\.(wik[^\.]+)\./ );
if ( m && m[ 2 ] !== 'wikimedia' ) {
language = m[ 1 ];
project = m[ 1 ] + m[ 2 ].replace( 'wikipedia', 'wiki' );
}
break;
case 'mw-redirect':
redirects.push( extractedUrl );
}
languages.push( language );
sites.push( project );
if ( $( $links[ j ] ).find( 'img' ) ) {
redirects.push( extractedUrl );
}
}
}
}
if ( redirects.length ) {
api.get( {
action: 'query',
redirects: 1,
titles: redirects
} ).done( function ( data ) {
if ( data.query && data.query.redirects ) {
for ( var i = 0; i < data.query.redirects.length; i++ ) {
for ( var j = 0; j < titles.length; j++ ) {
var lcTitle = titles[ j ].label.substr( 0, 1 ).toLowerCase() + titles[ j ].label.substr( 1 );
var lcRedirect = data.query.redirects[ i ].from.substr( 0, 1 ).toLowerCase() + data.query.redirects[ i ].from.substr( 1 );
if ( lcTitle === lcRedirect ) {
titles.splice( j + 1, 0, {
label: data.query.redirects[ i ].to,
year: titles[ j ].year
} );
sites.splice( j + 1, 0, wdeConfig.project );
languages.splice( j + 1, 0, wdeConfig.language );
j++;
}
}
}
}
wdApi.get( {
action: 'wbgetentities',
sites: sites,
languages: languages,
props: [ 'labels', 'descriptions', 'claims' ],
titles: titles.map( function ( item ) {
return item.label;
} )
} ).done( ProcessWbGetItems );
} );
} else {
wdApi.get( {
action: 'wbgetentities',
sites: sites,
languages: languages,
props: [ 'labels', 'descriptions', 'claims' ],
titles: titles.map( function ( item ) {
return item.label;
} )
} ).done( ProcessWbGetItems );
}
};
/**
* Распарсивание количества и (опционально) точности
*/
var wdeParseQuantity = function ( text, forceInteger ) {
var out = {
value: {},
};
text = text.replace( /,/g, '.' ).replace( /[−|–]/g, '-' );
// Sourcing circumstances (P1480) = circa (Q5727902)
var circaMatch = text.match( new RegExp( wdeConfig.reCirca ) );
if ( circaMatch ) {
out.qualifiers = {
P1480: [ {
snaktype: 'value',
property: 'P1480',
datavalue: {
type: 'wikibase-entityid',
value: { id: 'Q5727902' }
}
} ],
};
text = text.replace( circaMatch[ 0 ], '' );
}
var magnitude = 0;
if ( text.match( /тыс/ ) ) {
magnitude += 3;
} else if ( text.match( /млн|\dM(?:\s|$)|миллион|million/ ) ) {
magnitude += 6;
} else if ( text.match( /млрд|billion/ ) ) {
magnitude += 9;
} else if ( text.match( /трлн/ ) ) {
magnitude += 12;
} else {
var match = text.match( /[\*|·]10(-?\d+)/ );
if ( match ) {
text = text.replace( /[\*|·]10(-?\d+)/, '' );
magnitude += parseInt( match[ 1 ] );
}
}
var decimals = text.split( '±' );
if ( magnitude === 0 && forceInteger ) {
decimals[ 0 ] = decimals[ 0 ].replace( /\./g, '' );
}
var amount = parseFloat( decimals[ 0 ].replace( /[^0-9.+-]/g, '' ) );
if ( isNaN( amount ) ) {
return;
}
var parts = amount.toString().match( /(\d+)\.(\d+)/ );
var integral = parts ? parts[ 1 ].length : amount.toString().length;
var fractional = parts ? parts[ 2 ].length : 0;
if ( magnitude >= 0 ) {
if ( magnitude <= fractional ) {
out.value.amount = ( ( '1e' + magnitude ) * amount ).toFixed( fractional - magnitude );
} else {
out.value.amount = ( ( '1e' + fractional ) * amount ).toFixed( 0 ).replace( /$/, new Array( magnitude - fractional + 1 ).join( '0' ) );
}
} else {
if ( magnitude >= -integral ) {
out.value.amount = ( ( '1e' + magnitude ) * amount ).toFixed( fractional - magnitude );
} else {
out.value.amount = ( ( '1e-' + integral ) * amount ).toFixed( integral + fractional ).replace( /0\./, '0.' + new Array( -magnitude - integral + 1 ).join( '0' ) );
}
}
if ( decimals.length > 1 ) {
var bound = parseFloat( decimals[ 1 ].replace( /[^0-9.+-]/g, '' ) );
if ( !isNaN( bound ) ) {
if ( decimals[ 1 ].indexOf( '%' ) > 0 ) {
bound = amount * bound / 100;
} else {
parts = bound.toString().match( /(\d+)\.(\d+)/ );
integral = parts ? parts[ 1 ].length : amount.toString().length;
fractional = parts ? parts[ 2 ].length : 0;
}
if ( magnitude >= 0 ) {
if ( magnitude <= fractional ) {
out.value.lowerBound = ( ( '1e' + magnitude ) * ( amount - bound ) ).toFixed( fractional - magnitude );
out.value.upperBound = ( ( '1e' + magnitude ) * ( amount + bound ) ).toFixed( fractional - magnitude );
out.value.bound = ( ( '1e' + magnitude ) * bound ).toFixed( fractional - magnitude ); // нужно для показа пользователю
} else {
out.value.lowerBound = ( ( '1e' + fractional) * ( amount - bound ) ).toFixed( 0 ).replace( /$/, new Array( magnitude - fractional + 1 ).join( '0' ) );
out.value.upperBound = ( ( '1e' + fractional) * ( amount + bound ) ).toFixed( 0 ).replace( /$/, new Array( magnitude - fractional + 1 ).join( '0' ) );
out.value.bound = ( ( '1e' + fractional ) * bound ).toFixed( 0 ).replace( /$/, new Array( magnitude - fractional + 1 ).join( '0' ) );
}
} else {
if ( magnitude >= -integral ) {
out.value.lowerBound = ( ( '1e' + magnitude ) * ( amount - bound ) ).toFixed( fractional - magnitude );
out.value.upperBound = ( ( '1e' + magnitude ) * ( amount + bound ) ).toFixed( fractional - magnitude );
out.value.bound = ( ( '1e' + magnitude ) * bound ).toFixed( fractional - magnitude );
} else {
out.value.lowerBound = ( ( '1e-' + integral ) * ( amount - bound ) ).toFixed( integral + fractional ).replace( /0\./, '0.' + new Array( -magnitude - integral + 1 ).join( '0' ) );
out.value.upperBound = ( ( '1e-' + integral ) * ( amount + bound ) ).toFixed( integral + fractional ).replace( /0\./, '0.' + new Array( -magnitude - integral + 1 ).join( '0' ) );
out.value.bound = ( ( '1e-' + integral ) * bound ).toFixed( integral + fractional ).replace( /0\./, '0.' + new Array( -magnitude - integral + 1 ).join( '0' ) );
}
}
}
}
return out;
};
/**
* Распознавание единиц измерения в параметре карточки и его заголовке
*/
var wdeRecognizeUnits = function ( text, units, label ) {
if ( Array.isArray( units ) && units.length === 0 ) {
return [ '1' ];
}
var result = [];
for ( var idx in units ) {
if ( !units.hasOwnProperty( idx ) ) {
continue;
}
var item = parseInt( idx ) >= 0 ? units[ idx ] : idx;
var search = wdeConfig.units[ item ].search;
for ( var j = 0; j < search.length; j++ ) {
var expr = search[ j ];
if ( search[ j ].charAt( 0 ) !== '^' ) {
expr = '[\\d\\s\\.]' + expr;
if ( search[ j ].length < 5 ) {
expr = expr + '\\.?$';
}
}
if ( text.match( new RegExp( expr, 'i' ) ) ) {
result.push( item );
break;
} else if ( search[ j ].charAt( 0 ) !== '^' && label && label.match( new RegExp( '\\s' + search[ j ] + ':?$', 'i' ) ) ) {
result.push( item );
break;
}
}
}
return result;
};
/**
* Создание всех утверждений в Викиданных и отметка свойства экcпортированным
*/
var wdeCreateClaims = function ( propertyId, values, refUrl, revIds ) {
var value = values.shift();
revIds = revIds || [];
if ( !value ) {
// Все утверждения добавлены - переходим к установке меток
wdeAddTags( propertyId, revIds );
return;
} else {
value = JSON.parse( value );
}
var datatype = wdeConfig.properties[ propertyId ].datatype;
var mainsnak = value.value.toString().match( /^(novalue|somevalue)$/ ) ? {
snaktype: value.value,
property: propertyId
} : {
snaktype: 'value',
property: propertyId,
datavalue: {
type: wdeTypesMapping[ datatype ] ? wdeTypesMapping[ datatype ] : datatype,
value: value.value
}
};
var claim = {
type: 'statement',
mainsnak: mainsnak,
id: wdeClaimGuid( mw.config.get( 'wgWikibaseItemId' ) ),
references: refUrl,
rank: 'normal'
};
if ( value.qualifiers ) {
claim.qualifiers = value.qualifiers;
}
wdApi.postWithToken( 'csrf', {
action: 'wbsetclaim',
claim: JSON.stringify( claim ),
baserevid: wdeBaseRevId
} ).done( function ( claimData ) {
if ( claimData.success ) {
var valuesLeftStr = values.length ? ' (осталось ' + values.length + ')' : '';
mw.notify( 'Значение свойства ' + propertyId + ' успешно добавлено в Викиданные' + valuesLeftStr, {
tag: 'wikidataInfoboxExport-success'
} );
wdeBaseRevId = claimData.pageinfo.lastrevid;
revIds.push( wdeBaseRevId );
wdeCreateClaims( propertyId, values, refUrl, revIds );
} else {
wdeErrorDialog( 'Ошибка при сохранении', JSON.stringify( claimData ) );
}
} );
};
/**
* Установка меток гаджета для сделанных правок
* FIXME: Добавлять метки сразу, когда будет исправлен [[phab:T155109]]
*/
var wdeAddTags = function ( propertyId, revIds ) {
wdApi.postWithToken( 'csrf', {
action: 'tag',
add: 'InfoboxExport gadget',
revid: revIds
} ).done( function ( data ) {
var success = false;
if ( data.tag ) {
success = true;
for ( var i = 0; i < data.tag.length; i++ ) {
if ( data.tag[ i ].status !== 'success' ) {
success = false;
break;
}
}
}
if ( success ) {
mw.notify( 'Метки правок в Викиданных успешно установлены', {
tag: 'wikidataInfoboxExport-tags-success'
} );
$( '.no-wikidata[data-wikidata-property-id=' + propertyId + ']' )
.removeClass( 'no-wikidata' )
.off( 'dblclick', wdeClickEvent );
} else {
mw.notify( 'Ошибка при установке метки правок в Викиданных', {
type: 'warn',
tag: 'wikidataInfoboxExport-tags-error'
} );
}
} );
};
/**
* Обёртка для предзагрузки информации о свойствах, исключающая уже загруженные.
*/
var wdeLoadProperties = function ( propertyIds ) {
if ( !propertyIds || !propertyIds.length ) {
return;
}
var realPropertyIds = [];
for ( var i in propertyIds ) {
var propertyId = propertyIds[ i ];
if ( wdeConfig.properties[ propertyId ] === undefined ) {
realPropertyIds.push( propertyId );
}
}
if ( realPropertyIds.length ) {
wdeRealLoadProperties( realPropertyIds );
}
};
/**
* Предзагрузка информации о всех свойствах.
*/
var wdeRealLoadProperties = function ( propertyIds ) {
if ( !propertyIds || !propertyIds.length ) {
return;
}
var units = [];
wdApi.get( {
action: 'wbgetentities',
languages: wdeConfig.languages,
props: [ 'labels', 'datatype', 'claims' ],
ids: propertyIds
} ).done( function ( data ) {
if ( !data.success ) {
return;
}
for ( var propertyId in data.entities ) {
if ( !data.entities.hasOwnProperty( propertyId ) ) {
continue;
}
var entity = data.entities[ propertyId ];
var label = entity.labels[ wdeConfig.language ] ? entity.labels[ wdeConfig.language ].value : entity.labels.en.value;
wdeConfig.properties[ propertyId ] = {
datatype: entity.datatype,
label: label.charAt( 0 ).toUpperCase() + label.slice( 1 ),
constraints: { qualifier: [] },
units: []
};
if ( propertyId === 'P1128' || propertyId === 'P2196' ) {
wdeConfig.properties[ propertyId ].constraints.integer = 1;
}
if ( entity.claims ) {
// Ограничения свойства
if ( entity.claims.P2302 ) {
for ( var i in entity.claims.P2302 ) {
switch ( ( ( ( ( entity.claims.P2302[ i ] || {} ).mainsnak || {} ).datavalue || {} ).value || {} ).id ) {
case 'Q19474404':
case 'Q21502410':
wdeConfig.properties[ propertyId ].constraints.unique = 1;
break;
}
}
}
// "Обязательный" квалификатор
if ( entity.claims.P1646 ) {
for ( var i in entity.claims.P1646 ) {
var qualifierId = ( ( ( ( entity.claims.P1646[ i ] || {} ).mainsnak || {} ).datavalue || {} ).value || {} ).id;
if ( qualifierId ) {
wdeConfig.properties[ propertyId ].constraints.qualifier.push( qualifierId.toString() );
}
}
}
// Единицы измерения
if ( entity.claims.P2237 ) {
for ( var i in entity.claims.P2237 ) {
var unitId = ( ( ( ( entity.claims.P2237[ i ] || {} ).mainsnak || {} ).datavalue || {} ).value || {} ).id;
if ( unitId && unitId != 'Q21027105' ) {
wdeConfig.properties[ propertyId ].units.push( unitId );
units.push( unitId );
}
}
}
}
}
var languages = wdeConfig.languages;
wdApi.get( {
action: 'wbgetentities',
languages: languages,
props: [ 'labels', 'descriptions', 'aliases', 'claims' ],
ids: $.unique( units )
} ).done( function ( unitData ) {
if ( !unitData.success ) {
return;
}
for ( var unitId in unitData.entities ) {
var unit = unitData.entities[ unitId ];
var unitSearch = wdeConfig.units[ unitId ] ? wdeConfig.units[ unitId ].search : [];
if ( !wdeConfig.units[ unitId ] ) {
wdeConfig.units[ unitId ] = {};
}
// Метка
if ( unit.labels ) {
wdeConfig.units[ unitId ].label = unit.labels[ wdeConfig.language ] ||
unit.labels.en ||
unit.labels[ Object.keys( unit.labels )[ 0 ] ];
if ( unit.labels[ wdeConfig.language ] ) {
unitSearch.push( unit.labels[ wdeConfig.language ].value.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&' ) );
}
}
// Описание
if ( unit.descriptions ) {
wdeConfig.units[ unitId ].description = unit.descriptions[ wdeConfig.language ] ||
unit.descriptions.en ||
unit.descriptions[ Object.keys( unit.labels )[ 0 ] ];
}
// Алиасы
if ( unit.aliases && unit.aliases[ wdeConfig.language ] ) {
for ( var i in unit.aliases[ wdeConfig.language ] ) {
unitSearch.push( unit.aliases[ wdeConfig.language ][ i ].value.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&' ) );
}
}
// Обозначение единиц (P558)
if ( unit.claims && unit.claims.P558 ) {
for ( var i in unit.claims.P558 ) {
var claim = unit.claims.P558[ i ];
if ( claim.mainsnak &&
claim.mainsnak.datavalue &&
claim.mainsnak.datavalue.value
) {
unitSearch.push( claim.mainsnak.datavalue.value.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&' ) );
}
}
}
wdeConfig.units[ unitId ].search = unitSearch;
localStorage.setItem( 'wdeConfig', JSON.stringify( wdeConfig ) );
}
} );
} );
};
/**
* Парсинг значений из параметров перед выводом диалога
*/
var wdePrepareDialog = function ( $field, propertyId ) {
var values = [];
var datatype = wdeConfig.properties[ propertyId ].datatype;
var $content = $field.clone();
$content.find( 'sup.reference' ).remove();
$content.find( '[style*="display:none"]' ).remove();
switch ( datatype ) {
case 'commonsMedia':
var $imgs = $content.find( 'img' );
$imgs.each( function () {
var $img = $( this );
var src = $img.attr( 'src' );
if ( !src.match( /upload.wikimedia.org\/wikipedia\/commons/ ) ) {
return;
}
var srcParts = src.split( '/' );
var fileName = srcParts.pop();
if ( fileName.match( /^\d+px-/ ) ) {
fileName = srcParts.pop();
}
fileName = decodeURIComponent( fileName );
fileName = fileName.replace( /_/g, ' ' );
var value = { value: fileName };
var $label = $img.clone()
.attr( 'title', fileName )
.css( 'border', '1px dashed #a2a9b1' );
var $qualifiers = $field.find( '[data-wikidata-qualifier-id="P2096"]' );
if ( $qualifiers.length > 0 ) {
value.qualifiers = {
P2096: [ {
snaktype: 'value', property: 'P2096',
datavalue: {
type: 'monolingualtext',
value: {
text: $qualifiers[ 0 ].innerText.replace( '\n', ' ' ),
language: 'ru'
}
}
} ]
};
$label = $( this.outerHTML + '<p>' + $qualifiers[ 0 ].innerText + '</p>' );
}
values.push( { wd: value, label: $label } );
} );
break;
case 'external-id':
var externalId = $content.data( 'wikidata-external-id' ) || $content.text();
if ( propertyId === 'P345' ) { // IMDB
externalId = $content.find( 'a' ).first().attr( 'href' );
externalId = externalId.substr( externalId.lastIndexOf( '/', externalId.length - 2 ) ).replace( /\//g, '' );
} else {
externalId = externalId.toString().replace( /^ID\s/, '' ).replace( /\s/g, '' );
}
var sparql = 'SELECT * WHERE { ?item wdt:' + propertyId + ' "' + externalId + '" }';
$.ajax( {
url: 'https://query.wikidata.org/sparql?format=json&query=' + sparql,
success: function ( data ) {
var $label = $( '<code>' ).text( externalId );
if ( data.results.bindings.length ) {
var url = data.results.bindings[ 0 ].item.value;
$label = $( '<span>' ).append( $( '<code>' ).text( externalId ) )
.append( $( '<strong>' ).css( { 'color': 'red' } ).text( ' уже используется в ' ) )
.append( $( '<a>' ).attr( 'href', url ).attr( 'target', '_blank' ).text( url.replace( /[^Q]*Q/, 'Q' ) ) );
}
wdeDialog( $field, propertyId, [ {
wd: { value: externalId.toString() },
label: $label
} ], wdeGetReference( $content ) );
}
} );
return;
case 'string':
var text = $content.data( 'wikidata-external-id' );
if ( !text ) {
text = $content.text();
}
var strings = text.toString().trim().split( /[\n,;]+/ );
// Commons category
if ( propertyId === 'P373' ) {
var $link = $content.find( 'a[class="extiw"]' ).first();
if ( $link.length ) {
var url = $link.attr( 'href' );
var value = url.substr( url.lastIndexOf( '/' ) + 1 )
.replace( /_/g, ' ' )
.replace( /^[Cc]ategory:/, '' )
.replace( /\?.*$/, '' );
value = decodeURIComponent( value );
strings = [ value ];
}
}
for ( var i in strings ) {
var s = strings[ i ].replace( /\n/g, ' ' ).trim();
if ( s ) {
values.push( {
wd: { value: s },
label: $( '<code>' + s + '</code>' )
} );
}
}
break;
case 'monolingualtext':
var $items = $content.find( '[lang]' );
$items.each( function () {
var $item = $( this );
values.push( {
wd: {
value: {
text: $item.text().trim(),
language: $item.attr( 'lang' ).trim()
}
}
} );
} );
if ( !values.length ) {
var text = $content.text().trim();
if ( text ) {
var $items = mw.util.$content.find( '[lang]' );
$items.each( function () {
$item = $( this );
if ( $item.text().trim().startsWith( text ) ) {
values.push( {
wd: {
value: {
text: text,
language: $item.attr( 'lang' ).trim()
}
}
} );
}
} );
}
}
for ( var i in values ) {
values[ i ].label = $( '<span>' )
.append( $( '<span>' ).css( 'color', '#666' ).text( '(' + values[ i ].wd.value.language + ') ' ) )
.append( $( '<strong>' ).text( values[ i ].wd.value.text ) );
}
break;
case 'quantity':
var text = $content.text().replace( /[\u00a0\u25bc\u25b2]/g, ' ' ).replace( /\s\(([^)]*\))/g, '' ).trim();
var result = { wd: wdeParseQuantity( text, wdeConfig.properties[ propertyId ].constraints.integer ) };
if ( !result.wd.value ) {
break;
}
if ( wdeConfig.properties[ propertyId ].constraints.qualifier.indexOf( 'P585' ) !== -1 ) {
var yearMatch = $content.text().match( /\(([^)]*[12]\d\d\d)[,)\s]/ );
if ( !yearMatch ) {
yearMatch = $field.closest( 'tr' ).find( 'th' ).first().text().match( /\(([^)]*[12]\d\d\d)[,)\s]/ );
}
if ( yearMatch ) {
if ( extractedDate = wdeCreateTimeSnak( yearMatch[ 1 ] ) ) {
result.wd.qualifiers = {
P585: [ {
snaktype: 'value', property: 'P585',
datavalue: {
type: 'time',
value: extractedDate
}
} ]
};
}
}
}
var qualMatch = $content.text().match( /\(([^\)]*)/ );
if ( qualMatch ) {
qualQuantity = wdeParseQuantity( qualMatch[ 1 ] );
if ( qualQuantity ) {
var supportedProperties = [ 'P2076', 'P2077' ];
for ( var j = 0; j < supportedProperties.length; j++ ) {
var units = wdeRecognizeUnits( qualMatch[ 1 ], wdeConfig.properties[ supportedProperties[ j ] ].units );
if ( units.length === 1 ) {
qualQuantity.value.unit = 'http://www.wikidata.org/entity/' + units[ 0 ];
if ( !result.wd.qualifiers ) {
result.wd.qualifiers = {};
}
result.wd.qualifiers[ supportedProperties[ j ] ] = [ {
snaktype: 'value', property: supportedProperties[ j ],
datavalue: {
type: 'quantity',
value: qualQuantity.value
}
} ];
}
}
}
}
var founded = wdeRecognizeUnits( text, wdeConfig.properties[ propertyId ].units, $field.closest( 'tr' ).find( 'th' ).first().text() );
for ( var u = 0; u < founded.length; u++ ) {
result.wd.value.unit = '1';
if ( founded[ u ] !== '1' ) {
result.wd.value.unit = 'http://www.wikidata.org/entity/' + founded[ u ];
var item = wdeConfig.units[ founded[ u ] ];
}
result.wd.type = 'quantity';
result.label = wdeFormatDataValue( result.wd );
values.push( result );
}
break;
case 'time':
var value = wdeCreateTimeSnak( $content.text().replace( /\([^\)]*\)/, '' ).toLowerCase().trim().replace( /\s+(года?|г\.?)$/, '' ),
$content[ 0 ].outerHTML.includes( 'по юлианскому' ) );
if ( value.toString().match( /^(novalue|somevalue)$/ ) ) {
values.push( {
wd: { value: value },
label: $( '<span>' )
.append( $( '<span>' ).css( 'color', '#666' ).text( 'Значение ' ) )
.append( $( '<strong>' ).text( value.toString() === 'novalue' ? 'отсутствует' : 'неизвестно' ) )
} );
} else {
values.push( {
wd: { value: value },
label: $( '<span>' )
.append( $( '<strong>' ).append( wdeFormatDataValue( {
type: 'time',
value: value
} ) ) )
.append( $( '<span>' ).css( 'color', '#666' ).text( ' (' +
( value.calendarmodel.includes( '1985727' ) ? 'Григорианский' : 'Юлианский' ) + ') ' ) )
} );
}
break;
case 'wikibase-item':
value = wdeParseItems( $content, function ( values ) {
wdeDialog( $field, propertyId, values, wdeGetReference( $content ) );
} );
return;
case 'url':
var $links = $content.find( 'a' );
$links.each( function () {
var $link = $( this );
var url = $link.attr( 'href' );
values.push( {
wd: { value: url },
label: $( '<code>' + url + '</code>' )
} );
} );
break;
default:
mw.notify( 'Неизвестный тип данных свойства: ' + datatype, {
type: 'error',
tag: 'wikidataInfoboxExport-error'
} );
console.log( datatype, $content );
}
values = $.unique( values );
wdeDialog( $field, propertyId, values, wdeGetReference( $field ) );
};
/**
* Событие двойного клика по полю карточки
*/
var wdeClickEvent = function ( e ) {
var $field = $( this );
var propertyId = $field.attr( 'data-wikidata-property-id' );
wdePrepareDialog( $field, propertyId );
};
/**
* Вывод диалога для подтверждения экспорта
*/
var wdeDialog = function ( $field, propertyId, values, refUrl ) {
var fieldset;
if ( !values || !values.length ) {
mw.notify( 'Не удалось определить значение свойства', {
type: 'error',
tag: 'wikidataInfoboxExport-error'
} );
return;
}
// Создание диалога
function ProcessDialog( config ) {
ProcessDialog.super.call( this, config );
}
OO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );
ProcessDialog.static.name = 'Экспорт в Викиданные';
ProcessDialog.static.title = $( '<span>' )
.attr( 'title', 'Версия ' + wdeConfig.version )
.text( ProcessDialog.static.name );
ProcessDialog.static.actions = [
{ action: 'export', label: 'Экспорт', flags: [ 'primary', 'constructive' ] },
{ label: 'Отмена', flags: 'safe' }
];
ProcessDialog.prototype.initialize = function () {
ProcessDialog.super.prototype.initialize.apply( this, arguments );
this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
fieldset = new OO.ui.FieldsetLayout();
var firstSelected = false;
for ( var i = 0; i < values.length; i++ ) {
var alreadyInWikidata = ( wdeAlreadyExistingItems[ propertyId ] || [] ).includes( ( ( values[ i ].wd || {} ).value || {} ).id );
var checkbox = new OO.ui.CheckboxInputWidget( {
value: JSON.stringify( values[ i ].wd ),
selected: alreadyInWikidata,
disabled: alreadyInWikidata
} );
if ( !checkbox.isDisabled() ) {
if ( !firstSelected || !wdeConfig.properties[ propertyId ].constraints.unique ) {
firstSelected = true;
checkbox.setSelected( true );
}
if ( values[ i ].label[ 0 ].innerText.match( /уже используется/ ) &&
wdeConfig.properties[ propertyId ].constraints.unique &&
wdeConfig.properties[ propertyId ].datatype === 'external-id' ) {
checkbox.setSelected( false );
}
}
if ( refUrl ) {
values[ i ].label.append( wdeFormatDomains( refUrl ) );
}
fieldset.addItems( [
new OO.ui.FieldLayout( checkbox, {
label: values[ i ].label,
align: 'inline'
} )
] );
}
this.content.$element
.append( $( '<p>' ).append( $( '<strong>' )
.append( $( '<a>' ).attr( 'href', 'https://wikidata.org/wiki/Property:' + propertyId ).attr( 'target', '_blank' ).text( wdeConfig.properties[ propertyId ].label ) )
.append( $( '<span>' ).text( ':' ) )
) )
.append( fieldset.$element )
.append( $( '<hr>' ).css( 'margin-top', '1.5em' ) )
.append( $( '<p>' ).text( 'Экспортировать значение свойства из карточки в Викиданные?' ) )
.append( $( '<p>' ).css( 'font-size', 'smaller' ).html( 'Нажав на кнопку «Экспорт», вы соглашаетесь с <a href="https://foundation.wikimedia.org/wiki/Terms_of_Use" class="extiw" title="wikimedia:Terms of Use">условиями использования</a> и безотзывно соглашаетесь публиковать свой вклад на условиях <a rel="nofollow" class="external text" href="https://creativecommons.org/publicdomain/zero/1.0/">Creative Commons CC0 License</a>.' ) );
this.$body.append( this.content.$element );
};
ProcessDialog.prototype.getActionProcess = function ( action ) {
var dialog = this;
if ( action === 'export' ) {
return new OO.ui.Process( function () {
var values = [];
var fields = fieldset.getItems();
for ( var i in fields ) {
var checkbox = fields[ i ].getField();
if ( checkbox.isSelected() && !checkbox.isDisabled() ) {
values.push( checkbox.getValue() );
}
}
wdeCreateClaims( propertyId, values, refUrl );
dialog.close( { action: action } );
}, this );
}
return ProcessDialog.super.prototype.getActionProcess.call( this, action );
};
var windowManager = new OO.ui.WindowManager();
$( 'body' ).append( windowManager.$element );
var processDialog = new ProcessDialog();
windowManager.addWindows( [ processDialog ] );
windowManager.openWindow( processDialog );
};
/**
* Инициализация гаджета
*/
var wdeInit = function () {
if ( mw.config.get( 'wgWikibaseItemId' ) === null ||
mw.config.get( 'wgAction' ) !== 'view' ||
mw.config.get( 'wgNamespaceNumber' )
) {
return;
}
// Загрузка конфига из localStorage
var storedConfig;
try {
storedConfig = JSON.parse( localStorage.getItem( 'wdeConfig' ) );
} catch ( e ) {}
if ( storedConfig && storedConfig.version == wdeConfig.version ) {
wdeConfig = storedConfig;
}
if ( wdeConfig.properties === undefined ) {
wdeConfig.properties = {};
}
// Установка сайта и языка пользователя
wdeConfig.project = mw.config.get( 'wgDBname' );
wdeConfig.language = mw.user.options.get( 'language' ) || mw.config.get( 'wgContentLanguage' );
wdeConfig.languages.unshift( wdeConfig.language );
wdeConfig.languages = $.unique( wdeConfig.languages );
localStorage.setItem( 'wdeConfig', JSON.stringify( wdeConfig ) );
// Инициализация API
api = new mw.Api();
wdApi = new mw.ForeignApi( '//www.wikidata.org/w/api.php' );
// Инициализация диалогов
wdeWindowManager = new OO.ui.WindowManager();
$( 'body' ).append( wdeWindowManager.$element );
// Запрос данных элемента
wdApi.get( {
action: 'wbgetentities',
props: [ 'info', 'claims' ],
ids: mw.config.get( 'wgWikibaseItemId' )
} ).done( function ( data ) {
if ( data.success ) {
var claims;
for ( var i in data.entities ) {
if ( i == -1 ) {
return;
}
claims = data.entities[ i ].claims;
wdeBaseRevId = data.entities[ i ].lastrevid;
break;
}
if ( !claims ) {
return;
}
var $fields = $( '.infobox .no-wikidata' );
$fields.each( function () {
var $field = $( this );
var propertyId = $field.attr( 'data-wikidata-property-id' );
$field.removeClass( 'no-wikidata' );
wdePropertyIds.push( propertyId );
wdeCanExportValue( $field, claims[ propertyId ], function () {
$field.addClass( 'no-wikidata' );
$field.off( 'dblclick' ).on( 'dblclick', wdeClickEvent );
} );
} );
mw.util.addCSS( '\
.infobox .no-wikidata {\
display: block !important;\
background: #fdc;\
padding: 5px 0;\
}\
.infobox .no-wikidata .no-wikidata {\
margin: -5px 0;\
}\
' );
// TODO: Загружать при первом открытии окна
wdeLoadProperties( wdePropertyIds );
}
} );
};
$.when(
$.ready,
mw.loader.using( [
'mediawiki.api',
'mediawiki.ForeignApi',
'mediawiki.util',
'oojs-ui-core',
'oojs-ui-widgets',
'oojs-ui-windows'
] )
).done( wdeInit );
}( mediaWiki, jQuery ) );