MediaWiki:Gadget-DraggableSitelinks.js

From Wikidata
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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * DraggableSitelink.js
 *
 * Easily add a Wikipedia as an "imported from" (P143) reference to any
 * statement - just drag the sitelink on to the sources for that claim
 *
 * Patches to: https://github.com/inductiveload/wikidata-gadgets
 * Release: 2013-03-11 v0.9
 * Author: User:Inductiveload
 * Licence: MIT/GPL
 */
/* global mediaWiki, jQuery */
( function ( mw, $ ) {
	'use strict';

	var importedFrom = { // hint to show when dragging, defaults to 'en'
		'ar' : 'مستورد من',
		'de' : 'Datenvorlage',
		'el' : 'προέρχεται από',
		'en' : 'Imported from',
		'fr' : 'Importé de',
		'it' : 'Importato da',
		'mk' : 'Увезено од',
		'nl' : 'Geimporteerd uit',
		'pl' : 'Zaimportowane z',
		'ru' : 'взято из',
		'sv' : 'Importerad från',
		'zh' : '导入自'
	},
	// TODO: there are many many more
	wikiProperties = { // list of Wikipedia item IDs
		'arwiki' : 199700,
		'cawiki' : 199693,
		'cebwiki': 837615,
		'dawiki' : 181163,
		'dewiki' : 48183,
		'elwiki' : 11918,
		'enwiki' : 328,
		'euwiki' : 207260,
		'fiwiki' : 175482,
		'frwiki' : 8447,
		'eowiki' : 190551,
		'eswiki' : 8449,
		'glwiki' : 841208,
		'hewiki' : 199913,
		'iawiki' : 3757068,
		'iewiki' : 6167360,
		'iowiki' : 1154766,
		'itwiki' : 11920,
		'jawiki' : 177837,
		'mkwiki' : 842341,
		'nlwiki' : 10000,
		'plwiki' : 1551807,
		'ptwiki' : 11921,
		'ruwiki' : 206855,
		'svwiki' : 169514,
		'trwiki' : 58255,
		'ukwiki' : 199698,
		'viwiki' : 200180,
		'vowiki' : 714826,
		'zhwiki' : 30239
	},

	importedFromProperty = 'P143',
	claimPatt = /[Qq][0-9]+\$[\-A-Fa-f0-9]+/,
	refsSelector = 'div.wikibase-statementview-references-heading',
	myLang = mw.config.get( 'wgUserLanguage' ),

	// Private functions
	addImportedFrom = function ( target, lang ) {
		// isolate the
		var sourceItem,
			snaks = {},
			targetClaim = target.closest( '.wikibase-statementview' )
			.attr( 'class' );

		targetClaim = claimPatt.exec( targetClaim );
		if ( targetClaim === null ) { // we don't know the claim GUID, have to bail
			console.log( 'This claim does not have a known GUID - blame WD:DEVs!' );
			return;
		}

		sourceItem = wikiProperties[lang];

		if ( sourceItem === undefined ) { // we don't know this wiki, have to bail
			console.log( 'This Wiki does not have a known ID - add it!' );
			return;
		}

		// construct the Snak
		snaks[ importedFromProperty ] = [{
			'snaktype': 'value',
			'property': importedFromProperty,
			'datavalue': {
				'type': 'wikibase-entityid',
				'value': {
					'entity-type': 'item',
					'numeric-id': sourceItem
				}
			}
		}];

		// post the reference and reload
		new mw.Api()
		.postWithToken( 'csrf', {
			'action': 'wbsetreference',
			'statement': targetClaim[0],
			'snaks': JSON.stringify( snaks ),
			'tags': 'gadget-draggablesitelinks',
			'baserevid': mw.config.get( 'wgRevisionId' )
		} )
		.done( function ( /* data */ ) {
			document.location.reload( true );
		} );
	},

	init = function () {

		// set up styles
		mw.util.addCSS( '.x-draggable-sitelink-target{ background-color:#6EDDA6;}' );

		// make the sitelinks draggable
		$( '.wikibase-sitelinklistview-listview > .listview-item' ).draggable( {
			cursor: 'move',
			cursorAt: { top: 5, left: -5 },
			start: function ( /* event, ui */ ) {
				$( refsSelector )
					.addClass( 'x-draggable-sitelink-target' )

					// make the targets droppable (they can appear after load, 
					// so can't do this at init time
					.droppable( {
						drop: function ( event, ui ) {
							var lang = $( ui.helper ).data( 'lang' );

							addImportedFrom( $( event.target ), lang );

							return false;
						}
					} );
			},
			stop: function ( /* event, ui */ ) {
				$( refsSelector )
					.removeClass( 'x-draggable-sitelink-target' )
					.droppable( 'destroy' );
			},
			helper: function ( event ) {

				var $listview = $( event.target )
					.closest( '.wikibase-sitelinkview.listview-item' ),

				langCode = $listview
					.data( 'wb-siteid' ),

				draggedPage = $listview
					.find( '.wikibase-sitelinkview-page a' )
					.text(),

				prefixText = importedFrom[myLang];

				if ( prefixText === undefined ) {
					prefixText = importedFrom.en;
				}

				return $( '<div>' )
					.addClass( 'ui-widget-header x-draggable-sitelink-helper' )
					.text( prefixText + ': ' + langCode + ' (' + draggedPage + ')' )
					.data( 'lang', langCode );
			}
		} );
	};

	$( function () {
		mw.hook( 'wikibase.entityPage.entityView.rendered' ).add( init );
	} );
}( mediaWiki, jQuery ) );