MediaWiki:Gadget-DuplicateReferences.js

From wikibase-docker
Jump to navigation Jump to search

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: 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.
/**
 * Adds a link to copy references and add them to other statements on the same item.
 *
 * @see [[MediaWiki:Gadget-DuplicateReferences.css]]
 * @author Bene*
 */
( function ( $, mw, wb ) {
	'use strict';

	if ( !mw.config.exists( 'wbEntityId' ) ||
		!mw.config.get( 'wbIsEditView' ) ||
		!mw.config.get( 'wgIsProbablyEditable' )
	) {
		return;
	}

	switch ( mw.config.get( 'wgUserLanguage' ) ) {
	default:
	case 'en':
		mw.messages.set( {
			'insert-reference': 'insert reference',
			'copy': 'copy',
			'saving': 'saving',
			'copied': 'copied',
			'insert-reference-failed': 'The reference could not be inserted.'
		} );
		break;
	case 'cs':
		mw.messages.set( {
			'insert-reference': 'vložit referenci',
			'copy': 'zkopírovat',
			'saving': 'ukládám',
			'copied': 'zkopírováno',
			'insert-reference-failed': 'Referenci nebylo možné uložit.'
		} );
		break;
	case 'de':
		mw.messages.set( {
			'insert-reference': 'Einzelnachweis einfügen',
			'copy': 'kopieren',
			'saving': 'speichern',
			'copied': 'kopiert',
			'insert-reference-failed': 'Der Einzelnachweis konnte nicht eingefügt werden.'
		} );
		break;
	case 'el':
		mw.messages.set( {
			'insert-reference': 'προσθήκη παραπομπής',
			'copy': 'αντιγραφή',
			'saving': 'αποθηκεύεται',
			'copied': 'αντιγράφτηκε',
			'insert-reference-failed': 'αποτυχημένη προσθήκη παραπομπής.'
		} );
		break;
	case 'fr':
		mw.messages.set( {
			'insert-reference': 'coller la référence',
			'copy': 'copier',
			'saving': 'enregistrement',
			'copied': 'copiée',
			'insert-reference-failed': 'La référence ne peut pas être collée.'
		} );
		break;
	case 'it':
		mw.messages.set( {
			'insert-reference': 'incolla fonte',
			'copy': 'copia',
			'saving': 'copia in corso',
			'copied': 'copiato',
			'insert-reference-failed': 'la fonte non può essere copiata'
		} );
		break;
	case 'mk':
		mw.messages.set( {
			'insert-reference': 'вметни навод',
			'copy': 'копирај',
			'saving': 'зачувувам',
			'copied': 'ископирано',
			'insert-reference-failed': 'Не можев да го вметнам наводот.'
		} );
		break;
	case 'nl':
		mw.messages.set( {
			'insert-reference': 'bron invoegen',
			'copy': 'kopiëren',
			'saving': 'opslaan',
			'copied': 'gekopieerd',
			'insert-reference-failed': 'De bron kon niet ingevoegd worden.'
		} );
		break;
	case 'pl':
		mw.messages.set( {
				'insert-reference': 'wstaw odniesienie',
				'copy': 'kopiuj',
				'saving': 'zapisywanie',
				'copied': 'skopiowano',
				'insert-reference-failed': 'Odniesienie nie mogło zostać wstawione.'
		} );
		break;
    }
	var RevisionStore = function ( baseRev ) {
		this._revisions = {
			baseRevision: baseRev,
			labelRevision: baseRev,
			descriptionRevision: baseRev,
			aliasesRevision: baseRev,
			sitelinksRevision: {},
			claimRevisions: {}
		};
	};

	$.extend( RevisionStore.prototype, {
		getBaseRevision: function () {
			return this._revisions.baseRevision;
		},
		getLabelRevision: function () {
			return this._revisions.labelRevision;
		},
		getDescriptionRevision: function () {
			return this._revisions.descriptionRevision;
		},
		getAliasesRevision: function () {
			return this._revisions.aliasesRevision;
		},
		getSitelinksRevision: function ( siteId ) {
			if ( Object.prototype.hasOwnProperty.call( this._revisions.sitelinksRevision, siteId ) ) {
				return this._revisions.sitelinksRevision[ siteId ];
			}

			return this._revisions.baseRevision;
		},
		getClaimRevision: function ( statementGuid ) {
			if ( Object.prototype.hasOwnProperty.call( this._revisions.claimRevisions, statementGuid ) ) {
				return this._revisions.claimRevisions[ statementGuid ];
			}

			return this._revisions.baseRevision;
		},
		setLabelRevision: function ( rev ) {
			this._revisions.labelRevision = rev;
		},
		setDescriptionRevision: function ( rev ) {
			this._revisions.descriptionRevision = rev;
		},
		setAliasesRevision: function ( rev ) {
			this._revisions.aliasesRevision = rev;
		},
		setSitelinksRevision: function ( rev, siteId ) {
			this._revisions.sitelinksRevision[ siteId ] = rev;
		},
		setClaimRevision: function ( rev, statementGuid ) {
			this._revisions.claimRevisions[ statementGuid ] = rev;
		}

	} );
	var entityPromise = $.Deferred( function ( deferred ) {
		mw.hook( 'wikibase.entityPage.entityLoaded' ).add( function ( entity ) {
			deferred.resolve( entity );
		} );
	} ).promise();
	var entityInitializer = new wb.EntityInitializer( entityPromise );	
	var model = null;
	entityInitializer.getEntity().then( function ( entity ) {
		var repoConfig = mw.config.get( 'wbRepo' ),
		repoApiUrl = repoConfig.url + repoConfig.scriptPath + '/api.php',
		mwApi = wb.api.getLocationAgnosticMwApi( repoApiUrl ),
		repoApi = new wb.api.RepoApi( mwApi ),
		revisionStore = new RevisionStore(mw.config.get( 'wgCurRevisionId' ) ),
		entityChangersFactory = new wb.entityChangers.EntityChangersFactory(
			repoApi,
			revisionStore,
			entity
		);
		model = entityChangersFactory.getStatementsChanger();
	} );
	
/*
	/Create model	
*/

	var selectedReference = null;

	function insertReference( statementview ) {
		var deferred = $.Deferred();

		if ( selectedReference !== null ) {
			var statement = statementview.value();
			statement.getReferences().addItem( selectedReference );

			model.save( statement ).then( function ( statement ) {
				if ( !statementview._referencesListview ) {
					statementview._createReferencesListview();
				}
				statementview._recreateReferences();
				deferred.resolve();
			}, function ( error ) {
				mw.notify( error.getMessage(), {
					title: mw.msg( 'insert-reference-failed' ),
					type: 'error'
				} );
				deferred.resolve();
			} );
		}

		return deferred.promise();
	}

	function selectReference( ref ) {
		selectedReference = ref;
		selectedReference._hash = null; // set hash to null to create a new reference

		if ( $( '.wikibase-toolbar-button-insert' ).length === 0 ) {
			addInsertLinks();
		}
	}

	function addInsertLinks() {
		// [insert reference]
		$( '.wikibase-statementview-references .wikibase-toolbar-button-add' ).after(
			$( '<span>' )
			.addClass( 'wikibase-toolbarbutton wikibase-toolbar-item wikibase-toolbar-button wikibase-toolbar-button-insert' )
			.append(
				$( '<a>' )
				.attr( 'href', '#' )
				.text( mw.msg( 'insert-reference' ) )
				.prepend( $( '<span>' ).addClass( 'wb-icon' ) )
				.click( function ( e ) {
					e.preventDefault();
					var $this = $( this ),
						$parent = $this.parent();

					if ( !$parent.hasClass( 'wikibase-toolbarbutton-disabled' ) ) {
						$parent.addClass( 'wikibase-toolbarbutton-disabled ui-state-disabled' );
						$this.text( mw.msg( 'saving' ) ).prepend( $( '<span>' ).addClass( 'wb-icon' ) );

						var statementview = $this.parents( '.wikibase-statementview' ).data( 'statementview' );
						insertReference( statementview ).then( function () {
							$parent.removeClass( 'wikibase-toolbarbutton-disabled ui-state-disabled' );
							$this.text( mw.msg( 'insert-reference' ) ).prepend( $( '<span>' ).addClass( 'wb-icon' ) );
						} );
					}
				} )
			)
		);
	}

	function addCopyLinks( element ) {
		//hide existing items
		$( element ).find( '.wikibase-referenceview-heading' ).find( '.wikibase-toolbar-item' ).hide();
		// [copy]
		$( element ).find( '.wikibase-referenceview-heading' ).append(
			$( '<div>' )
			.addClass( 'wikibase-copytoolbar-container wikibase-toolbar-container' )
			.append(
				$( '<span>' )
				.addClass( 'wikibase-toolbarbutton wikibase-toolbar-item wikibase-toolbar-button wikibase-toolbar-button-copy' )
				.append(
					$( '<a>' )
					.attr( 'href', '#' )
					.text( mw.msg( 'copy' ) )
					.prepend( $( '<span>' ).addClass( 'wb-icon' ) )
					.click( function ( e ) {
						e.preventDefault();
						var $this = $( this ),
							$parent = $this.parent();

						if ( !$parent.hasClass( 'wikibase-toolbarbutton-disabled' ) ) {
							$( '.wikibase-toolbar-button-copy' )
								.removeClass( 'wikibase-toolbarbutton-disabled ui-state-disabled' )
								.find( 'a' )
								.text( mw.msg( 'copy' ) )
								.prepend( $( '<span>' ).addClass( 'wb-icon' ) );

							$parent.addClass( 'wikibase-toolbarbutton-disabled ui-state-disabled' );
							$this.text( mw.msg( 'copied' ) ).prepend( $( '<span>' ).addClass( 'wb-icon' ) );

							var hash = $this.closest( '.wikibase-referenceview' )[ 0 ].className.match( /wikibase-referenceview-([0-9a-z]+)/ )[ 1 ];
							var statement = $this.closest( '.wikibase-statementview' ).data( 'wikibase-statementview' ).value();
							selectReference( statement.getReferences().toArray().filter( function ( v ) { return v.getHash() === hash } )[ 0 ] );
						}
					} )
				)
			)
		);
	}

	$( function () {
		addCopyLinks( '.wikibase-statementview' );

		// remove [copy] when entering edit mode to avoid clashes
		$( document )
			.on( 'snakviewafterstartediting', function ( e ) {
				setTimeout( function () {
					$( e.target ).find( '.wikibase-referenceview-heading' ).find( '.wikibase-copytoolbar-container' ).remove();
					// show existing items
					$( e.target ).find( '.wikibase-referenceview-heading' ).find( '.wikibase-toolbar-item' ).show();
				}, 50 );			
			} )
			.on( 'snakviewafterstopediting', function ( e ) {
				var element = $( e.target ).parents( '.wikibase-statementview' );
				// ugly hack but there seems to be no proper event to add this
				setTimeout( function () {
					addCopyLinks( element );
				}, 50 );
			} );
	} );

} )( jQuery, mediaWiki, wikibase );