Difference between revisions of "MediaWiki:Gadget-QuickPresets.js"

From Wikibase Personal data
Jump to navigation Jump to search
Line 173: Line 173:
 
  */
 
  */
 
function quickpresets_checktype(qid, prop) {
 
function quickpresets_checktype(qid, prop) {
var typeqid=prop.qid;
+
  var typeqid = prop.qid;
    // Search in HTML-DOM
+
  // Search in HTML-DOM
    // for each "instance of" value, run this function
+
  // for each "instance of" value, run this function
    var typefromdom=$.map($('#P3').find(".wikibase-snakview-value a"), function(value, index) {
+
  var typefromdom = $.map($("#P3").find(".wikibase-snakview-value a"), function(
if(typeof value.attributes.href === "undefined")
+
    value,
    {
+
    index
        return [];
+
  ) {
    }
+
    if (typeof value.attributes.href === "undefined") {
else
+
      return [];
    {
+
    } else {
        return [value.attributes.href.value.substring(6)];
+
      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 ) {
+
  // typefromdom is now a list of Item:Qxxx, possibly empty
    // the 0 prescription, applicable to all items which are instance of something
+
  if (typefromdom.length === 0) {
    quickpresets_addinterface(qid, prop);
+
    if (typeqid === null) {
    }
+
      // the null prescription for when there is no "instance of"
    else if ( typefromdom.includes("Item:Q"+typeqid) ) {
+
      quickpresets_addinterface(qid, prop);
    // 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); } );
 
    }
 
 
     }
 
     }
 +
  } 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";
 +
      const sparqlQuery = "Ask { pdio:Q" + qid + " pdiot:P3/pdiot:P4* pdio:Q" + typeqid + '. hint:Prior hint:gearing "forwards" }';
 +
      const fullUrl = endpointUrl + "?query=" + encodeURIComponent(sparqlQuery);
 +
      const myHeaders = { Accept: "application/sparql-results+json" };
 +
      debug("qid: " + qid + "\ntypeqid: " + typeqid + "\n" + fullUrl + "\n" + sparqlQuery );
 +
      fetch(fullUrl, { headers: myHeaders })
 +
        .then(function(body) {body.json();})
 +
        .then(function(json) {if (json.boolean) {quickpresets_addinterface(qid, prop);}});
 +
    }
 +
  }
 
}
 
}
  

Revision as of 12:09, 12 January 2020

// 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";
      const sparqlQuery = "Ask { pdio:Q" + qid + " pdiot:P3/pdiot:P4* pdio:Q" + typeqid + '. hint:Prior hint:gearing "forwards" }';
      const fullUrl = endpointUrl + "?query=" + encodeURIComponent(sparqlQuery);
      const myHeaders = { Accept: "application/sparql-results+json" };
      debug("qid: " + qid + "\ntypeqid: " + typeqid + "\n" + fullUrl + "\n" + sparqlQuery );
      fetch(fullUrl, { headers: myHeaders })
        .then(function(body) {body.json();})
        .then(function(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]);
	}
    });

} );