User:Bargioni/UseAsRef 1.0.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* *******************************************************************
_ _ ___ ______ __
| | | | / _ \ | ___ \ / _|
| | | |___ ___/ /_\ \___ | |_/ /___| |_
| | | / __|/ _ \ _ / __|| // _ \ _|
| |_| \__ \ __/ | | \__ \| |\ \ __/ |
\___/|___/\___\_| |_/___/\_| \_\___|_|
use an ID as a reference for statements
gadget written by User:Epìdosis and User:Bargioni - feb 2021
******************************************************************* */
mw.loader.using('wikibase.Site').then(function () {
( function ( mw, wb, $ ) {
function makeSPARQLQuery( endpointUrl, sparqlQuery, doneCallback ) {
var settings = {
headers: { Accept: 'application/sparql-results+json' },
data: { query: sparqlQuery }
};
return $.ajax( endpointUrl, settings ).then( doneCallback );
}
function snaks_order (reference, P) {
// output order ["P248", "P9073", "P1810", "P813"]
var ordered_snaks = [];
ordered_snaks.push('P248');
ordered_snaks.push(P);
if (reference.P1810) ordered_snaks.push('P1810');
ordered_snaks.push('P813');
return ordered_snaks;
}
function new_reference ( current_reference ) {
var now = '+'+(new Date()).toISOString().substr(0,10)+'T00:00:00Z'; // WD doesn't handle hhmmss
var source_qid = current_reference.P9073.substr(1); // the numeric part of Qnnnn
var reference = {
"P248": [
{
"snaktype": "value",
"property": "P248", // source of info
"datavalue": {
"value": {
"entity-type": "item",
"numeric-id": source_qid
},
"type": "wikibase-entityid"
}
}
],
[current_reference.P] : [
{
"snaktype": "value",
"property": current_reference.P,
"datavalue": {
"value": current_reference.value,
"type": "string"
},
"datatype": "external-id"
}
],
"P813": [
{
"snaktype": "value",
"property": "P813", // stated on
"datatype": "time",
"datavalue": {
"value": {
"after": 0,
"before": 0,
"calendarmodel": "http://www.wikidata.org/entity/Q1985727",
"precision": 11,
"time": now,
"timezone": 0
},
"type": "time"
}
}
]
};
if (current_reference.P1810) {
reference.P1810 = [
{
"snaktype": "value",
"property": "P1810",
"datavalue": {
"value": current_reference.P1810,
"type": "string"
},
// "datatype": "?string?" // not mandatory
}
];
}
return reference;
}
function append_reference_to_statement( paste_icon, claim_guid, NR, P ) {
// disable paste icon, without changing its visibility
// perform only after a successfull save? FIXME
var so = snaks_order( NR, P );
$(paste_icon)
.css({
'border':'3px solid red',
'padding':'2px'
});
$(paste_icon).parents('.pasteref-container').css('pointer-events','none');
// save new reference
var api = new mw.Api();
var token = mw.user.tokens.values.csrfToken;
api.post({
'action' : 'wbsetreference',
'summary' : 'Added with [[User:Bargioni/UseAsRef|UseAsRef]]',
'statement' : claim_guid,
'snaks-order': JSON.stringify(so),
'snaks' : JSON.stringify(NR),
'format' : 'json',
'token' : token
})
.then( function(aw) {
if ( aw.success == 1 ) {
var ps = aw.reference['snaks-order'].toString();
mw.notify ('Reference successfully added using '+ps+'.\nYou may wish to reload the page.',
{
title: 'UseAsRef - Info',
autoHide: true,
type: 'info'
}
);
}
else {
console.log('ko',aw);
mw.notify (aw.error,
{
title: 'UseAsRef - Error',
autoHide: false,
type: 'error'
}
);
}
} )
.catch( function(e) { // catch errors that may occur inside .then function
console.log('ko',e);
mw.notify (e,
{
title: 'UseAsRef - Error',
autoHide: false,
type: 'error'
}
);
} );
}
function paste_reference ( paste_icon, current_reference ) {
// console.log( 'paste_reference', current_reference ); // test
// console.log( 'paste_icon', paste_icon ); // test
var in_edit_mode = $(paste_icon).parents('.wikibase-statementview-mainsnak').parent().parent().find('.wikibase-edittoolbar-ineditmode').length;
if (in_edit_mode) {
$('#useasref_dialog_msg').html('<div style="color:red">Cannot paste when in edit mode</div>');
$( '#useasref_dialog' ).dialog( 'open' );
return;
}
var NR = new_reference( current_reference );
var qid = mw.config.get( 'wbEntityId' ); // Qnnnn unused? TODO
var P = $(paste_icon).parents('div[id^=P]');
var Pclaim = $(P).attr('id'); // this is the P of the claim(s) the reference will be attached
var claim_guid = $(paste_icon).parents('div[class~="wikibase-statementview"]').attr('id');
var claim = Pclaim + ':'+ claim_guid; // unused? TODO
// and finally, let's call wbsetreference; see https://www.wikidata.org/w/api.php?action=help&modules=wbsetreference
append_reference_to_statement( paste_icon, claim_guid, NR, current_reference.P );
}
function link_to_P (P) {
var L = '<a href="https://www.wikidata.org/wiki/Property:'+ P +'" target"="_blank">'+P+'</a>';
return L;
}
function doneCallback(R) {
// console.log(R, mw.current_reference); // test
var rrb = R.results.bindings[0];
var uri_root = 'http://www.wikidata.org/entity/';
mw.current_reference.P9073 = rrb.P9073 ? rrb.P9073.value.replace(uri_root,'') : '';
mw.current_reference.P9073 = replaceAll(mw.current_reference.P9073, 'http://www.wikidata.org/entity/', '');
// mw.current_reference.P1629 = rrb.P1629 ? rrb.P1629.value : '';
// mw.current_reference.P1629 = replaceAll(mw.current_reference.P1629, 'http://www.wikidata.org/entity/', '');
var rrb_p1629 = rrb.P1629 ? rrb.P1629.value : '';
if ( mw.current_reference.P9073 == '') {
$('.copyref-container .useasref_icon').css({'border':'', 'padding':''});
var msg;
if ( rrb_p1629 == '' ) {
msg = 'Cannot use property ' +
link_to_P(mw.current_reference.P) +
' as a reference.<br>It lacks ' +
link_to_P('P9073') +
'. You may consider to add it.<br>' +
'Please respect the constraints of P9073 and ask <a target="_blank" href="/w/index.php?title=Property_talk:P9073&action=edit§ion=new">here</a> if you are unsure about the value of P9073 to be added.';
}
else {
msg = 'Cannot use property ' +
link_to_P(mw.current_reference.P) +
' as a reference.<br>It has ' +
link_to_P('P1629') +
' but it lacks ' +
link_to_P('P9073') +
'. You may consider to add P9073 on the basis of P1629.<br>' +
'Please respect the constraints of P9073 and ask <a target="_blank" href="/w/index.php?title=Property_talk:P9073&action=edit§ion=new">here</a> if you are unsure about the value of P9073 to be added.';
}
$( '#useasref_dialog_msg' )
.html(msg)
.css('color','red');
$( '#useasref_dialog' ).dialog( 'open' ); $('.useasref_icon').css('width','16px');
}
else {
$('.pasteref-container').css('pointer-events',''); // enable paste buttons
$('.pasteref-container a').css('opacity',''); // no opacity
mw.notify( 'Reference copied: ' + mw.current_reference.P + ' ' + mw.current_reference.value, {
title: 'UseAsRef - Info',
type: 'info'
});
}
}
function copy_reference ( identifier, external_id, P1810 ) {
// console.log('copy_reference',identifier.attr('id'), external_id); // test
mw.current_reference = {};
mw.current_reference.P = identifier.attr('id');
mw.current_reference.value = external_id;
mw.current_reference.P1810 = P1810;
// P9073 must be a property of mw.current_reference.P; if present, P1629 may help to add P9073
var sparql_query = 'select ?P9073 ?P1629 where \
{ optional { wd:'+ mw.current_reference.P +' wdt:P9073 ?P9073 . } \
optional { wd:'+ mw.current_reference.P +' wdt:P1629 ?P1629 . } }';
makeSPARQLQuery('https://query.wikidata.org/sparql', sparql_query, doneCallback);
return mw.current_reference;
}
function addButton_paste( $identifier ) {
var statements = $($identifier).find('.wikibase-snakview-body'); // qualifiers are statements too
var statement = statements[0]; // add paste button only to the main statement, get rid of qualifiers
$(statement).append(
$( '<div>' )
.attr( 'class', 'pasteref-container' )
.css( {
'float': 'right',
'position': 'relative',
'z-index': 1,
'pointer-events':'none'
} )
.append(
$( '<a>' )
// .text('Paste Ref')
.html('<img class="useasref_icon" src="'+icon_paste+'">')
.css({'opacity':'0.4'})
.attr( {
'href': '#',
'title': 'paste copied ref',
'class': 'pasteref-button',
} )
.on( 'click', function ( event ) {
event.preventDefault();
paste_reference( event.target, mw.current_reference );
} )
)
);
}
function addButton_copy( $identifier ) {
var ids = $identifier.find('a.external');
ids.after( // prepend o append non sembrano utili per la cattura del valore dell'ID
$( '<div>' )
.attr( 'class', 'copyref-container' )
.css( {
'float': 'right',
'position': 'relative',
'z-index': 1,
} )
.append(
$( '<a>' )
.html('<img class="useasref_icon" src="'+icon_copy+'">')
.attr( {
'href': '#',
'title': 'copy this as ref',
'class': 'copyref-button',
} )
.on( 'click', function ( event ) {
event.preventDefault();
var external_id = $(event.target).parents('.wikibase-snakview-value').eq(0).find('a').text();
$('.copyref-container .useasref_icon').css({'border':'', 'padding':''});
$('.pasteref-button img').css({'border':'', 'padding':''}); // sb, 2021-02-13
$(event.target).css({'border':'3px solid green', 'padding':'2px'});
var P1810_a = $(event.target).parents('.wikibase-statementview-mainsnak-container').find('a[title="Property:P1810"]');
var P1810 = $(P1810_a) ? $(P1810_a).parents('div.wikibase-snakview').find('.wikibase-snakview-value').text() : '';
mw.current_reference = copy_reference( $identifier, external_id, P1810 );
} )
)
);
}
function replaceAll(s, s_search, s_replace) {
return s.split(s_search).join(s_replace);
}
function build_up_dialog () {
$( '<div>' )
.attr( 'id', 'useasref_dialog' )
.append(
$( '<p>' )
.attr( 'id', 'useasref_dialog_msg' )
.html('qui messaggio')
)
.dialog( {
dialogClass: 'useasref_dialog',
title: 'Use As Ref' + ' <img class="useasref_icon" src="'+icon_copy+'">'+' <img class="useasref_icon" src="'+icon_paste+'">',
autoOpen: false,
modal: true,
width: 500,
buttons: [ {
id: 'useasref_dialog-button-close',
text: 'Close',
click: function ( event ) {
event.preventDefault();
$( '#useasref_dialog' ).dialog( 'close' );
}
} ]
} );
}
function useasref_init () {
// console.log('init (re)start'); // test
var ids = $('.wikibase-statementgrouplistview>div').get(2); // the block containing identifiers
var div_ids = $(ids).find('>div'); // the divs of each identifier; inside each div, more identifiers can exist: .find('a.external')
// wait for identifiers
if ( div_ids.length === 0 ) {
mw.useasref_retries++;
if (mw.useasref_retries >= mw.useasref_max_retries) {
return; // stop trying
}
setTimeout(function(){ useasref_init(); }, 200);
return;
}
div_ids = div_ids
.not('#P212, #P213, #P214, #P236, #P646, #P2671, #P791, #P957, #P2333, #P7859'); // exclude ID of some properties
/* TODO better solution: use a select
SELECT ?p WHERE {
{ ?p p:P9073/a wdno:P9073 . }
UNION { ?p wdt:P9073 ?value . FILTER (isBlank(?value)) }
}
and add VIAF P214, ISNI P213, WorldCat P7859
*/
div_ids = div_ids.toArray();
$( div_ids ).each( function () {
addButton_copy( $( this ) );
} );
$( '.wikibase-statementview' ) // add paste button to statements
.not($($('.wikibase-statementgrouplistview>div').get(2)).find('.wikibase-statementview')) // do not add paste button to identifiers
.each ( function () {
addButton_paste( $( this ) );
} );
build_up_dialog(); // prepare a dialog, now closed
$( '#identifiers' ).after(' \
<img class="useasref_info" src="'+icon_paste+'"> \
<img class="useasref_info" src="'+icon_copy+'">');
$( '.useasref_info' )
.attr('title','UseAsRef Gadget - Info')
.css({'position':'relative', 'float':'right', 'width':'16px', 'cursor':'pointer'})
.click(function(){
$('#useasref_dialog_msg').html('<div>UseAsRef version 1.0.1 (2021-02-13)<p><a target="_blank" href="/wiki/User:Bargioni/UseAsRef">More info</a></p></div>');
$( '#useasref_dialog' ).dialog( 'open' );
});
$('.useasref_icon').css('width','16px');
$('.useasref_icon').attr('unselectable', 'on').css('user-select', 'none').on('selectstart', false); // prevent selectable
console.log('UseAsRef loaded');
}
// do not apply to items that are properties
if (document.location.href.indexOf('Property:P') > -1) return; // mw.config.values.wgTitle ?
$.when(
mw.loader.using( [
'jquery.spinner', 'jquery.ui', 'mediawiki.api',
'mediawiki.util', 'wikibase.api.RepoApi',
] )
.then( function () {
mw.useasref_retries = 0;
mw.useasref_max_retries = 50;
// icons
icon_warning = 'https://upload.wikimedia.org/wikipedia/commons/d/d9/Warning_sign_font_awesome-red.svg';
icon_copy = 'https://upload.wikimedia.org/wikipedia/commons/1/15/Font_Awesome_5_solid_copy.svg';
icon_paste = 'https://upload.wikimedia.org/wikipedia/commons/4/4d/Font_Awesome_5_solid_file-import.svg';
icon_ok = 'https://upload.wikimedia.org/wikipedia/commons/0/05/Font_Awesome_5_solid_check-circle.svg';
icon_help = '?';
// object to paste
mw.current_reference = {};
// required?
// api = new mw.Api();
// repoApi = new wb.api.RepoApi( api );
} ),
$.ready
)
.then( useasref_init );
} ( mediaWiki, wikibase, jQuery ) );
});