MediaWiki:Gadget-EasyQuery.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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
$( function () {
var namespace = mw.config.get( 'wgNamespaceNumber' );
var isMain = namespace === 0;
var isProperty = namespace === 120;
var isLemma = namespace === 146;
if ( !isMain && !isProperty && !isLemma ) {
return;
}
function createPopupAndAddIcon( element, query, title, label ) {
var url = '#' + encodeURIComponent(query);
mw.loader.using( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui.styles.icons-interactions' ] ).then( function () {
var searchIcon = new OO.ui.IconWidget( {
icon: 'ellipsis',
iconTitle: title,
$element: $( '<a>' ).attr( {
href: 'https://query.wikidata.org/' + url,
target: '_blank',
style: 'background-size: 20px 20px; opacity: 0.5;'
} )
} );
var $content = $( '<div>' );
var popup = new OO.ui.PopupWidget( {
$content: $content,
width: 500,
head: true,
padded: false,
label: label,
align: 'force-right'
} );
$( document ).keydown( function( e ) {
// ESCAPE key pressed
if ( e.keyCode === 27 ) {
popup.onCloseButtonClick();
}
} );
searchIcon.$element.click( function () {
$content.html(
$( '<iframe scrolling="yes" frameborder="0">' )
.attr( {
src: 'https://query.wikidata.org/embed.html' + url,
width: '500',
height: '400'
} )
);
popup.$element.attr( 'style', 'position:absolute; z-index:100;' );
popup.toggle( true );
return false;
} );
$( element ).append( searchIcon.$element, popup.$element );
} );
}
// Title lable popup
var $title = $( '.wikibase-title' );
var id = $title.find( '.wikibase-title-id' ).text().replace( /[()]/g, '' );
var query = ''
+ '#defaultView:Graph\n'
+ 'SELECT ?node ?nodeLabel ?nodeImage ?childNode ?childNodeLabel ?childNodeImage ?rgb WHERE {\n'
+ ' {\n'
+ ' BIND(wd:' + id + ' AS ?node)\n'
+ ' ?node ?p ?i.\n'
+ ' OPTIONAL { ?node wdt:P18 ?nodeImage. }\n'
+ ' ?childNode ?x ?p.\n'
+ ' ?childNode rdf:type wikibase:Property.\n'
+ ' FILTER(STRSTARTS(STR(?i), "http://www.wikidata.org/entity/Q"))\n'
+ ' FILTER(STRSTARTS(STR(?childNode), "http://www.wikidata.org/entity/P"))\n'
+ ' }\n'
+ ' UNION\n'
+ ' {\n'
+ ' BIND("EFFBD8" AS ?rgb)\n'
+ ' wd:' + id + ' ?p ?childNode.\n'
+ ' OPTIONAL { ?childNode wdt:P18 ?childNodeImage. }\n'
+ ' ?node ?x ?p.\n'
+ ' ?node rdf:type wikibase:Property.\n'
+ ' FILTER(STRSTARTS(STR(?childNode), "http://www.wikidata.org/entity/Q"))\n'
+ ' }\n'
+ ' OPTIONAL {\n'
+ ' ?node wdt:P18 ?nodeImage.\n'
+ ' ?childNode wdt:P18 ?childNodeImage.\n'
+ ' }\n'
+ ' SERVICE wikibase:label { bd:serviceParam wikibase:language "' + mw.config.get( 'wgUserLanguage' ) + '". }\n'
+ '}';
createPopupAndAddIcon( $title.find( '.wikibase-title-id' ), query, 'Click to see graph', 'Entity Graph');
function buildQuery(property, object) {
var query;
var language = mw.config.get( 'wgUserLanguage' ) + ',en,de,fr,ja,es,ru,pt,it,zh,fa,ar,pl,nl,uk,tr,id,he,cs,sv,hu,fi,vi,ko,el,hi,bn,no,ca,ro,th,da,sr,bg,az,ms,et,uz,hr,sk,eu,hy,sl,lt,eo,ta,kk,lv,be,kn,sq,ur,mk';
// Use nested query, otherwise query timeouts on basic things like "P31 Q5"
// Do not use [AUTO_LANGUAGE], because there is no language selector in iframe
if ( isLemma ) {
query = ''
+ 'SELECT ?item ?lemma ?category ?language {\n'
+ ' {\n'
+ ' SELECT * WHERE {\n'
+ ' ?item rdf:type ontolex:LexicalEntry ;\n'
+ ' wdt:'+ property +' '+ object +' ;\n'
+ ' wikibase:lemma ?lemma ;\n'
+ ' wikibase:lexicalCategory ?categoryItem ;\n'
+ ' dct:language ?languageItem .\n'
+ ' } LIMIT 100\n'
+ ' }\n'
+ ' SERVICE wikibase:label {\n'
+ ' bd:serviceParam wikibase:language "'+ language +'" .\n'
+ ' ?languageItem rdfs:label ?language . ?categoryItem rdfs:label ?category .\n'
+ ' }\n'
+ '}';
} else {
var propFilter = isProperty ? ' ?item rdf:type wikibase:Property .\n' : '';
// Use nested query, otherwise query timeouts on basic things like "P31 Q5"
// Do not use [AUTO_LANGUAGE], because there is no language selector in iframe
query = ''
+ 'SELECT * {\n'
+ ' {\n'
+ ' SELECT * {\n'
+ ' ?item wdt:'+ property +' '+ object +' .\n'
+ propFilter
+ ' } LIMIT 100\n'
+ ' }\n'
+ ' SERVICE wikibase:label {\n'
+ ' bd:serviceParam wikibase:language "'+ language +'" .\n'
+ ' ?item rdfs:label ?label . ?item schema:description ?description\n'
+ ' }\n'
+ '}';
}
return query;
}
mw.hook( 'wikibase.entityPage.entityLoaded' ).add( function ( entityData ) {
var propertyId;
for (propertyId in entityData.claims) {
var statementGroup = entityData.claims[propertyId];
for ( var i = 0; i < statementGroup.length; i++ ) {
var statement = statementGroup[i];
if ( statement.mainsnak.snaktype !== "value" ) {
continue;
}
var statementId = statement.id;
var statementView = document.getElementById(statementId);
if ( !statementView ) {
continue;
}
var attachPoint = statementView.querySelector('.wikibase-statementview-mainsnak .wikibase-snakview-indicators');
if ( !attachPoint ) {
continue;
}
var datavalue = statement.mainsnak.datavalue;
var datatype = statement.mainsnak.datatype;
var object = undefined;
if ( datatype === 'wikibase-item' || datatype === 'wikibase-property' || datatype === 'wikibase-lexeme' ) {
object = 'wd:' + datavalue.value.id;
} else if ( datatype === 'time' ) {
object = '"' + datavalue.value.time + '"^^xsd:dateTime';
} else if ( datatype === 'quantity' ) {
object = datavalue.value.amount;
} else if ( datatype === 'string' || datatype === 'external-id' ) {
object = JSON.stringify(datavalue.value); // escaping quotes
} else if ( datatype === 'url' ) {
object = '<' + datavalue.value + '>';
} else if ( datatype === 'monolingualtext' ) {
object = JSON.stringify(datavalue.value.text) + '@' + datavalue.value.language;
} else if ( datatype === 'commonsMedia' ) {
object = '<http://commons.wikimedia.org/wiki/Special:FilePath/' + encodeURIComponent(datavalue.value) + '>';
}
if ( !object ) {
continue;
}
var query = buildQuery( propertyId, object );
createPopupAndAddIcon( $( attachPoint ), query, 'More items with this statement' );
}
}
} );
} );