User:Samwilson/GoogleOCR.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
function GoogleOcr() {

	var messages = {
		'en': {
			'ocr': 'OCR',
			'button': 'Use Google OCR to extract text from this image',
			'getting-image-info': "Getting image information.",
			'ocr-in-progress': 'OCR in progress',
			'insert': 'Insert',
			'cancel': 'Cancel',
			'no-text': 'No text could be found in the image.'
		}
	};
	var toolUrl = "https://tools.wmflabs.org/ws-google-ocr/api.php";
	var loadingGifUrl = 'https://upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif';
	var lang = mw.config.get( 'wgUserLanguage' );

	var GoogleOcr = {};
	
	GoogleOcr.Dialog = function googleOcrDialog( config ) {
	    GoogleOcr.Dialog.parent.call( this, config );
	}

	OO.inheritClass( GoogleOcr.Dialog, OO.ui.ProcessDialog );

	GoogleOcr.Dialog.static.name = 'GoogleOcrDialog';
	GoogleOcr.Dialog.static.title = getMsg( 'ocr' );
	GoogleOcr.Dialog.static.size = 'full';
	GoogleOcr.Dialog.static.actions = [
	    { action: 'insert', label: getMsg( 'insert' ), flags: 'primary' },
	    { label: getMsg( 'cancel' ), flags: 'safe' }
	];

	GoogleOcr.Dialog.prototype.getBodyHeight = function () {
		return 600;
	};

	GoogleOcr.Dialog.prototype.initialize = function () {
		var $panel;
		GoogleOcr.Dialog.parent.prototype.initialize.apply( this, arguments );
		this.$img = $( '<img>' )
			.css( 'width', '100%' );
		this.$imgWrap = $( '<div>' )
			.css( 'width', '50%' )
			.append( this.$img );
		this.$textarea = $( '<textarea>' )
			.css( { width: '50%' } );
		$panel = $( '<div>' )
			.css( { display: 'flex', height: '100%' } )
			.append( this.$imgWrap, this.$textarea );
		this.$body.append( $panel );
	};

	GoogleOcr.Dialog.prototype.getSetupProcess = function ( data ) {
		var dialog = this;
		return GoogleOcr.Dialog.super.prototype.getSetupProcess.call( this, data )
		.next( function () {
			dialog.pushPending();
			new mw.Api().get( {
				action: 'query',
				prop: 'imageinfo',
				titles: mw.config.get( 'wgPageName' ),
				iiprop: 'url',
				iiurlwidth: 1500
			} )
			.done( dialog.processImageInfoResult.bind( dialog ) )
			.fail( dialog.processImageInfoResult.bind( dialog ) )
			.always( function () { dialog.popPending(); } );
		}, this );
	};

	GoogleOcr.Dialog.prototype.processImageInfoResult = function ( response ) {
		var dialog = this;
		dialog.pushPending();
		if ( response.responseJSON !== undefined && response.responseJSON.error ) {
			console.log(response);
			dialog.popPending();
			mw.notify( mw.message( 'error' ) + ' ' + response.responseJSON.error.code + ' ' + response.responseJSON.error.message );
			return;
		}
		// Get thumb URL.
		var pageId = Object.keys( response.query.pages )[ 0 ];
		var imageUrl = response.query.pages[ pageId ].imageinfo[ 0 ].thumburl;
		var fullUrl = response.query.pages[ pageId ].imageinfo[ 0 ].url;
		dialog.$img.attr( 'src', imageUrl );
		this.$imgWrap.zoom( { url: fullUrl } );
		var requestUrl = toolUrl + "?image=" + imageUrl + "&lang="+lang;
		$.getJSON( requestUrl )
			.done( dialog.processOcrResult.bind( dialog ) )
			.fail( dialog.processOcrResult.bind( dialog ) ) // Same handler, for simplicity.
			.always( function () { dialog.popPending(); } );
	};

	GoogleOcr.Dialog.prototype.processOcrResult = function( response ) {
		if ( response.responseJSON !== undefined && response.responseJSON.error ) {
			console.log(response);
			mw.notify( mw.message( 'error' ) + ' ' + response.responseJSON.error.code + ' ' + response.responseJSON.error.message );
			return;
		}
		if ( response.text === undefined || response.text.length === 0 ) {
			mw.notify( getMsg( 'no-text' ) );
			return;
		}
		this.$textarea.val( response.text );
	}

	GoogleOcr.Dialog.prototype.getActionProcess = function ( action ) {
		var dialog = this;
		return GoogleOcr.Dialog.super.prototype.getActionProcess.call( this, action )
			.next( function () {
				if ( action === 'insert' ) {
					textSelectionOpts = {
						peri: '{{inscription |language=' + lang + ' |1=' + dialog.$textarea.val() + '}}',
						replace: true,
						selectPeri: false
					};
					$( '#wpTextbox1' ).textSelection( 'encapsulateSelection', textSelectionOpts );
					dialog.close();
				}
			} );
	};

	function getMsg( msg ) {
		if ( messages[ lang ] !== undefined && messages[ lang ][ msg ] !== undefined ) {
			return messages[ lang ][ msg ];
		} else if ( messages.en[ msg ] !== undefined ) {
			return messages.en[ msg ];
		} else {
			return '⟨' + msg + '⟩';
		}
	}

	function main() {
		var ocrDialog = new GoogleOcr.Dialog();
		OO.ui.getWindowManager().addWindows( [ ocrDialog ] );

		$( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', function () {
			var ocrButtonDetails = {
				type: 'button',
				icon: 'https://upload.wikimedia.org/wikipedia/commons/b/bd/GoogleOcr_WikiEditor_button.png',
				label: getMsg( 'ocr' ),
				action: {
					type: 'callback',
					execute: function() {
						OO.ui.getWindowManager().openWindow( ocrDialog );
					}
				}
			};
			var ocrButton = {
				section: 'main',
				group: 'insert',
				tools: { 'GoogleOcr': ocrButtonDetails }
			};
			$( "#wpTextbox1" ).wikiEditor( 'addToToolbar', ocrButton );
			$( "a[rel='GoogleOcr']" ).css("width", "42px");
		} );
	}

