Jump to content

User:NguoiDungKhongDinhDanh/SectionMover.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// For attribution: [[User:DannyS712/SectionMover.js]]
// jshint esversion: 6

$.when(mw.loader.using(['mediawiki.util', 'mediawiki.api']), $.ready).done(function() {
	if (mw.config.get('wgNamespaceNumber') === -1) {
		return;
	}
	
	var api = new mw.Api();
	var pagename = mw.config.get('wgPageName');
	
	var validSections = {};
	var fromTos = {};
	var wikiText, revStamp;
	
	$('head').append(
		$('<style>').text('a.arxylink { font-weight:bold } .arxyhighlight { background-color:#aef9fc }')
	);
	
	var $button = $('<button>').css({
		height: '2em',
		width: '5em',
		'font-size': '100%'
	});
	
	$('<div>').attr('id', 'moveandcopybuttons').css({
		position: 'fixed',
		right: '1em',
		bottom: '5em'
	}).append(
		$button.clone().attr({
			id: 'movebutton'
		}).text('Move'),
		'&nbsp;',
		$button.clone().attr({
			id: 'copybutton'
		}).text('Copy')
	).appendTo(document.body).toggle();
	
	$('#moveandcopybuttons button').click(function() {
		var numOfThreads, archiveTarget, sections,
			archiveThis, cutOffset, revisedPage;
		var copy = $(this).is('#copybutton');
		
		function cut(s, start, end) {
			return s.substr(0, start) + s.substring(end);
		}
		cutOffset = numOfThreads = 0;
		revisedPage = wikiText;
		sections = $('a.arxylink').map(function() {
			return $(this).attr('data-section');
		});
		numOfThreads = sections.length;
		if (!(numOfThreads)) {
			return alert('No sections selected, aborting');
		}
		archiveTarget = prompt(
			'Moving/Copying ' + numOfThreads + ' sections; where should they be moved/copied to?',
			pagename.replace(/_/g, ' ')
		).replace(/_/g, ' ');
		if (!archiveTarget || archiveTarget == pagename.replace(/_/g, ' ')) {
			alert('No target selected, aborting');
			return;
		}
		sections.each(function(i, n) {
			revisedPage =
				revisedPage.substr(0, fromTos[n][0] - cutOffset) +
				revisedPage.substring(fromTos[n][1] - cutOffset);
			cutOffset += fromTos[n][1] - fromTos[n][0];
		} );
		archiveThis = sections.map(function() {
			return wikiText.substring(fromTos[this][0], fromTos[this][1]);
		}).toArray().join('');
		console.log('archive this:', archiveThis);
		console.log('revised page:', revisedPage);
		
		function addToTarget(c) {
			api.postWithToken('csrf', {
				action: 'edit',
				title: archiveTarget,
				appendtext: '\n' + archiveThis,
				summary: (c ? 'Copied' : 'Moved') + ' sections from [[' + pagename.replace(/_/g, ' ') + ']] using [[:w:en:User:DannyS712/SectionMover|SectionMover]]'
			}).done(function(res2) {
				alert('Successfully added sections to page');
			}).fail(function(res2) {
				alert('Failed to add sections to page. Manual inspection needed.');
			}).always(function(res2) {
				console.log(arguments);
				window.location.reload();
			});
		}
		if (!copy) {
			api.postWithToken('csrf', {
				action: 'edit',
				title: pagename,
				text: revisedPage,
				summary: 'Moved sections to [[' + archiveTarget.replace(/_/g, ' ') + ']] using [[:w:en:User:DannyS712/SectionMover|SectionMover]]',
				basetimestamp: revStamp,
				starttimestamp: revStamp
			}).done(function(res1) {
				alert('Successfully moved sections from page');
				console.log(res1);
				addToTarget(false);
			}).fail(function(res1) {
				alert('Failed to move sections from page. Aborting.');
				console.log(arguments);
				window.location.reload();
			});
		} else {
			addToTarget(true);
		}
	});
	
	$(mw.util.addPortletLink(
		'p-cactions', '#', 'Move section',
		'pt-oeca', 'Enter/exit the process'
	)).click(function(e) {
		e.preventDefault();
		$('.arxylink').click();
		$('.arxy').toggle();
		$('#moveandcopybuttons').toggle();
	});
	
	api.get({
		action: 'parse',
		page: pagename,
		format: 'json'
	}).done(function(response1) {
		api.get({
			action: 'query',
			pageids: mw.config.get('wgArticleId'),
			prop: ['revisions'],
			rvprop: ['content', 'timestamp'],
			format: 'json'
		}).done(function(response2) {
			var rv = response2.query.pages[mw.config.get('wgArticleId')].revisions[0];
			wikiText = rv['*'];
			revStamp = rv.timestamp;
		});
		$(response1.parse.sections).filter(function(i, s) {
			return s.index == parseInt(s.index);
		}).each(function(i, s) {
			validSections[s.index] = s;
		});
		for (let i in validSections) {
			i = parseInt(i);
			fromTos[i] = [
				validSections[i].byteoffset,
				validSections.hasOwnProperty(i + 1) ? validSections[i + 1].byteoffset : Infinity
			];
		}
		$('#mw-content-text').find(':header').find('span.mw-headline').each(function(i, title) {
			var header, editSection, sectionNumber;
			header = $(this).parent();
			editSection = header.find('.mw-editsection'); // 1st child
			sectionNumber = header.find('.mw-editsection a:first');
			if (sectionNumber[0]) {
				sectionNumber = sectionNumber.attr('href').match( /&section=(\d+)/ );
				if (sectionNumber) {
					sectionNumber = sectionNumber[1];
				} else {
					// eg <h2>not a real section</h2>
					sectionNumber = undefined;
				}
			}
			if (validSections.hasOwnProperty(sectionNumber)) {
				editSection[0].innerHTML += '&nbsp;' +
					'<span class="arxy" style="display: none;">' +
						'<span class="mw-editsection-bracket">[</span>' +
						'<a class="arxy-inner" data-section="' + sectionNumber + '">select section</a>' +
						'<span class="mw-editsection-bracket">]</span>' +
					'</span>';
			}
		});
		$('.arxy-inner').click(function(e) {
			e.preventDefault();
			$(this).closest(':header').toggleClass('arxyhighlight');
			$(this).toggleClass('arxylink');
		});
	});
});