User:Inductiveload/IaUploadPopup.js

From Wikisource
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

/* eslint-disable one-var, vars-on-top */

( function ( $, mw ) {

	var IAUP = {
		showTimeout: 400
	};

	var getIaIdFromUrl = function ( url ) {
		var match;
		if ( url.match( 'https?://archive\\.org/' ) ) {
			var rx = /(details|manage|download)\/([^/]*)/;
			match = rx.exec( url );

			if ( match ) {
				return match[ 2 ];
			}
		} else if ( url.match( /^https?:\/\/ia\d+\.[a-z]+\.archive\.org/ ) ) {
			match = /\/items\/([^/]+)\//.exec( url );

			if ( match ) {
				return match[ 1 ];
			}
		}

		return null;
	};

	var getIaMeta = function ( iaId ) {

		var url = 'https://archive.org/metadata/' + iaId;

		return $.get( url );
	};

	var getAuthor = function ( str ) {
		// strip dates - these are nearly always not needed
		str = str.replace( /(?:, )?(?:(?:ca\.|fl\.) )?(\(?\d+-\d+\)?).?$/, '' );

		// strip birth date
		str = str.replace( /(?:, )(?:b\.|d\.) +\d{3,4}$/, '' );

		// strip initial expansions
		str = str.replace( /(?:[A-Z]. ?)+ \((.*)\)/, '$1' );

		str = str.replace( /, (Sir|Lord)$/, '' );

		// Last, First -> First Last
		str = str.replace( /^([^,]+), ([^,]+)$/, '$2 $1' );

		// Fix initials without dots
		str = str.replace( / ([A-Z]) /g, ' $1. ' );

		return str;
	};

	var getAuthors = function ( strOrArr ) {
		if ( !Array.isArray( strOrArr ) ) {
			strOrArr = [ strOrArr ];
		}

		return strOrArr.map( function ( a ) {
			return getAuthor( a );
		} );
	}
	/*
	 * Converts text to title case.
	 *
	 * BOOK IV. THE INSTRUCTIONS OF I -> Book IV. The Instructions of I.
	 *
	 * Takes care of:
	 *   - all-caps roman numerals
	 *   - always title-cases the first words after .
	 *   - otherwise title-cases words except a list of exceptions like 'a', 'of'
	 */
	var toTitleCase = function ( str ) {

		var titler = function ( word ) {
			if ( word.length === 0 ) {
				return word;
			}

			return word.replace( word[ 0 ], word[ 0 ].toUpperCase() );
		};

		var allCapped = function ( word ) {
			// check for roman numerals (and "I"), maybe followed by punct
			return ( word.search( /^[ivxlcdm]+\b.$/ ) > -1 );
		};

		// if bookish title case, not all words are capped
		var noCapWords = [ 'a', 'an', 'the', 'of', 'to', 'at', 'this', 'than',
			'then', 'by', 'and'
		];

		var words = str.toLowerCase().split( ' ' );

		var titled = [];

		var newSentence = true;

		for ( var i = 0; i < words.length; i++ ) {

			if ( allCapped( words[ i ] ) ) {
				// some words are all caps always
				titled.push( words[ i ].toUpperCase() );

			} else if ( newSentence || noCapWords.indexOf( words[ i ] ) === -1 ) {
				// new sentences and most words get title casing
				titled.push( titler( words[ i ] ) );
			} else {
				// lower
				titled.push( words[ i ] );
			}

			newSentence = words[ i ].search( /\.$/ ) !== -1;
		}

		return titled.join( ' ' );
	};

	var getFileNameFromIa = function ( iaId ) {

		var prom = getIaMeta( iaId )
			.then( function ( meta ) {

				var title = toTitleCase( meta.metadata.title );

				if ( meta.metadata.creator ) {
					var authors = getAuthors( meta.metadata.creator );

					const getSurname = function( a ) {
						return a.split( ' ' ).pop()
					}

					authors = authors.map( getSurname ).join( ', ' )

					if ( authors ) {
						title += ' - ' + authors
					}
				}

				if ( meta.metadata.year ) {
					title += ' - ' + meta.metadata.year;
				}

				return title;
			} );

		return prom;
	};

	var uploadToFilename = function ( iaId, filename ) {
		// eslint-disable-next-line compat/compat
		var iauUrl = new URL( 'https://ia-upload.toolforge.org' );

		iauUrl.searchParams.append( 'iaId', iaId );
		iauUrl.searchParams.append( 'commonsName', filename );

		window.open( iauUrl.href );
	};

	var onlinkClick = function ( iaId, uploadFilename ) {

		if ( uploadFilename ) {
			uploadToFilename( iaId, uploadFilename );
		} else {
			getFileNameFromIa( iaId )
				.then( function ( title ) {
					uploadToFilename( iaId, title );
				} );
		}
	};

	var thePopup;

	var onMouseover = function () {

		var $iaLink = $( this );

		var iaId = getIaIdFromUrl( $iaLink.attr( 'href' ) );

		if ( !iaId ) {
			return;
		}

		var uploadFilename = $iaLink.parent()
			.data( 'upload-filename' );

		var $uploadLink = $( '<a>' )
			.append( 'Upload with IA-Upload' )
			.on( 'click', function () {
				onlinkClick( iaId, uploadFilename );
			} );

		if ( uploadFilename ) {
			$uploadLink.append( ' to "' + uploadFilename + '"' );
		}

		var $popupContent = $( '<div>' )
			.append( $uploadLink );

		if ( !thePopup ) {
			thePopup = new OO.ui.PopupWidget( {
				$content: $popupContent,
				padded: true,
				width: 300,
				$floatableContainer: $iaLink,
				autoClose: true,
				classes: [ 'iaUploadPopup-popup' ]
			} );
			$( document.body ).append( thePopup.$element );
		} else {
			thePopup.setFloatableContainer( $iaLink );
			thePopup.$content = $popupContent;
		}

		thePopup.toggle( true );
	};

	$( function () {

		// eslint-disable-next-line no-jquery/no-global-selector
		$( 'a.external[href^="https://archive.org"]' )
			.on( 'mouseover', function ( event ) {
				var $hovered = $( this );
				setTimeout( function () {

					// popup if still hovering after 500ms
					if ( $hovered.is( ':hover' ) ) {
						onMouseover.call( $hovered, event );
					}
				}, IAUP.showTimeout );
			} );
	} );

// eslint-disable-next-line no-undef
}( jQuery, mediaWiki ) );