Jump to content

User:NguoiDungKhongDinhDanh/QuickTranslation.js

From Meta, a Wikimedia project coordination wiki

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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/** <nowiki>
 * Quickly translate a page.
 * Documentation: [[User:NguoiDungKhongDinhDanh/QuickTranslation]]
 * 
 * For attribution: [[User:DannyS712/TranslationSource.js]]
**/

$(document).ready(() => {
	// 1198 is the translation namespace
	if (mw.config.get('wgNamespaceNumber') !== 1198 || mw.config.get('wgAction') !== 'view') {
		return;
	}
	
	// Load CSS file
	mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:NguoiDungKhongDinhDanh/QuickTranslation.css&action=raw&ctype=text/css', 'text/css');
	
	// Main functions
	var quickTranslationCore = function(docHTML, docTitle, sourceWikitext, translationWikitext) {
		// Hide the button
		$('#quickTranslationButton, #mw-content-text').hide();
		$('#quickTranslationButton').text('QuickTrans!');
		
		// Create form
		$('#quickTranslation-topbuttons').after(
			'<div id="quickTranslationEditor">' +
				(docHTML.length <= 0 ? '' :
					'<span class="quickTranslationLabel" id="quickTranslation-doc-span">' +
						'<label for="quickTranslation-doc">' +
							'<a href="/wiki/' + docTitle.replace(/ /g, '_') + '">Translation documentation</a>:' +
						'</label>'+
					'</span>' +
					'<div id="quickTranslation-doc">' +
						docHTML.replace(/mw-collapsible|mw-collapsed/g, '') +
					'</div>'
				) +
				'<span class="quickTranslationLabel" id="quickTranslation-sourcecode-span">' +
					'<label for="quickTranslation-sourcecode">' +
						'<a href="/wiki/' + 'Translations:' + sourceTitleUnit.replace(/ /g, '_') + '/en">Source code</a>:' +
					'</label>'+
				'</span>' +
				'<pre class="quickTranslationCode" id="quickTranslation-sourcecode">' +
				'</pre>' +
				(translationWikitext.length <= 0 ? '' :
					'<span class="quickTranslationLabel" id="quickTranslation-curtrans-span">' +
						'<label for="quickTranslation-curtrans">Current translation:</label>'+
					'</span>' +
					'<pre class="quickTranslationCode" id="quickTranslation-curtrans">' +
					'</pre>'
				) +
				'<span class="quickTranslationLabel" id="quickTranslation-yourtrans-span">' +
					'<label for="quickTranslation-yourtrans">Your translation:</label>'+
				'</span>' +
				'<div id="quickTranslation-yourtrans">' +
					'<textarea tabindex="0" name="wpText-quickTranslation" rows="15" id="quickTranslationEditorTextarea" \
					class="oo-ui-inputWidget-input">' +
					'</textarea>' +
				'</div>' +
				'<div id="quickTranslation-others">' +
					'<input type="text" placeholder="Optional edit summary..." \
					id="quickTranslationSummary" maxlength="255" value="' +
						'(via [[:metawikimedia:User:NguoiDungKhongDinhDanh/QT|QuickTranslation]])' + // Need some promotion here
					'">' +
					'<br>' +
					'<button class="mw-ui-button mw-ui-progressive quickTranslationButtons" \
					id="translationSubmit">Submit</button>' +
					'<button class="mw-ui-button mw-ui-destructive quickTranslationButtons" \
					id="translationCancel">Cancel</button>' +
				'</div>' +
			'</div>'
		);
		
		// Workaround to prevent parsing HTML tags in wikitext.
		$('#quickTranslation-sourcecode').text(sourceWikitext);
		$('#quickTranslation-curtrans').text(translationWikitext);
		$('#quickTranslationEditorTextarea').text(translationWikitext);
			
		// Event handlers
		$('#translationSubmit').click(function() {
			var submission = $('#quickTranslationEditorTextarea').val(),
				editsummary = $('#quickTranslationSummary').val();
			new mw.Api().postWithToken('csrf', {
				action: 'edit',
				title: fulltitle,
				text: submission,
				summary: editsummary,
				format: 'json'
			}).done(function() {
				$('#quickTranslationEditor').remove();
				mw.notify(
					'You have successfully submitted your translation. Reloading...',
					{
						title: 'Translation submitted!'
					}
				);
				location.reload();
			});
		});
		
		$('#translationCancel').click(function() {
			$('#quickTranslationEditor').remove();
			$('#quickTranslationButton, #mw-content-text').show();
		});
	},
		s = function(a) { // Standardize page names.
			return a.replace(/_/g, ' ');
		};
	
	// This is the part of Translations: and includes the unit and language
	var fulltitle = mw.config.get('wgPageName'),
		titleWithUnit = mw.config.get('wgTitle'),
		ta = titleWithUnit.split('/');
	
	// Trim off last 2 slashes
	var sourceTitle = ta.slice(0, ta.length - 2).join('/'),
		sourceTitleUnit = ta.slice(0, ta.length - 1).join('/'),
		sourceTitleUnitWithNs = 'Translations:' + sourceTitleUnit + '/en', // How can I get original page's lang?
		docTitle = 'Translations:' + sourceTitleUnit + '/qqq',
		unit = (ta[ta.length - 2] === 'Page display title' ? 0 : +ta[ta.length - 2]),
		links = function(o, b, c) {
			var a = [];
			if (c === 's' && typeof b === 'boolean') {
				if (b) a.push('Translations:' + sourceTitle);
				if (o === '+') a.push(unit + 1);
				else if (unit - 1 === 0) a.push('Page display title');
				else a.push(unit - 1);
				if (b) a.push('en');
			} else {
				if (b) a.push('Translations:' + sourceTitle);
				if (o === '+') a.push(unit + 1);
				else if (unit - 1 === 0) a.push('Page display title');
				else a.push(unit - 1);
				if (b) a.push(ta[ta.length - 1]);
			}
			if (!b && a[0] === 'Page display title') a[0] = 0;
			return a.join('/');
		},
		getwt = function(n, d) {
			if (!!d.query.pages[n].missing) {
				return '';
			} else {
				return d.query.pages[n].revisions[0].slots.main.content;
			}
		};
	
	// So that there will be no buttons on source page.
	if (s(fulltitle) === s(sourceTitleUnitWithNs)) return;
		
	// Add buttons after title
	$('#firstHeading').after($('<div>').attr('id', 'quickTranslation-topbuttons'));
	
	$('#quickTranslation-topbuttons').append(
		$('<button>')
		.text('QuickTrans!')
		.attr('class', 'mw-ui-button mw-ui-progressive')
		.attr('id', 'quickTranslationButton')
		.attr('title', sourceTitleUnitWithNs)
	);
	$('#quickTranslationButton').after(
		$('<span>')
		.attr('class', 'plainlinks')
		.attr('id', 'quickTranslation-links')
	);
	
	// Links to unit - 1 and unit + 1 pages
	var linksarray = [links('-', true, 's'), links('+', true, 's')];
	
	new mw.Api().get({
		action: 'query',
		prop: 'revisions',
		titles: linksarray,
		rvslots: '*',
		rvprop: 'content',
		formatversion: 2
	}).done(function(d) {
		var linkswt = [];
		
		for (let i = 0; i < 2; i++) {
			for (let j = 0; j < 2; j++) {
				if (d.query.pages[i].title === linksarray[j]) {
					linkswt[i] = getwt(j, d);
				}
			}
		}
		console.log(linkswt);
		
		if (linkswt[0].length > 0) {
			$('#quickTranslation-links').append(
				'<a href="/wiki/' + links('-', true) + '">' +
					'<span class="mw-ui-button">' + links('-', false) + '</span>' +
				'</a>'
			);
		}
		if (linkswt[1].length > 0) {
			$('#quickTranslation-links').append(
				'<a href="/wiki/' + links('+', true) + '">' +
					'<span class="mw-ui-button">' + links('+', false) + '</span>' +
				'</a>'
			);
		}
	});
	
	// Main function
	$('#quickTranslationButton').click(function(e) {
		e.preventDefault();
		$(this).text('Initializing...');
		var tid = mw.config.get('wgArticleId');
		new mw.Api().get({
			action: 'query',
			prop: 'revisions',
			titles: [sourceTitleUnitWithNs, fulltitle],
			rvslots: '*',
			rvprop: 'content',
			formatversion: 2
		}).done(function(response) {
			// Get source/target wikitext
			var sourceWikitext, translationWikitext,
				p = response.query.pages[0];
				
			if (tid !== p.pageid &&	typeof p.pageid != 'undefined') { // If the translation's id differs from first page's id,
                sourceWikitext = getwt(0, response); // then the first page is the source page.
                translationWikitext = getwt(1, response);
            } else { // Else, the second one is the source.
                sourceWikitext = getwt(1, response);
                translationWikitext = getwt(0, response);
            }
			
			if (sourceWikitext.length == 0) {
				$('#quickTranslation-topbuttons').remove();
				$('#firstHeading').after(
					'<strong class="error" style="color: #D33;" id="quickTranslationError">Source page doesn\'t exist!</span>'
				);
				setTimeout(function() {
					$('#quickTranslationError').fadeOut('slow', function() {
						$('#quickTranslationError, #quickTranslationButton').remove();
					});
				}, 1000);
				return;
			}
			
			new mw.Api().get({ // Get translation documentation. This one use a different API action.
				action: 'parse',
				page: docTitle,
				prop: 'text',
				wrapoutputclass: 'mw-parser-output',
				format: 'json',
				formatversion: 2
			}).then( // Dirty workaround...
				function(response) {
					quickTranslationCore(response.parse.text, docTitle, sourceWikitext, translationWikitext);
				},
				function() {
					quickTranslationCore('', docTitle, sourceWikitext, translationWikitext);
				}
			);
		});
	});
});

// </nowiki>