/* Zoom 1.7.21 license: MIT http://www.jacklmoore.com/zoom */
(function(o){var t={url:!1,callback:!1,target:!1,duration:120,on:"mouseover",touch:!0,onZoomIn:!1,onZoomOut:!1,magnify:1};o.zoom=function(t,n,e,i){var u,c,a,r,m,l,s,f=o(t),h=f.css("position"),d=o(n);return t.style.position=/(absolute|fixed)/.test(h)?h:"relative",t.style.overflow="hidden",e.style.width=e.style.height="",o(e).addClass("zoomImg").css({position:"absolute",top:0,left:0,opacity:0,width:e.width*i,height:e.height*i,border:"none",maxWidth:"none",maxHeight:"none"}).appendTo(t),{init:function(){c=f.outerWidth(),u=f.outerHeight(),n===t?(r=c,a=u):(r=d.outerWidth(),a=d.outerHeight()),m=(e.width-c)/r,l=(e.height-u)/a,s=d.offset()},move:function(o){var t=o.pageX-s.left,n=o.pageY-s.top;n=Math.max(Math.min(n,a),0),t=Math.max(Math.min(t,r),0),e.style.left=t*-m+"px",e.style.top=n*-l+"px"}}},o.fn.zoom=function(n){return this.each(function(){var e=o.extend({},t,n||{}),i=e.target&&o(e.target)[0]||this,u=this,c=o(u),a=document.createElement("img"),r=o(a),m="mousemove.zoom",l=!1,s=!1;if(!e.url){var f=u.querySelector("img");if(f&&(e.url=f.getAttribute("data-src")||f.currentSrc||f.src),!e.url)return}c.one("zoom.destroy",function(o,t){c.off(".zoom"),i.style.position=o,i.style.overflow=t,a.onload=null,r.remove()}.bind(this,i.style.position,i.style.overflow)),a.onload=function(){function t(t){f.init(),f.move(t),r.stop().fadeTo(o.support.opacity?e.duration:0,1,o.isFunction(e.onZoomIn)?e.onZoomIn.call(a):!1)}function n(){r.stop().fadeTo(e.duration,0,o.isFunction(e.onZoomOut)?e.onZoomOut.call(a):!1)}var f=o.zoom(i,u,a,e.magnify);"grab"===e.on?c.on("mousedown.zoom",function(e){1===e.which&&(o(document).one("mouseup.zoom",function(){n(),o(document).off(m,f.move)}),t(e),o(document).on(m,f.move),e.preventDefault())}):"click"===e.on?c.on("click.zoom",function(e){return l?void 0:(l=!0,t(e),o(document).on(m,f.move),o(document).one("click.zoom",function(){n(),l=!1,o(document).off(m,f.move)}),!1)}):"toggle"===e.on?c.on("click.zoom",function(o){l?n():t(o),l=!l}):"mouseover"===e.on&&(f.init(),c.on("mouseenter.zoom",t).on("mouseleave.zoom",n).on(m,f.move)),e.touch&&c.on("touchstart.zoom",function(o){o.preventDefault(),s?(s=!1,n()):(s=!0,t(o.originalEvent.touches[0]||o.originalEvent.changedTouches[0]))}).on("touchmove.zoom",function(o){o.preventDefault(),f.move(o.originalEvent.touches[0]||o.originalEvent.changedTouches[0])}).on("touchend.zoom",function(o){o.preventDefault(),s&&(s=!1,n())}),o.isFunction(e.callback)&&e.callback.call(a)},a.setAttribute("role","presentation"),a.alt="",a.src=e.url})},o.fn.zoom.defaults=t})(window.jQuery);

	main();
}

var isEditing = $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1,
	isFile = mw.config.get( 'wgCanonicalNamespace' ) === 'File';
if ( isEditing && isFile ) {
	var dependencies = [
		'oojs-ui-core',
		'oojs-ui-windows'
	];
	mw.loader.using( dependencies, $.ready ).then( GoogleOcr );
}