User:Magnus Manske/sdc tool.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
Documentation for this user script can be added at User:Magnus Manske/sdc tool. |
- Report page listing warnings and errors.
/*
(c) 2019 by [[User:Magnus Manske]]. GPLv3 or later.
This tool lets you quickly add statements for Structured Data on Commons (SDC) to (selected) files on galleries, category pages, and serach results.
Demo video: https://www.youtube.com/watch?v=RIjXRJNcbL0
Demo video 2 (item creation/Wikidata Infobox): https://www.youtube.com/watch?v=vvSimZSD_IU
To use this script, add it to your [https://commons.wikimedia.org/wiki/Special:MyPage/common.js common.js page], like so:
importScript('User:Magnus Manske/sdc_tool.js') ;
Activate by clicking on the "SDC" link in the box in the lower-right corner, or by pressing S with (Alt/Ctrl/whatever your browser uses).
*/
$.when(mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'mediawiki.ForeignApi']), $.ready).done ( function () {
// Dialog
function SDCdialog( config ) {
SDCdialog.super.call( this, config );
}
OO.inheritClass( SDCdialog, OO.ui.Dialog );
// Specify a name for .addWindows()
SDCdialog.static.name = 'SDCdialog';
// Specify a title statically (or, alternatively, with data passed to the opening() method).
SDCdialog.static.title = 'Find a target item for SDC';
SDCdialog.prototype.update_results = function () {
let html = "" ;
$.each ( this.results , function ( result_id , v ) {
html += "<div style='margin:2px;padding:2px;border:1px solid #DDD;border-radius:3;display:flex;'>" ;
html += "<div style='margin-right:0.2rem;'><input style='color:green;font-size:1.5em;' class='sdc_dialog_cegision_button' result='" ;
html += result_id+"' type='button' value='✓' /></div>" ;
html += "<div>" ;
html += "<div><b class='result_label' result='"+result_id+"'></b> <small>[<a href='https://www.wikidata.org/wiki/"+v.q+"' target='_blank'>"+v.q + "</a>]</small></div>" ;
html += "<div class='result_description' result='"+result_id+"'></div>" ;
html += "</div>" ;
html += "</div>" ;
} ) ;
if ( html === '' ) html = '<div style="margin:2px;"><i>No results found on Wikidata</i></div>' ;
$('#sdc_dialog_results').html(html);
$.each ( this.results , function ( result_id , v ) {
$('#sdc_dialog_results b.result_label[result="'+result_id+'"]').text(v.label);
$('#sdc_dialog_results div.result_description[result="'+result_id+'"]').text(v.description);
} ) ;
let me = this ;
$('.sdc_dialog_cegision_button').click(function(){
let result_id = $(this).attr('result')*1 ;
console.log(me.results);
let item = me.results[result_id] ;
me.on_decision(item);
});
}
SDCdialog.prototype.get_time_claim_for_year = function ( property , year ) {
let value = {
"time": "+"+year+"-01-01T00:00:00Z",
"timezone": 0,
"before": 0,
"after": 0,
"precision": 9,
"calendarmodel": "http://www.wikidata.org/entity/Q1985727"
} ;
let claim = {mainsnak:{snaktype:"value",property:property,datavalue:{value:value,type:'time'}},type:"statement",rank:"normal"} ;
return claim ;
}
SDCdialog.prototype.create_new_item_for_category = function () {
let me = this ;
let label = mw.config.values.wgTitle ;
let data = {
claims:[{mainsnak:{snaktype:"value",property:'P373',datavalue:{value:label,type:'string'}},type:"statement",rank:"normal"}],
labels:{en:{language:"en",value:label}}
} ;
let summary = 'SDC: created item based on Commons category ' + label ;
// If the page exists, add sitelink
if ( mw.config.values.wgArticleId !== 0 ) {
data.sitelinks = {"commonswiki":{site:"commonswiki",title:mw.config.values.wgPageName}} ;
}
let is_human = false ;
let gender = '' ;
$.each ( mw.config.values.wgCategories , function ( dummy , category ) {
let m = category.match ( /^(\d{3,4}) births$/ ) ;
if ( m !== null ) {
data.claims.push ( me.get_time_claim_for_year ( 'P569' , m[1] ) ) ;
is_human = true ;
}
m = category.match ( /^(\d{3,4}) deaths$/ ) ;
if ( m !== null ) {
data.claims.push ( me.get_time_claim_for_year ( 'P570' , m[1] ) ) ;
is_human = true ;
}
if ( category.match ( /^Female / ) !== null ) gender = 'Q6581072' ;
if ( category.match ( /^Male / ) !== null ) gender = 'Q6581097' ;
} ) ;
if ( gender !== '' ) {
let value = {'entity-type':'item',id:gender} ;
let claim = {mainsnak:{snaktype:"value",property:'P21',datavalue:{value:value,type:'wikibase-entityid'}},type:"statement",rank:"normal"} ;
data.claims.push ( claim ) ;
is_human = true ;
}
if ( is_human ) {
let value = {'entity-type':'item',id:'Q5'} ;
let human = {mainsnak:{snaktype:"value",property:'P31',datavalue:{value:value,type:'wikibase-entityid'}},type:"statement",rank:"normal"} ;
data.claims.push ( human ) ;
}
sdc.get_wikidata_token ( function ( token ) {
let params = {
action:'wbeditentity',
new:'item',
data:JSON.stringify(data),
token:token,
summary:summary,
format:'json'
} ;
let api = new mw.ForeignApi( 'https://www.wikidata.org/w/api.php' );
api.post(params).done(function(d) {
if ( d.success != 1 ) {
console.log ( d ) ;
alert ( "Something went wrong with item creation, see JS console" ) ;
return ;
}
let q = d.entity.id ;
let item = {q:q,label:label,description:''} ;
me.on_decision(item);
} ) ;
} );
}
/*
// Obsolete, but keeping code around in case of mw issues...
SDCdialog.prototype.get_qs_creation = function () {
let me = this ;
let commands = [ "CREATE" ] ;
commands.push ( "LAST\tLen\t\""+mw.config.values.wgTitle+"\"" ) ;
commands.push ( "LAST\tP373\t\""+mw.config.values.wgTitle+"\"" ) ;
let is_human = false ;
$.each ( mw.config.values.wgCategories , function ( dummy , category ) {
let m = category.match ( /^(\d{3,4}) births$/ ) ;
if ( m !== null ) {
commands.push ( "LAST\tP569\t+"+m[1]+"-01-01T00:00:00Z/9") ;
is_human = true ;
}
m = category.match ( /^(\d{3,4}) deaths$/ ) ;
if ( m !== null ) {
commands.push ( "LAST\tP570\t+"+m[1]+"-01-01T00:00:00Z/9") ;
is_human = true ;
}
} ) ;
if ( is_human ) commands.push ( "LAST\tP31\tQ5") ;
return commands.join("\n") ;
}
*/
// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
SDCdialog.prototype.initialize = function () {
// Call the parent method.
SDCdialog.super.prototype.initialize.call( this );
// Create and append a layout and some content.
this.content = new OO.ui.PanelLayout( {
padded: true,
expanded: false
} );
let html = "<p>";
html += "<div>Enter a search query for Wikidata items</div>" ;
html += "<div><input type='text' id='sdc_dialog_query' style='width:100%' placeholder='search query' /></div>" ;
html += "<div id='sdc_dialog_results' style='height:10rem;overflow:auto;'></div>" ;
if ( mw.config.values.wgNamespaceNumber == 14 ) {
html += "<div><i>or</i> <span id='create_new_item_container'></span></div>" ;
}
html += "</p>" ;
this.content.$element.append( html );
this.$body.append( this.content.$element );
// Create a new item based on the category
if ( mw.config.values.wgNamespaceNumber == 14 ) {
//let qs = this.get_qs_creation() ;
//console.log(qs);
//let url = "https://tools.wmflabs.org/quickstatements/api.php?action=import&format=v1&temporary=1&openpage=1&data="+encodeURIComponent(qs) ;
//let button_create_new_item = new OO.ui.ButtonWidget( { label: 'create new item based on this category in QuickStatements',href:url,target:'_blank' } ) ;
let button_create_new_item = new OO.ui.ButtonWidget( { label: 'create new item based on this category',href:'#' } ) ;
$('#create_new_item_container ').html(button_create_new_item.$element);
$('#create_new_item_container a.oo-ui-buttonElement-button').click(function(){me.create_new_item_for_category();});
}
this.results = [] ;
let me = this ;
me.query_counter = 0 ;
me.last_query = '' ;
$('#sdc_dialog_query').keyup(function(){
me.run_query() ;
});
};
SDCdialog.prototype.run_query = function () {
let me = this ;
let query = $('#sdc_dialog_query').val();
me.results = [] ;
if ( query=='' || query==me.last_query ) return ;
me.last_query = query ;
me.query_counter++ ;
let qc = me.query_counter ;
var wgUserLanguage = mw.config.get('wgUserLanguage')
$.getJSON('https://www.wikidata.org/w/api.php?callback=?',{
action:'wbsearchentities',
search:query,
language:wgUserLanguage,
limit:50,
type:'item',
format:'json'
},function(d){
if ( me.query_counter != qc ) return ; // New query was started while this one was running
$(d.search).each(function(k,v){
me.results.push({q:v.id,label:v.label,description:v.description||''});
});
me.update_results();
});
}
// Override the getBodyHeight() method to specify a custom height (or don't to use the automatically generated height).
SDCdialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight( true );
};
var sdc = {
// Properties allowed to set; must be of 'Wikidata item' type
properties : {
P180 : 'depicts' ,
P921 : 'main subject',
P195 : 'collection' ,
P793 : 'significant event' ,
P1071 : 'location of creation' ,
P7108 : 'location of the point of view' ,
P5961 : 'depicted part' ,
P6243 : 'digital representation of',
P8058 : 'symbol of' ,
} ,
exclude_files:['Gtk-dialog-info-14px.png','Reasonator_logo_proposal_no_background.png'],
is_stopped : true,
active : false,
dialog: new SDCdialog( { size: 'medium' } ),
windowManager: new OO.ui.WindowManager(),
mid_cache:[],
mid2file:[],
media_items:[],
wikidata_items_to_load:[],
wikidata_item_labels:[],
target_item : {
q:'',
label:'',
description:''
},
init : function () {
if ( mw.config.values.wgNamespaceNumber == 6 ) return ; // Not for single images
if ( $('a.image, a.mw-file-description').length == 0 ) return ; // No possible thumbnails
let me = this ;
me.dialog.on_decision = me.set_target_item;
$( document.body ).append( me.windowManager.$element );
me.windowManager.addWindows( [ me.dialog ] );
me.show_main_element();
me.try_guess_main_item();
//me.toggle_main(); // Auto-open
} ,
try_guess_main_item : function () {
let me = this ;
if ( typeof wgWikibaseItemId == 'undefined' || wgWikibaseItemId == '' ) return ;
me.try_set_main_item(wgWikibaseItemId);
} ,
try_set_main_item : function (q) {
let me = this ;
me.wikidata_items_to_load=[q] ;
me.load_wikidata_items(function(){
$.getJSON("https://www.wikidata.org/w/api.php?callback=?&action=wbgetentities&format=json&ids="+q,function(d){
let item = (d.entities||{})[q] ;
if ( typeof item == 'undefined' ) return ;
if ( me.does_item_have_property_target(item,'P31','Q4167836') ) {
let statement = ((item.claims||item.statements||{}).P301||[])[0] ;
if ( typeof statement == 'undefined' ) return ; // No "category's main topic"
let target_id = (((statement.mainsnak||{}).datavalue||{}).value||{}).id ;
if ( typeof target_id != 'undefined' && target_id != q ) me.try_set_main_item(target_id);
return ;
}
let label = $(me.wikidata_item_labels[q]).text();
me.set_target_item({q:q,label:label,description:''});
});
});
} ,
update_main_position : function () {
let bottom = $('#cat_a_lot_toggle').length>0 ? 30 : 0 ;
$('#sdc_main').css({bottom:bottom+'px'})
} ,
show_action_button : function () {
let me = this ;
var action_button = new OO.ui.ButtonWidget( {
label: 'Set '+me.get_property()+' to '+me.target_item.q,
href: '#',
flags: 'progressive'
} );
$('#sdc_action_button_container').html(action_button.$element);
$('#sdc_action_button_container a.oo-ui-buttonElement-button').click(function(){
if ( $('input.sdc_checkbox:checked').length == 0 ) {
alert("No files selected");
return false ;
}
me.is_stopped = false ;
me.show_action_stop_button();
me.edit_next();
return false;
});
} ,
show_wikidata_infobox_button : function () {
let me = this ;
if ( mw.config.values.wgNamespaceNumber != 14 ) return ; // Categories only
if ( $('#wdinfobox').length > 0 ) return ; // Already has infobox
var wikidata_infobox_button = new OO.ui.ButtonWidget( {
label: 'Add Wikidata Infobox for '+me.target_item.q,
href: '#',
flags: 'progressive'
} );
$('#sdc_add_wikidata_infobox_button').html(wikidata_infobox_button.$element);
$('#sdc_add_wikidata_infobox_button a.oo-ui-buttonElement-button').click(function(){
//let wikitext = '{{Wikidata Infobox|qid='+me.target_item.q+'}}\n' ; // old syntax
let wikitext = '{{Wikidata Infobox}}\n' ;
let summary = 'SDC: added '+wikitext ;
$('#sdc_add_wikidata_infobox_button').html('<i>Editing...</i>');
me.get_token ( function ( token ) {
let params = {
action:'edit',
title:mw.config.values.wgPageName,
prependtext:wikitext,
token:token,
summary:summary,
format:'json'
} ;
$.post('/w/api.php',params,function(d){
if ( (d.edit||{}).result != 'Success' ) {
console.log(d);
alert ( "Something went wrong with the edit, see JS console" ) ;
return ;
}
let html = "<div id='wdinfobox' style='background-color:#d5fdf4'><tt>"+wikitext+"</tt> was added, reload page to show</div>" ;
$('#bodyContent').prepend(html);
$('#sdc_add_wikidata_infobox_button').html('');
},'json');
} );
return false;
});
} ,
show_action_stop_button : function () {
let me = this ;
var action_button = new OO.ui.ButtonWidget( {
label: 'Stop editing',
href: '#',
flags: 'destructive'
} );
$('#sdc_action_button_container').html(action_button.$element);
$('#sdc_action_button_container a.oo-ui-buttonElement-button').click(function(){
me.is_stopped=true;
$('#sdc_action_button_container').html("<i>Stopping edits...</i>");
return false;
});
} ,
set_prominent_checkbox : function ( state ) {
$('#sdc_prominent').prop( "checked", state );
} ,
edit_next : function () {
let me = this ;
if ( me.is_stopped ) return me.show_action_button(); // User stopped this
let cbs = $('input.sdc_checkbox:checked') ;
if ( cbs.length == 0 ) { // All done
me.set_prominent_checkbox ( false ) ;
return me.show_action_button();
}
let cb = $(cbs.get(0)) ;
let file = decodeURIComponent(cb.attr('file')) ;
if ( typeof file == 'undefined' ) { // All done
me.set_prominent_checkbox ( false ) ;
return me.show_action_button();
}
me.get_mediainfo_id_for_file ( file , function ( mediainfo_id ) {
me.add_item_statement_to_item(mediainfo_id,me.get_property(),me.target_item.q,me.is_prominent(),function(ok){
// TODO check ok
cb.attr('checked', false);
cb.prop('checked', false);
me.edit_next();
//delete me.media_items[mediainfo_id] ;
me.load_media_items([mediainfo_id]);
});
} ) ;
} ,
is_prominent : function() {
return $('#sdc_prominent').is(":checked");
} ,
// `file` WITHOUT File: prefix!
get_mediainfo_id_for_file : function ( file , callback ) {
let me = this ;
if ( typeof me.mid_cache[file] != 'undefined') {
return callback ( me.mid_cache[file] ) ;
}
$.get('/w/api.php',{
action:'query',
prop:'info',
titles:"File:"+file,
format:'json'
},function(d){
let mid = -1 ;
$.each ( d.query.pages , function ( page_id , page_info ) { mid = page_id } ) ;
if ( mid == -1 ) mid = '' ;
else mid = 'M'+mid ;
me.mid_cache[file] = mid ;
callback(mid);
},'json');
} ,
get_wikidata_token : function ( callback ) {
let params = { action : 'query' , meta : 'tokens' , format : 'json' } ;
let api = new mw.ForeignApi( 'https://www.wikidata.org/w/api.php' );
api.post(params).done(function(d) {
callback(d.query.tokens.csrftoken);
} ) ;
} ,
get_token : function ( callback ) {
$.post ( '/w/api.php' , {
action : 'query' ,
meta : 'tokens' ,
format : 'json' ,
} , function ( d ) {
callback(d.query.tokens.csrftoken);
} ) ;
} ,
does_item_have_property_target : function ( item , property , target_item_id ) {
let statement_present = false ;
$.each ( ((item.statements||item.claims||{})[property]||[]) , function ( dummy , statement ) {
if ( ((((statement||{}).mainsnak||{}).datavalue||{}).value||{}).id == target_item_id ) {
statement_present = true ;
}
} ) ;
return statement_present ;
} ,
add_item_statement_to_item : function ( item_id , property , target_item_id , prominent , callback ) {
let me = this ;
let value = {'entity-type':'item',id:target_item_id} ;
let data = {claims:[{mainsnak:{snaktype:"value",property:property,datavalue:{value:value,type:'wikibase-entityid'}},type:"statement",rank:"normal"}]} ;
let summary = 'SDC: added [[d:Special:EntityPage/'+property+']] => [[d:Special:EntityPage/'+target_item_id+']]' ;
if ( prominent ) {
data.claims[0].rank = 'preferred' ;
summary += ', prominent' ;
}
// Check if statement already present
if ( typeof me.media_items[item_id] != 'undefined' ) {
if ( me.does_item_have_property_target(me.media_items[item_id],property,target_item_id) ) return callback(true);
}
me.get_token ( function ( token ) {
let params = {
action:'wbeditentity',
id:item_id,
data:JSON.stringify(data),
token:token,
summary:summary,
format:'json'
} ;
$.post('/w/api.php',params,function(d){
callback(true);
},'json');
} );
} ,
set_target_item : function ( item ) {
let me = sdc ;
me.target_item = item ;
let html = "" ;
html += "<small>Target item: [<a href='https://www.wikidata.org/wiki/"+item.q+"' target='_blank'>"+item.q+"</a>]</small><br/><div id='sdc_target_item_label'></div>";
html = "<div style='margin:0.2rem;'>"+html+"</div>" ;
$('#sdc_target_item_display').html(html).show();
$('#sdc_target_item_label').text(item.label);
me.show_action_button();
me.show_wikidata_infobox_button();
me.update_main_position();
me.windowManager.closeWindow( me.dialog );
} ,
get_property : function () {
return $('#sdc_property').val();
} ,
open_dialog : function () {
this.windowManager.openWindow( this.dialog );
if ( $('#sdc_dialog_query').val() == '' ) {
$('#sdc_dialog_query').val(mw.config.values.wgTitle) ;
$('#sdc_dialog_query').keyup();
}
setTimeout(function(){$('#sdc_dialog_query').focus()},500);
} ,
show_main_element : function () {
let me = this ;
let html = "<div id='sdc_main' style='position:fixed;right:0px;bottom:0px;background-color:#FEF6E7;box-shadow:0 2px 4px rgba(0,0,0,0.5);font-size:.75em;padding:5px;'>" ;
html += "<a href='#' id='sdc_main_button' accesskey='s' title='Structured Data on Commons tagger [shortcut:S]'>SDC</a>" ;
html += "<div id='sdc_options' style='display:none'>" ;
html += "<div><span id='sdc_cb_all'></span> <span id='sdc_cb_toggle'></span> <span id='sdc_cb_none'></span></div>" ;
/*
html += "<div>Check " ;
html += "<a href='#' id='sdc_cb_all'>all</a> | " ;
html += "<a href='#' id='sdc_cb_toggle'>toggle</a> | " ;
html += "<a href='#' id='sdc_cb_none'>none</a>" ;
html += "</div>" ;
*/
html += "<div style='margin:0.2em;'>Property "
html += "<select id='sdc_property'>" ;
$.each ( me.properties , function ( property , label ) {
html += "<option value='"+property+"'" ;
if ( property == 'P180' ) html += ' selected' ;
html += ">"+label+" ["+property+"]</option>" ;
} ) ;
html += "</select>" ;
html += "</div>" ;
html += "<div id='sdc_target_item' style='margin:2px;padding:2px;border:1px solid #DDD;border-radius:3px'>";
html += "<div id='sdc_target_item_display' style='display:none;'></div>" ;
html += "<div id='sdc_target_item_button' style='text-align:center;'></div>" ;
html += "<div id='sdc_add_wikidata_infobox_button' style='text-align:center;'></div>" ;
html += "</div>" ;
html += "<div id='sdc_action' style='text-align:center'>" ;
html += "<div><label><input type='checkbox' id='sdc_prominent' /> Prominent</label></div>" ;
html += "<div id='sdc_action_button_container'><i>Set a target item to perform an action</i></div>" ;
html += "</div>" ;
html += "</div>" ;
html += "</div>" ;
$('body').append(html);
$('#sdc_main_button').click(function(){ me.toggle_main(); return false; });
let button_all = new OO.ui.ButtonWidget( { label: 'All',href: '#' } ) ;
let button_toggle = new OO.ui.ButtonWidget( { label: 'Toggle',href: '#' } ) ;
let button_none = new OO.ui.ButtonWidget( { label: 'None',href: '#' } ) ;
$('#sdc_cb_all ').html(button_all.$element);
$('#sdc_cb_toggle').html(button_toggle.$element);
$('#sdc_cb_none').html(button_none.$element);
$('#sdc_cb_all a.oo-ui-buttonElement-button').click(function(){ $('input.sdc_checkbox').attr('checked', true); return false; });
$('#sdc_cb_toggle a.oo-ui-buttonElement-button').click(function(){ $('input.sdc_checkbox').click(); return false; });
$('#sdc_cb_none a.oo-ui-buttonElement-button').click(function(){ $('input.sdc_checkbox').attr('checked', false); return false; });
let button_sti = new OO.ui.ButtonWidget( { label: 'Set target item',href: '#' } ) ;
$('#sdc_target_item_button ').html(button_sti.$element);
$('#sdc_target_item_button a.oo-ui-buttonElement-button').click(function(){me.open_dialog(me);});
$('#sdc_property').change(function(){me.show_action_button()});
me.update_main_position();
setTimeout(me.update_main_position,200);
} ,
toggle_main : function () {
this.active = !this.active ;
if ( this.active ) {
this.show_checkboxes();
$('#sdc_options').show();
} else {
$('div.sdc_checkbox_container').remove();
$('#sdc_options').hide();
}
this.update_main_position();
} ,
cache_file_media_ids : function ( files ) {
let me = this ;
let chunks = [ [] ] ;
let MAX_CHUNK_SIZE = 50 ;
$.each ( files , function ( dummy , file ) {
if ( chunks[chunks.length-1].length < MAX_CHUNK_SIZE ) {
chunks[chunks.length-1].push ( file ) ;
} else {
chunks.push ( [ file ] ) ;
}
} ) ;
me.wikidata_items_to_load = [] ;
$.each ( chunks , function ( dummy , chunk ) {
me.cache_file_media_ids_chunk(chunk) ;
} ) ;
} ,
cache_file_media_ids_chunk : function ( files ) {
let me = this ;
let params = {
action:'query',
prop:'info',
titles:"File:"+files.join("|File:"),
format:'json'
} ;
$.post('/w/api.php',params,function(d){
let to_load = [] ;
$.each ( d.query.pages , function ( page_id , page_info ) {
if ( page_id == -1 ) return ; // Paranoia
let mid = 'M'+page_id ;
let file = page_info.title.replace(/^File:/,'').replace(/ /g,'_');
me.mid_cache[file] = mid ;
me.mid2file[mid] = file ;
to_load.push ( mid ) ;
} ) ;
me.load_media_items(to_load);
},'json');
} ,
load_media_items : function ( mids ) {
if ( mids.length == 0 ) return ;
let me = this ;
let params = {
action:'wbgetentities',
ids:mids.join('|'),
format:'json'
} ;
$.post('/w/api.php',params,function(d){
$.each ( d.entities , function ( mid , mi ) {
me.media_items[mid] = mi ;
me.update_file_sdc(mid);
} ) ;
me.load_wikidata_items();
},'json');
} ,
load_wikidata_items : function ( callback ) {
let me = this ;
let to_load = [] ; // Should never be more than 50
$.each ( me.wikidata_items_to_load , function ( dummy , q ) {
if ( typeof me.wikidata_item_labels[q] != 'undefined' ) {
me.update_q_labels(q);
return ;
}
if ( $.inArray(q,to_load) !== -1 ) return ;
to_load.push(q) ;
} ) ;
me.wikidata_items_to_load = [] ;
if ( to_load.length == 0 ) return ;
$.getJSON('https://www.wikidata.org/w/api.php?callback=?',{
action:'wbformatentities',
ids:to_load.join('|'),
format:'json'
},function(d){
$.each ( d.wbformatentities , function ( q , html ) {
me.wikidata_item_labels[q] = html.replace('<a ','<a target="_blank" ') ;
me.update_q_labels(q);
} ) ;
if ( typeof callback != 'undefined' ) callback() ;
});
} ,
update_q_labels : function ( q ) {
let me = this ;
$('td.q_to_load[q="'+q.replace(/'/g, "'")+'"]').removeClass('q_to_load').html(me.wikidata_item_labels[q]);
} ,
get_wikidata_item_label_td : function ( q , prominent ) {
let me = this ;
let style = 'vertical-align:top;' ;
if ( prominent ) style += 'font-weight:bold;' ;
if ( typeof me.wikidata_item_labels[q] == 'undefined' ) {
return "<td class='q_to_load' q='"+q+"' style='"+style+"'>"+q+"</td>" ;
} else {
return "<td q='"+q+"' style='"+style+"'>"+me.wikidata_item_labels[q]+"</td>" ;
}
} ,
update_file_sdc : function ( mid ) {
let me = this ;
let file = me.mid2file[mid] ;
if ( typeof file == 'undefined' ) return ;
let mi = me.media_items[mid] ;
if ( typeof mi == 'undefined' ) return ;
let out = [] ;
$.each ( (mi.statements||{}) , function ( property , statements ) {
$.each ( statements , function ( dummy , statement ) {
if ( ((statement.mainsnak||{}).datavalue||{}).type != 'wikibase-entityid' ) return ;
me.wikidata_items_to_load.push(property);
let wd_item_id = statement.mainsnak.datavalue.value.id ;
me.wikidata_items_to_load.push(wd_item_id);
out.push({property:property,target:wd_item_id,prominent:statement.rank=='preferred'});
} ) ;
} ) ;
let h = '' ;
if ( out.length == 0 ) {
let html = "<div class='sdc_statements' mid='"+mid+"' style='font-size:9pt;width:100%;text-align:left;'>" ;
html += "<div style='color:#b32424;font-weight:bold;'>No SDC</div>" ;
html += "</div>" ;
h = $(html);
} else {
let html = "<div class='sdc_statements' mid='"+mid+"' style='font-size:9pt;width:100%;text-align:left;'>" ;
html += "<table style='border-spacing:0;border-collapse:collapse;'><tbody>" ;
$.each ( out , function ( dummy , row ) {
html += "<tr>" ;
html += me.get_wikidata_item_label_td(row.property,false) ;
html += me.get_wikidata_item_label_td(row.target,row.prominent) ;
html += "</tr>" ;
} ) ;
html += "</tbody></table></div>" ;
h = $(html);
h.find('td').css({padding:'1px','text-align':'left'});
}
let element = $($('input.sdc_checkbox[file="'+me.sanitize_file_attribute(file)+'"]').parent()) ;
$('div.sdc_statements[mid="'+mid+'"').remove();
element.after(h);
} ,
sanitize_file_attribute : function ( file ) {
return encodeURIComponent(file).replace(/'/g, "'") ;
} ,
show_checkboxes : function () {
let me = this ;
let files = [] ;
$('a.image, a.mw-file-description').each(function(num,a){
let file = decodeURIComponent($(a).attr('href')).replace(/^.+\/File:/,'') ;
if ( $.inArray(file,me.exclude_files) > -1 ) return ; // Bad file!
if ( $(a).parents('#wdinfobox').length > 0 ) return ; // In infobox
files.push(file);
let html = "<div class='sdc_checkbox_container' style='display:flex'>" ;
html += "<div><input type='checkbox' class='sdc_checkbox' file='"+me.sanitize_file_attribute(file)+"' /></div>" ;
html += "</div>" ;
$(a).after(html);
});
me.cache_file_media_ids(files);
}
} ;
sdc.init();
});