MediaWiki:Gadget-QuickPresets.js

From Wikibase Personal data
Revision as of 11:36, 12 January 2020 by Stenli karanxha (talk | contribs)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Note: After saving, 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: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
// taken from https://www.wikidata.org/wiki/User:MichaelSchoenitzer/quickpresets.js
// non exhaustive list of modifications:
// P31 and P(subclass) ---> P3 and P4   (see #P31, pid == 3)
// wd, wdt --> pdio, pdiot
// importScript and importStyleSheet replaced
// turned into a common script
// see doc at [[Gadget-QuickPresets/doc]]

// mw.notify("QuickPresets")
function debug(alert){
	// mw.notify(alert)
}
mw.loader.load( '/w/index.php?title=MediaWiki:Gadget-QuickPresets/defaultconf.css&action=raw&ctype=text/css', 'text/css' );

if( typeof(quick_props)=="undefined" ) {
    mw.loader.load( '/w/index.php?title=MediaWiki:Gadget-QuickPresets/defaultconf.js&action=raw&ctype=text/javascript' );
}

/**
 * Load the entityselector-plugin, try until it works
 * See: https://stackoverflow.com/questions/47985370/
 */
function quickpresets_loadentityselector(){
    try {
	$( ".quickpresetsiteminput input" ).entityselector( {
	    url: 'https://wiki.personaldata.io/w/api.php',
	    language: mw.config.get('wgUserLanguage')
	} );
    }
    catch(err) {
	setTimeout(quickpresets_loadentityselector, 100);
    }
}

/**
 * Add the interface wich alows to quickly add statements
 */
function quickpresets_addinterface(qid, prop) {
    // compose and intert fieldset.
    var $fieldset = $("<fieldset id=\"quickpresets\"><legend>Quick Presets (" + prop.name + ")</legend></fieldset>")
	.insertAfter($('.wikibase-statementgrouplistview').first());

    prop.defaults.forEach(function(dflt) {
	if(typeof dflt.type == "undefined") {
	    dflt.type = "item";
	}
	var $line = $("<div><p class='addstatement'>Add "+dflt.name+":<span class='links'></span>" + 
	    "<span class='quickpresets" + dflt.type + "input'>&nbsp;<input/>&nbsp;" +
	    "<a href=\'#\'>✔</a></span></p></div>"
	).appendTo($fieldset);
	if($('#P'+dflt.pid).find(".wikibase-snakview-value a").length !== 0) {
	    $line.addClass('disabled');
	}
	if(dflt.values.length === 0) {
	    $line.addClass('compact');
	}
	$line.find('.quickpresets' + dflt.type + 'input a')
	    .on('click', function(e) {
		e.preventDefault();
		if(dflt.type == "item") {
		    var selection = $(this).prev('input').data('entityselector').selectedEntity();
		    quickpresets_additemstatement(qid, dflt.pid, dflt.name, selection.id.substring(1), selection.label);
		}
		else if(dflt.type == "string") {
			quickpresets_addstringstatement(qid, dflt.pid, dflt.name, $(this).prev('input')[0].value);
		}
	    });

	// Add links for all preset-values…
	dflt.values.forEach(function(val) {
	    $("<span>&nbsp;<a href='#'></a>&nbsp;∙</span>")
		.appendTo($line.find('span.links'))
		.find('a')
		.text(val.name)
		.on('click', function(e) {
		    e.preventDefault();
		    if(dflt.type == "item") {
			quickpresets_additemstatement(qid, dflt.pid, dflt.name, val.qid, val.name);
		    }
		    else if(dflt.type == "string") {
			quickpresets_addstringstatement(qid, dflt.pid, dflt.name, val.text);
		    }
		});
	});

    });

    setTimeout(quickpresets_loadentityselector, 100);
}

/**
 * Add a formated claim and in case of success show succtext
 */
function quickpresets_addclaim(claim, succtext) {
    var api = new mw.Api();
    var token = mw.user.tokens.values.csrfToken;
    api.post( { 
	action: 'wbsetclaim',
	summary: "Added with [[MediaWiki:Gadget-QuickPresets.js|Quickpresets]]",
	claim: JSON.stringify(claim),
	token: token
    }).then(
	function(aw){
	    if(aw.success == 1)
		//$('.wikibase-statementgrouplistview').first().after( succtext );
		mw.notify(succtext);
	}); 
}

