Wikisłownikarz:Peter Bowman/add-translations.js: Różnice pomiędzy wersjami

Z Wikisłownika – wolnego słownika wielojęzycznego
Usunięta treść Dodana treść
jezeli nie znajdzie sekcji 'jezyk polski', niech poszuka 'termin obcy...'
problem z jezykami z nawiasami w nazwie, uzycie $.escapeRE
Linia 151: Linia 151:
gadget.index = a3 + 1;
gadget.index = a3 + 1;
} else {
} else {
targetRow = mw.format( '\\* +$1:', targetLang );
targetRow = mw.format( '\\* +$1:', $.escapeRE( targetLang ) );
a4 = translations.search( targetRow );
a4 = translations.search( targetRow );
Linia 380: Linia 380:
'mediawiki.util',
'mediawiki.util',
'mediawiki.api.edit',
'mediawiki.api.edit',
'jquery.mwExtension',
'ext.gadget.section-links'
'ext.gadget.section-links'
] )
] )

Wersja z 13:10, 1 maj 2015

( function ( mw, $ ) {
	var gadget = window.add_translations = {};
	
	var pageContent, pageDraft, api;
	var $transl, $defs, $buttonHolder;
	var starttimestamp, basetimestamp;
	
	var css = [
		'#transl-buttons { display: inline; margin: 0 5px; }',
		'#transl-buttons > small { cursor: pointer; font-weight: normal; margin: 0 5px; }',
		'#transl-editbox { border: 1px solid black; background-color: #F9F9F9; margin-top: 5px; font-weight: normal; }',
		'#transl-editbox > div { text-align: center; vertical-align: middle; margin: 5px; display: inline-block; }',
		'#transl-textinputs > div input:first-child { margin: 0 5px; }',
		'#transl-preview { width: 100%; }',
		'#transl-preview p { font-size: 13px; font-family: monospace, Courier; margin: 5px 0; }'
	];
	
	var messages = {
		'transl-add-translation': '(dodaj)',
		'transl-edit-summary':    'dodano tłumaczenie na $1',
		'transl-api-error':       'Prawdopodobnie nastąpił konflikt edycji. Przeładuj stronę i spróbuj ponownie.',
		'transl-lang-label':      'tłumaczysz na<br><strong>$1</strong>',
		'transl-preview-label':   'Podgląd zmian',
		'transl-apply-button':    'Pokaż zmiany',
		'transl-submit-button':   'Zapisz',
		'transl-watch-article':   'Dodaj do obserwowanych',
		'transl-submitting':      'Zapisywanie...'
	};
	
	gadget.init = function ( lang ) {
		this.lang = lang;
		this.preview = '';
		this.defn = [];
		this.index = 0;
		this.langs = [];
		
		$transl = $( 'dt.lang-pl.fldt-tlumaczenia' ).first();
		$defs   = $( 'dd.lang-pl.fldt-znaczenia' );
		
		if ( !$transl.length || !$defs.length ) {
			return;
		}
		
		$transl
			.children( '#transl' )
			.css( 'display', 'inline' );
		
		$buttonHolder = $( '<div>' )
			.attr( 'id', 'transl-buttons' )
			.appendTo( $transl );
		
		extractDefNums();
		
		if ( gadget.defn.length !== $defs.length ) {
			return;
		}
		
		api.get( {
			prop:        'revisions',
			rvprop:      [ 'timestamp', 'content' ],
			titles:       mw.config.get( 'wgPageName' ),
			indexpageids: true,
			curtimestamp: true
		} )
		.done( function ( data ) {
			var id   = data.query.pageids[ 0 ];
			var page = data.query.pages[ id ];
			
			pageContent    = page.revisions[ 0 ][ '*' ];
			starttimestamp = data.curtimestamp;
			basetimestamp  = page.revisions[ 0 ].timestamp;
		} )
		.done( function () {
			if ( analyzePage() ) {
				createMenu();
			}
		} );
	};
	
	function extractDefNums() {
		$defs.each( function () {
			var m, def = $( this ).children( 'dfn' ).text();
			
			if ( !def ) {
				def = $( this ).text();
			}
			
			m = def.match( /^(\(.+?\))/ );
			
			if ( m && m[ 0 ] && m[ 1 ] ) {
				gadget.defn.push( m[ 1 ] );
			} else {
				return false;
			}
		} );
	}
	
	function analyzePage() {
		var a2, a3, a4, b, langSection, translations, langs, targetLang, targetRow;
		var a = pageContent.indexOf( ' ({' + '{język polski' );
		
		if ( a === -1 ) {
			a = pageContent.indexOf( ' ({' + '{termin obcy w języku polskim' );
		}
		
		if ( a === -1 ) {
			return false;
		}
		
		b = pageContent.indexOf( '\n== ', a );
		langSection = pageContent.slice( 0, ( b !== -1 ) ? b : pageContent.length );
		a2 = langSection.indexOf( '{' + '{tłumaczenia}}\n', a );
		b = langSection.indexOf( '{' + '{źródła}}', a2 );
		
		if ( a2 === -1 || b === -1 ) {
			return false;
		}
		
		translations = langSection.slice( 0, b );
		a3 = translations.indexOf( '\n*', a2 );
		
		if (
			a3 !== -1 &&
			translations.slice( a3 ).indexOf( '{{zobtłum' ) !== -1
		) {
			a3 = translations.lastIndexOf( '{{zobtłum' );
			a3 = translations.indexOf( '\n*', a3 );
		}
		
		if ( a3 !== -1 ) {
			langs = [];
			
			$.each(
				translations.slice( a3 + 1, b ).split( '\n' ),
				function ( i, line ) {
					var res = line.match( /^\* +([^:]+):/ );
					
					if ( res && res[ 1 ] ) {
						langs.push( res[ 1 ] );
					}
				} );
			
			if ( !langs.length || langs.indexOf( gadget.lang ) !== -1 ) {
				return false;
			}
			
			gadget.langs = langs;
			targetLang = getLangPos( langs );
			
			if ( !targetLang ) {
				gadget.index = a3 + 1;
			} else {
				targetRow = mw.format( '\\* +$1:', $.escapeRE( targetLang ) );
				a4 = translations.search( targetRow );
				
				if ( a4 < a3 ) {
					return false;
				}
				
				gadget.index = translations.indexOf( '\n', a4 ) + 1;
			}
		} else {
			gadget.index = b;
		}
		
		return true;
	}
	
	function getLangPos( langs ) {
		var n, lang, _char, p1, p2;
		var abc = 'aąbcćdeęfghijklłmnńoópqrsśtuvwxyzźż';
		var target = gadget.lang;
		var index = -1;
		
		outer:
		for ( n = 0; n < langs.length; n++ ) {
			lang = langs[ n ];
			
			inner:
			for ( _char = 0; _char < lang.length; _char++ ) {
				p1 = abc.indexOf( target[ _char ] );
				p2 = abc.indexOf( lang[ _char ] );
				
				if ( p1 > p2 ) {
					index++;
					continue outer;
				} else if ( p1 === p2 ) {
					continue inner;
				} else {
					break outer;
				}
			}
		}
		
		return langs[ index ];
	}
	
	function onApplyChanges( gui, evt ) {
		var preview;
		var out = [];
		evt.preventDefault();
		
		gui.$textinputs
			.children()
			.each( function () {
				var terms, tmpls, temp;
				var $this = $( this );
				var $inputs = $this.children();
				var text = $inputs.first().val().trim();
				var tmpl = $inputs.last().val().trim();
				
				if ( !text ) {
					return true;
				}
				
				terms = text.split( / *, */ );
				tmpls = tmpl
					? tmpl.split( / *, */ )
					: null;
				temp = [];
				
				$.each( terms, function ( j, term ) {
					var s;

					if ( term.indexOf( '[' ) > -1 ) {
						s = term;
					} else {
						s = '[' + '[' + term + ']]';
					}
					
					if ( tmpls && tmpls[ j ] ) {
						s += ' {' + '{' + tmpls[ j ] + '}}';
					}
					
					temp.push( s );
				} );
				
				out.push( $this.data( 'num' ) + ' ' + temp.join( ', ' ) );
			} );
		
		if ( !out.length ) {
			return;
		}
		
		preview = mw.format( '$1: $2\n', gadget.lang, out.join( '; ' ) );
		
		pageDraft =
			pageContent.slice( 0, gadget.index ) +
			'* ' + preview +
			pageContent.slice( gadget.index, pageContent.length );
			
		gui.$preview.children( 'p' ).text( '* ' + preview );
		gui.$submit.prop( 'disabled', false );
		gui.$watch.prop( 'disabled', false );
		gadget.preview = preview;
	}
	
	function onSubmit( gui, evt ) {
		evt.preventDefault();
		
		gui.$submit
			.prop( 'disabled', true )
			.attr( 'value', mw.msg( 'transl-submitting' ) );
		
		api.postWithEditToken( {
			action:        'edit',
			title:          mw.config.get( 'wgPageName' ),
			text:           pageDraft,
			tags:           'script',
			summary:        mw.msg( 'transl-edit-summary', gadget.preview ),
			watchlist:      gui.$watch.prop( 'checked' ) ? 'watch' : 'nochange',
			starttimestamp: starttimestamp,
			basetimestamp:  basetimestamp
		} )
		.done( function () {
			window.location.reload();
		} )
		.fail( function () {
			alert( mw.msg( 'transl-api-error' ) );
		} );
	}
	
	function createMenu() {
		var gui = {};
		
		gui.$button = $( '<small>' )
			.text( mw.msg( 'transl-add-translation' ) )
			.attr( 'id', 'transl-addbutton' )
			.appendTo( $buttonHolder );
		
		gui.$textinputs = $( '<div>' )
			.attr( 'id', 'transl-textinputs' );
		
		$.each( gadget.defn, function ( i, def ) {
			$( '<div>' )
				.data( 'num', def )
				.append(
					def,
					$( '<input>' )
						.attr( {
							'type': 'text',
							'size': 70
						} ),
					$( '<input>' )
						.attr( {
							'type': 'text',
							'size': 1
						} )
				)
				.appendTo( gui.$textinputs );
		} );
						
		gui.$apply = $( '<input>' )
			.attr( {
				'type':  'submit',
				'value': mw.msg( 'transl-apply-button' )
			} )
			.on( 'click', $.proxy( onApplyChanges, this, gui ) );
				
		gui.$submit = $( '<input>' )
			.attr( {
				'type':  'submit',
				'value': mw.msg( 'transl-submit-button' )
			} )
			.prop( 'disabled', true )
			.on( 'click', $.proxy( onSubmit, this, gui ) );
		
		gui.$watch = $( '<input>' )
			.attr( {
				type: 'checkbox',
				id:   'transl-watch'
			} )
			.prop( {
				disabled: true,
				checked:  !!mw.user.options.get( 'watchdefault' )
			} );
		
		gui.$preview = $( '<div>' )
			.attr( 'id', 'transl-preview' )
			.append(
				$( '<strong>' ).text( mw.msg( 'transl-preview-label' ) ),
				$( '<p>' )
			);
		
		gui.$editbox = $( '<div>' )
			.attr( 'id', 'transl-editbox' )
			.hide()
			.append(
				$( '<div>' )
					.html( mw.msg( 'transl-lang-label', gadget.lang ) ),
				gui.$textinputs,
				$( '<div>' )
					.append(
						gui.$apply, gui.$submit, '<br>', gui.$watch,
						$( '<label>' )
							.attr( 'for', 'transl-watch' )
							.text( mw.msg( 'transl-watch-article' ) )
					),
				$( '<hr>' ),
				gui.$preview
			);
			
		$transl
			.append( gui.$editbox )
			.parent()
			.show();
		
		gui.$button.on( 'click', function () {
			gui.$editbox.toggle();
		} );
	}
	
	if (
		mw.config.get( 'wgNamespaceNumber' ) === 0 &&
		mw.config.get( 'wgAction' ) === 'view' &&
		window.customLang
	) {
		mw.loader.using( [
			'mediawiki.user',
			'mediawiki.util',
			'mediawiki.api.edit',
			'jquery.mwExtension',
			'ext.gadget.section-links'
		] )
		.done( function () {
			mw.util.addCSS( css.join( ' ' ) );
			mw.messages.set( messages );
			
			api = new mw.Api();
			
			mw.hook( 'wikipage.content' ).add( function () {
				gadget.init( customLang );
				
				if ( typeof hideTranslations === 'function' ) {
					hideTranslations( customLang );
				}
			} );
		} );
	}
}( mediaWiki, jQuery ) );