User:Magnus Manske/wd edit.js
Jump to navigation
Jump to search
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.
/*
Allows for editing of Wikidata statements in a Listeria table from within Wikipedia
*/
mw.loader.load( ['jquery.ui'] );
$(document).ready ( function () {
if ( mw.config.get('wgAction') != 'view' ) return ;
var wd_edit = {
t : {
go2wd:"View or edit this property on Wikidata",
set_value:"Set or edit this value",
add_value:"Add a new value for this property",
add:'add',
edit:'edit',
sticky_msg:'Your input has been added to Wikidata. It will become permanent in this table on the next update (within ~24h or manually).',
no_commons_file:'No file with that name on Commons.',
wd_api_fail:'Edit via Wikidata API has failed.'
} ,
init : function () {
var me = this ;
me.lang = mw.config.get('wgPageContentLanguage') ;
} ,
getItemString : function ( i , p ) {
var me = this ;
var key = p=='label' ? 'labels' : 'descriptions' ;
if ( typeof i[key] == 'undefined' ) return '' ;
if ( typeof i[key][me.lang] == 'undefined' ) return '' ;
return i[key][me.lang].value ;
} ,
setDisplayString : function ( o , s , mode ) {
var me = this ;
$('#wd_hover').remove() ;
var note = "<div style='background-color:#FFFF84;font-size:7pt;'>" + me.t.sticky_msg + "</div>" ;
if ( mode == 'replace' ) {
var a = o.find('a') ;
if ( a.length === 0 ) $(o).text(s) ;
else $(a[0]).text(s) ;
$(o).append ( note ) ;
} else if ( mode == 'append' ) {
$(o).append(s+note) ;
}
} ,
getWikidataEditToken : function ( callback ) {
this.doAPI ( {
action: 'query',
meta: 'tokens'
} , function ( d ) {
callback ( d.query.tokens.csrftoken ) ;
} ) ;
} ,
setLabelValue : function ( q , p , s , callback ) {
var me = this ;
var action = '' ;
if ( p == 'label' ) action = 'wbsetlabel' ;
if ( p == 'desc' ) action = 'wbsetdescription' ;
me.editAPI ( {
action:action,
id:q,
language:me.lang,
value:s
} , function ( d ) {
callback ( d ) ;
}) ;
} ,
editAPI : function ( data , callback ) {
var me = this ;
me.getWikidataEditToken ( function ( token ) {
data.token = token ;
me.doAPI ( data , callback ) ;
}) ;
} ,
doAPI : function ( data , callback ) {
data.format = 'json' ;
data.origin = 'https:'+mw.config.get('wgServer') ;
$.ajax( {
url: 'https://www.wikidata.org/w/api.php',
method:'POST',
data: data ,
xhrFields: {
withCredentials: true
},
dataType: 'json'
} ).done( function ( d ) {
// console.log('OK!',d) ;
callback ( d ) ;
} );
} ,
setItemString : function ( i , p , v , o ) {
var me = this ;
me.setLabelValue ( i.title , p , v , function ( d ) {
if ( d.success ) me.setDisplayString ( o , v , 'replace' ) ;
else alert ( me.t.wd_api_fail ) ;
} ) ;
} ,
addPropValueWikidata : function ( q , p , v , o , proptype ) {
// q = 'Q4115189' ; // SANDBOX ITEM FOR TESTING
// console.log ( q , p , v , o , proptype ) ;
var me = this ;
var vv ;
var vs ;
if ( proptype == 'string' ) {
vv = v ;
vs = "<div>"+v+"</div>" ;
} else if ( proptype == 'wikibase-item' ) {
vv = { 'entity-type':'item' , 'numeric-id':v.replace(/\D/g,'') } ;
vs = "<div><a href='//www.wikidata.org/wiki/"+v+"'>"+v+"</a></div>" ;
} else if ( proptype == 'globe-coordinate' ) {
vv = v ; //{"latitude":v.lat,"longitude":v.lon,"globe":"http://www.wikidata.org/entity/Q2","precision":v.prec} ;
vs = "<div>"+v.latitude+"/"+v.longitude+"</div>" ;
} else if ( proptype == 'time' ) {
vv = v ;
vs = "<div>" + v.time + "</div>" ;
} else if ( proptype == 'external-id' ) {
vv = v;
vs = "<div>" + v + "</div>" ;
// } else if ( proptype == 'quantity' ) {
} else if ( proptype == 'commonsMedia' ) {
vv = v ;
vs = "<div>File:" + v + "</div>" ;
} else {
alert ( "addPropValueWikidata : Unknown proptype " + proptype ) ;
}
me.editAPI ( {
action:'wbcreateclaim',
entity:q.toUpperCase(),
snaktype:'value',
property:p.toUpperCase(),
value:JSON.stringify(vv)
} , function ( d ) {
//console.log ( d ) ;
if ( d.success ) me.setDisplayString ( o , vs , 'append' ) ;
else alert ( me.t.wd_api_fail ) ;
}) ;
} ,
// Loads the requested item and passes it as parameter to callback function
loadItem : function ( q , callback ) {
q = q.toUpperCase() ;
$.getJSON ( 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='+q+'&format=json&callback=?' , function ( d ) {
callback ( d.entities[q] ) ;
} ) ;
} ,
showDialogSearchResults : function () {
var me = this ;
var h = '' ;
$.each ( me.dialog_results , function ( k , v ) {
h += "<div class='wb_dialog_option' value='" + k + "' style='margin-top:10px;'>" ;
h += "<b>" + v.label + "</b>" ;
if ( typeof v.desc != 'undefined' ) h += "<br/>" + v.desc ;
h += "</div>" ;
} ) ;
$('#wd_dialog_select').html(h) ;
$('div.wb_dialog_option').click ( function () {
var o = $(this) ;
me.dialog_selection = o.attr('value') ;
$('#wd_dialog_ok').attr("disabled", true);
$('div.wb_dialog_option').css({'background-color':''});
if ( typeof me.dialog_results[me.dialog_selection].value == 'undefined' ) return ;
o.css({'background-color':'#7BA7E1'});
$('#wd_dialog_ok').attr("disabled", false);
} ) ;
if ( me.dialog_results.length == 1 && typeof me.dialog_results[0].value != 'undefined' ) {
me.dialog_selection = 0 ;
$('div.wb_dialog_option').css({'background-color':'#7BA7E1'});
$('#wd_dialog_ok').attr("disabled", false);
}
} ,
dialogValueProcess : function ( s , proptype ) {
var me = this ;
if ( me.last_dialog_search == s ) return ;
me.last_dialog_search = s ;
me.dialog_results = [] ;
me.dialog_selection = undefined ;
$('#wd_dialog_ok').attr("disabled", true);
var rand = Math.random();
me.last_rand = rand ;
if ( proptype == 'wikibase-item' ) {
$.getJSON('https://www.wikidata.org/w/api.php?callback=?',{
action:'wbsearchentities',
search:s,
format:'json',
language:me.lang,
uselang:me.lang,
type:'item',
'continue':0
} , function(d){
if ( me.last_rand != rand ) return ;
$.each ( (d.search||[]) , function ( k , v ) {
me.dialog_results.push ( {label:v.label,desc:v.description,value:v.id} ) ;
} ) ;
me.showDialogSearchResults() ;
} ) ;
} else if ( proptype == 'commonsMedia' ) {
$.getJSON ( 'https://commons.wikimedia.org/w/api.php?callback=?' , {
action:'query',
titles:'File:'+s,
prop:'imageinfo',
iiprop:'url',
iiurlwidth:250,
iiurlheight:250,
format:'json'
} , function ( d ) {
if ( me.last_rand != rand ) return ;
$.each ( d.query.pages , function ( k , v ) {
if ( k == -1 ) {
me.dialog_results.push ( {label:me.t.no_commons_file} ) ;
} else {
var name = v.title.replace(/^[^:]+:/,'') ;
me.dialog_results.push ( {label:name,value:name,desc:"<img src='"+v.imageinfo[0].thumburl+"' />"} ) ;
}
} ) ;
me.showDialogSearchResults() ;
} ) ;
} else {
$.getJSON('https://www.wikidata.org/w/api.php?callback=?',{
action:'wbparsevalue',
values:s,
format:'json',
datatype:proptype,
validate:1
} , function(d){
if ( me.last_rand != rand ) return ;
var x = d.results[0] ;
var out = {} ;
if ( typeof x.valid !== 'undefined' ) {
var l = "??" ;
if ( proptype == 'globe-coordinate' ) l = x.value.latitude+'/'+x.value.longitude ;
if ( proptype == 'time' ) l = x.value.time ;
out = { value : x.value , label:l } ;
} else {
out = { label:x['error-info'] } ;
}
me.dialog_results.push ( out ) ;
me.showDialogSearchResults() ;
} ) ;
}
} ,
getDialogValue : function ( p , proptype , callback ) {
var me = this ;
me.last_dialog_search = '' ;
me.dialog_selection = undefined ;
var h = "<div title='"+me.t.add_value+"' id='wd_dialog'>" ;
h += "<div><form id='wd_dialog_form'><input type='text' id='wd_dialog_input'><input id='wd_dialog_ok' type='submit' value='OK' /></form></div>" ;
h += "<div><div id='wd_dialog_select' style='width:100%;height:350px;overflow:auto;'></div></div>" ;
h += "</div>" ;
$('#wd_dialog').remove() ;
$('body').append(h);
$('#wd_dialog').dialog({ modal: true }) ;
$('#wd_dialog_ok').attr("disabled", true);
$('#wd_dialog_input').keyup ( function () {
var s = $('#wd_dialog_input').val() ;
me.dialogValueProcess ( s , proptype ) ;
} ) ;
$('#wd_dialog_form').submit ( function () {
$('#wd_dialog').dialog( "close" );
if ( typeof me.dialog_selection != 'undefined' ) {
callback ( me.dialog_results[me.dialog_selection].value ) ;
}
return false ;
} ) ;
$('#wd_dialog_input').focus() ;
} ,
// Base function to set/add statement, label, description
addPropValue : function ( o , q , p ) {
var me = this ;
me.loadItem ( q , function ( i ) {
if ( p == 'label' || p == 'desc' ) {
var s = me.getItemString(i,p) ;
var v = prompt ( me.t.set_value , s ) ;
if ( v !== null && v != s ) me.setItemString ( i , p , v , o ) ;
return ;
} else if ( p.match(/^[pP]\d+$/) ) {
me.loadItem ( p , function ( pi ) {
// console.log ( pi ) ;
var proptype = pi.datatype ;
if ( proptype == 'string' || proptype == 'external-id' ) {
var v = prompt ( me.t.add_value , '' ) ;
if ( v == null || v == '' ) return ;
me.addPropValueWikidata ( q , p , v , o , proptype ) ;
} else if ( proptype == 'wikibase-item' || proptype == 'globe-coordinate' || proptype == 'time' || proptype == 'commonsMedia' ) {
var v = me.getDialogValue ( p , proptype , function ( v ) {
me.addPropValueWikidata ( q , p , v , o , proptype ) ;
} ) ;
// } else if ( proptype == 'quantity' ) {
} else {
alert ( "Apologies, type " + proptype + " is not supported yet!" ) ;
}
} ) ;
}
} ) ;
return false ;
} ,
prep4edit : function ( o_orig , q , p ) {
var me = this ;
$(o_orig).hover(function(){
$('#wd_hover').remove() ;
var o = $(this) ;
var off = o.offset() ;
var ry = parseInt(off.top) ;
var h = "<div style='position:absolute;test-align:right;border-radius:3px;background-color:#EEE;border:1px solid #DDD;padding:2px;box-shadow: 10px 10px 5px #888888;z-index:5;top:"+ry+"px' id='wd_hover'>" ;
var m = p.match(/^p(\d+)$/) ;
var title = me.t.set_value ;
if ( m !== null ) title = me.t.add_value ;
var label = me.t.add ;
if ( m === null ) label = me.t.edit ;
h += "<div><a href='#' id='wd_hover_add' title='"+title+"'>["+label+"]</a></div>" ;
var target = q ;
if ( m !== null ) target += "#" + p.toUpperCase() ;
h += "<div><a href='//www.wikidata.org/wiki/"+target+"' title='"+me.t.go2wd+"'>[WD]</a></div>" ;
h += "</div>" ;
$('body').append(h) ;
$('#wd_hover').css ( { left:parseInt(off.left)+parseInt(o.width())-parseInt($('#wd_hover').width()) } ) ;
$('#wd_hover_add').click ( function () {
$('#wd_hover').remove() ;
me.addPropValue ( o , q , p ) ;
return false ;
})
},function(){
$('#wd_hover').remove() ;
}) ;
}
} ;
// Prepare cells
wd_edit.init() ;
$('table.wd_can_edit').each ( function () {
var table = $(this) ;
table.find('tr').each ( function () {
var classList = this.className.split(/\s+/);
var q ;
$.each ( classList , function (k,v) {
var m = v.match(/^wd_q(\d+)/);
if ( m === null ) return ;
q = 'Q'+m[1];
});
if ( typeof q == 'undefined' ) return ;
$(this).find('td').each ( function () {
var classList = this.className.split(/\s+/);
var me = this ;
$.each ( classList , function (k,v) {
var m = v.match(/^wd_(.+)/);
if ( m === null ) return ;
wd_edit.prep4edit ( me , q , m[1] ) ;
} ) ;
}) ;
});
});
});