/**
 * Add a statement with datatype 'item'
 * qid: the qid of the item wich should get the statment
 * pid: the property to add
 * pname: the name of the property for showing a success-note
 * toqid: the qid of the item that is used as value
 * toname: the name of the value-item property for showing a success-note
 */
function quickpresets_additemstatement(qid, pid, pname, toqid, toname) {
	var claim = {
	id: (new wb.utilities.ClaimGuidGenerator("q" + qid)).newGuid(),
	type: "claim",
	mainsnak: {
	    snaktype: "value",
	    property: "P" + pid,
	    datavalue: {
		value: {
		    "entity-type": "item",
		    "numeric-id": toqid
		},
		type: "wikibase-entityid"
	    },
	    datatype: "wikibase-item"
	}
    };
    quickpresets_addclaim(claim,  "Added "+pname+" "+toname+"");
    // Check if we now support it with another element of the config
    if(pid == 3) {
	$('#quickpresets').remove();
	for( var t = 0; t<quick_props.length; t++) {
	    if(quick_props[t].qid == toqid) {
		quickpresets_addinterface(qid, quick_props[t]);
	    }
	}
    }
}

/**
 * Add a statement with datatype 'string'
 * qid: the qid of the item wich should get the statment
 * pid: the property to add
 * pname: the name of the property for showing a success-note
 * str: the value of the statement
 */
function quickpresets_addstringstatement(qid, pid, pname, str) {
	var claim = {
	id: (new wb.utilities.ClaimGuidGenerator("q" + qid)).newGuid(),
	type: "claim",
	mainsnak: {
	    snaktype: "value",
	    property: "P" + pid,
	    datatype: "string",
	    datavalue: {
		value: str,
		type: "string"
	    }
	}
    };
    quickpresets_addclaim(claim,  "Added "+pname+" "+str+"");
}

/**
 * check if an item is of a type, if so add options
 */
function quickpresets_checktype(qid, prop) {
	var typeqid=prop.qid;
    // Search in HTML-DOM
    // for each "instance of" value, run this function
    var typefromdom=$.map($('#P3').find(".wikibase-snakview-value a"), function(value, index) {
	if(typeof value.attributes.href === "undefined")
	    {
	        return [];  
	    }
	else
	    {
	        return [value.attributes.href.value.substring(6)];
	    }
    });
    // typefromdom is now a list of Item:Qxxx, possibly empty
    if ( typefromdom.length === 0) {
	    if(typeqid === null) // the null prescription for when there is no "instance of"
	        {
	            quickpresets_addinterface(qid, prop);
	        }
    }
    else {
	     if ( typeqid === 0 ) {
	     	// the 0 prescription, applicable to all items which are instance of something
		    quickpresets_addinterface(qid, prop);
	     }
	    else if ( typefromdom.includes("Item:Q"+typeqid) ) {
	    	// direct relevance
		    quickpresets_addinterface(qid, prop);
	    }
	    else {
	    	// indirect relevance, through subclassing
	        // Now check via sparql (much slower but includes subtypes)
	        const endpointUrl = 'https://query.personaldata.io/proxy/wdqs/bigdata/namespace/wdq/sparql',
		    sparqlQuery = 'Ask { pdio:Q' + qid + ' pdiot:P3/pdiot:P4* pdio:Q' + typeqid + '. hint:Prior hint:gearing "forwards" }',
		    fullUrl = endpointUrl + '?query=' + encodeURIComponent( sparqlQuery ),
		    headers = { 'Accept': 'application/sparql-results+json' };
		    debug("qid: "+ qid + "\ntypeqid: " + typeqid + "\n" + fullUrl + "\n" + sparqlQuery);
	        fetch( fullUrl, { headers: { 'Accept': 'application/sparql-results+json' }, } )
	        	.then( body => { body.json() } )
	        	.then( json => { if ( json.boolean ) quickpresets_addinterface(qid, prop); } );
	    }
    }
}

/**
 * wait for config to be loaded, then execute func
 */
function quickpresets_waitForConfig(func){
    if(typeof quick_props !== "undefined"){
	func();
    }
    else{
	setTimeout(quickpresets_waitForConfig, 100, func);
    }
}


$( function($) {

    /**
     * Check if we're viewing an item
     */
    var qid = mw.config.get( 'wbEntityId' );
    if ( !qid ) {
	    return;
    }
    else {
	qid = qid.substring(1);
    }

    /**
     * check if item is a of right kind
     */
    quickpresets_waitForConfig(function() {
	for( var t = 0; t<quick_props.length; t++) {
	    quickpresets_checktype(qid, quick_props[t]);
	}
    });

} );