User:Bargioni/PrefRank.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)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/*
Wikidata gadget to set preferred rank to P19, P20, P569, P570
or other properties (see config).
Basic idea: User:Epìdosis
Written by: User:Bargioni, Jan. 2024
____ __ ____ _
| _ \ _ __ ___ / _| _ \ __ _ _ __ | | __
| |_) | '__/ _ \ |_| |_) / _` | '_ \| |/ /
| __/| | | __/ _| _ < (_| | | | | <
|_| |_| \___|_| |_| \_\__,_|_| |_|_|\_\ 0.1
Logo obtained from
https://patorjk.com/software/taag/#p=author&f=Standard&t=PrefRank
*/
/* jshint esversion: 6 */
mw.loader.using([ 'jquery.ui' ]).then(function () {
$( function($) { // our workspace
function save_pref_rank(claim_id, Qmotivation) {
// console.log('saving claim', claim_id, Qmotivation); // test
// refresh claim, modify and save it
var jq_claim_id = '#'+claim_id.replace(/\$/,'\\$'); // escape $ for jQuery reasons
$.getJSON(`https://www.wikidata.org/w/api.php?action=wbgetclaims&claim=${claim_id}&format=json`, function(CC) {
try {
// console.log(CC, claim_id, Qmotivation); // test
var P = Object.keys(CC.claims)[0];
var C = CC.claims[P][0]; // C is the claim to be modified
C.rank = 'preferred';
// add qualifier P7452 with value Qmotivation, unless Q0
if (Qmotivation != 'Q0') {
var motivation = Qmotivation.replace(/Q/,'');
if (!C.hasOwnProperty('qualifiers')) {
C.qualifiers = {};
C['qualifiers-order'] = [];
}
C.qualifiers["P7452"] = [
{
"property" : "P7452",
"snaktype" : "value",
"datavalue" : {
"value" : {
"entity-type": "item",
"numeric-id": motivation,
"id": Qmotivation
},
"type": "wikibase-entityid"
},
"datatype" : "wikibase-item"
}
];
C['qualifiers-order'].push("P7452");
}
// console.log('going to save claim',C); // test
let api = new mw.Api()
let token = mw.user.tokens.values.csrfToken;
api.post({
'action' : 'wbsetclaim',
'claim' : JSON.stringify(C),
'format' : 'json',
'token' : token,
'summary' : "Set preferred value using [[User:Bargioni/PrefRank|PrefRank]]"
})
.then(function(aw) {
let P = aw.claim.mainsnak.property;
mw.notify(`Preferred value of ${P} saved successfully. Please reload the page to see this change.`, {title: 'PrefRank', type: 'success'});
$(jq_claim_id).fadeOut(200, function(){
$(this).css('background', '#F0FFF0').fadeIn(1200);
});
})
.catch(function(aw) {
console.log('PrefRank server side error',aw);
mw.notify("A server side error occurred while saving the preferred value.", {title: 'PrefRank', type: 'error'});
$(jq_claim_id).fadeOut(200, function(){
$(this).css('background', 'pink').fadeIn(1200);
});
});
}
catch(e){
console.log('PrefRank: client side error while saving preferred value',e);
mw.notify(`A client side error occurred while saving the preferred value: ${e}`, {title: 'PrefRank', type: 'error'});
$(jq_claim_id).fadeOut(200, function(){
$(this).css('background', 'pink').fadeIn(1200);
});
}
});
}
function setup_pref_rank_motivation_dialog() {
$('body').append('<div style="display:none" id="PrefRank_dialog" title=""></div>');
$( "#PrefRank_dialog" ).dialog({
autoOpen: false,
modal: true,
buttons: [
{
text: "OK",
click: function() {
var claim_id = $('#claim_id').val();
var Qmotivation = $('#PrefRank_dialog input[name="motivation"]:checked').attr('id');
// colorare valore pref o altra cosa, o farlo a cosa fatta TODO
save_pref_rank( claim_id, Qmotivation );
$( this ).dialog( "close" );
}
}
]
});
$('#PrefRank_dialog').on('dialogclose', function(event) {
mw.PrefRank.chosen_value.css('background-color',''); // disattiva background del valore scelto
mw.PrefRank.chosen_value = '';
});
$('#PrefRank_dialog').parent().css('font-size','1.0em');
let info_icon = 'https://upload.wikimedia.org/wikipedia/commons/e/e4/Infobox_info_icon.svg';
$('#PrefRank_dialog').siblings('.ui-dialog-buttonpane').find('.ui-dialog-buttonset').before(
`<span style="position:relative; top:15px; color:gray"><a href="https://www.wikidata.org/w/index.php?title=User:Bargioni/PrefRank" style="color:gray" target="_blank">PrefRank 0.1 <img src="${info_icon}" width="22px"></a></span>`
);
}
function get_property(P) {
let item = mw.PrefRank.item.entities[qid];
let claims = item.claims[P] ? item.claims[P] : [];
return claims;
}
function get_property_values(P) {
// return the values of property P
var values = [];
let props = get_property(P);
for (var i = 0; i < props.length; i++) {
var v = props[i].mainsnak.datavalue;
if (v) {
if (v.type == 'time') { values.push( v.value.time ) }
if (v.type == 'wikibase-entityid') { values.push( v.datavalue ? v.datavalue.value.id : v.value.id ) }
if (v.type == 'string') { values.push( v.datavalue ? v.datavalue.value : v.value ) }
}
}
return values;
}
function setup_pref_rank(apply_to_claims, P) {
// console.log('apply PrefRank button to ',P, apply_to_claims); // test
for (var i=0; i < apply_to_claims.length; i++) {
var claim = apply_to_claims[i];
var claim_id = claim.id;
var jq_claim_id = '#'+claim_id.replace(/\$/,'\\$'); // escape $ for jQuery reasons
if (mw.PrefRank.config.button == 'special_icon') {
var pref_rank_icon = `<img class="pref_rank_icon"
title="${mw.PrefRank.config.strings[mw.PrefRank.user_lang] ? mw.PrefRank.config.strings[mw.PrefRank.user_lang].tooltip : mw.PrefRank.config.strings.en.tooltip}"
width="${mw.PrefRank.config.special_icon_img_width}"
alt="[PrefRank button]"
src="${mw.PrefRank.config.special_icon_img_src}"
data_prop="${claim_id}"/>`;
$(jq_claim_id).find('.wikibase-toolbar-container.wikibase-edittoolbar-container').prepend('<span style="float:left">'+pref_rank_icon+'</span>')
}
if (mw.PrefRank.config.button == 'click_on_rank_icon') {
$(jq_claim_id).find('.ui-icon-rankselector')
.css({'cursor':'pointer', 'border':'2px solid lightgreen'})
.addClass('pref_rank_icon')
.attr('title', `${mw.PrefRank.config.strings[mw.PrefRank.user_lang] ? mw.PrefRank.config.strings[mw.PrefRank.user_lang].tooltip : mw.PrefRank.config.strings.en.tooltip}`)
.attr('data_prop', claim_id);
}
}
}
function apply_pref_rank_to_property(P) {
// console.log('apply_pref_rank_to_property',P); // test
let claims = get_property(P);
// console.log(P, claims); // test
var apply_to_claims = [];
for (var i = 0; i < claims.length; i++) {
var claim = claims[i];
// console.log(claim) // test
if (claim.rank == 'preferred') return false; // do not apply, we have a pref'd value
if (claim.rank == 'normal') apply_to_claims.push(claim);
}
if (apply_to_claims.length > 1) {
setup_pref_rank(apply_to_claims, P); // apply
return true;
}
return false; // do not apply, no more than 1 value
}
function setup_options() {
var motivations = [];
var strings = mw.PrefRank.config.strings[ mw.PrefRank.user_lang ] || mw.PrefRank.config.strings.en;
var motivations = mw.PrefRank.config.motivations;
var motivation_labels = strings.motivation_labels;
var html = []; var check = 'checked="checked"';
for (var i=0; i < motivations.length; i++) {
var m = motivations[i];
var ml = motivation_labels[i] || '?';
html.push(`<input ${check} type="radio" id="${m}" name="motivation" value="${m}">
<label for="${m}">${ml}</label><br/>`);
check = '';
}
return html.join('');
}
function apply_pref_rank() {
for (var i = 0; i < mw.PrefRank.config.properties.length; i++) {
var P = mw.PrefRank.config.properties[i];
apply_pref_rank_to_property(P);
}
if ($('.pref_rank_icon').length) {
setup_pref_rank_motivation_dialog();
$('.pref_rank_icon')
.css('cursor','pointer')
.click(function(event){
event.preventDefault();
var claim_id = $(this).attr('data_prop');
var h_claim_id = `<input id="claim_id" type="hidden" value="${claim_id}"/>`;
var options = setup_options();
var P = $(this).closest('.wikibase-statementgroupview.listview-item').attr('id');
var chosen_value;
if (mw.PrefRank.config.button == 'special_icon') {
chosen_value = $( $(this).closest('div') ).find('.wikibase-snakview-value.wikibase-snakview-variation-valuesnak').eq(0);
}
else {
chosen_value = $(this).closest('div.wikibase-statementview').find('.wikibase-snakview-value.wikibase-snakview-variation-valuesnak').eq(0);
}
chosen_value.css('background-color',mw.PrefRank.config['background-color']);
mw.PrefRank.chosen_value = chosen_value;
var strings = mw.PrefRank.config.strings[ mw.PrefRank.user_lang ] || mw.PrefRank.config.strings.en;
var comment = strings.dialog_comment1 + ' "' +
chosen_value.text() +
'" ' + strings.dialog_comment2 +
' ' + P + '. ' +
strings.dialog_comment3;
$( "#PrefRank_dialog" )
.dialog( "option", "title", strings.dialog_title )
.html(comment + '<p style="padding-top:5px">' + options + '</p>' + h_claim_id);
if (!event.originalEvent.shiftKey) {
// open the dialog unless shift was pressed
$( "#PrefRank_dialog" ).dialog('open');
}
else {
// save the preferred value using the first i.e. the default motivation
$('#PrefRank_dialog').parent().find('.ui-dialog-buttonpane button').click();
}
});
// disable the pref_rank_icon when user edits the claim as usual; this will allow to manually modify the rank itself, e.g. for deprecating
$('.wikibase-edittoolbar-container').click(function(){
$(this).parent().find('.pref_rank_icon').unbind('click');
$(this).parent().find('.pref_rank_icon').css('border','');
$(this).parent().find('.pref_rank_icon').removeClass('pref_rank_icon');
});
}
}
function pref_rank_check_item_instances() {
let item_instances = get_property_values('P31');
let config_instances = mw.PrefRank.config.instances;
let instances = item_instances.filter(e => config_instances.includes(e));
if (instances.length == 0) {
console.log('PrefRank: no instances, exit');
return false;
}
return true;
}
function get_config_and_item( qid ) {
if (mw.PrefRank.config === undefined) {
mw.PrefRank.retries++;
if (mw.PrefRank.retries > mw.PrefRank.max_retries) {
alert("Unable to load config.\nImpossible to activate gadget PrefRank");
return;
}
setTimeout(function(){get_config_and_item(qid)}, 200); // try (again)
}
else {
console.log('PrefRank config loaded'); // test
let url = 'https://www.wikidata.org/wiki/Special:EntityData/'+qid+'.json';
$.getJSON(url, function(R) {
mw.PrefRank.item = R;
if ( pref_rank_check_item_instances() ) apply_pref_rank();
});
}
}
// ========== MAIN
// check if we are viewing an item
var qid = mw.config.get( 'wbEntityId' );
if ( !qid ) return;
console.log('PrefRank gadget loaded');
if (mw.PrefRank === undefined) mw.PrefRank = {};
mw.PrefRank.qid = qid;
mw.PrefRank.user_lang = wb.getUserLanguages()[0];
mw.PrefRank.retries = 0;
mw.PrefRank.max_retries = 50;
mw.PrefRank.chosen_value = '';
get_config_and_item(qid);
}); // end of our workspace
}); // end of mw.loader.using