Jump to content

User:Nardog/AutoSectionLink.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Nardog (talk | contribs) at 01:52, 19 November 2021 (now real-time). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using([
	'jquery.textSelection', 'mediawiki.Title', 'oojs-ui-core',
	'oojs-ui.styles.icons-editing-core'
])).then(function autoSectionLink() {
	let $widget = $('#wpSummaryWidget');
	if (!$widget.length) return;
	let input = OO.ui.infuse($widget);
	if (!input) return;
	let button = new OO.ui.ButtonWidget({
		framed: false,
		icon: 'undo',
		title: 'Restore previous section link'
	}).toggle().on('click', () => {
		let cache = button.getData();
		input.setValue(input.getValue().replace(
			/^(\/\*.*?\*\/)?\s*/,
			cache[0] ? '/* ' + cache[0] + ' */ ' : ''
		));
		updatePreview(cache[0]);
		cache.reverse();
	}).on('toggle', () => {
		input.$element.css('width', `calc(100% - ${button.$element.width()}px)`);
	});
	button.$element.css({ position: 'absolute', top: 0, right: 0, margin: 0 })
		.insertAfter($widget).parent().css('position', 'relative');
	let origLines, $textarea;
	let update = mw.util.debounce(500, () => {
		let lines = $textarea.textSelection('getContents').replace(/\s+$/, '').split('\n');
		let firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
		if (!firstLineNum) firstLineNum = 1;
		for (let i = 1, x = lines.length, y = origLines.length; i < x && lines[x - i] === origLines[y - i]; i++) {
			lines.pop();
		}
		let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 6;
		lines.slice(firstLineNum).forEach(line => {
			let match = line.match(re);
			if (match && match[1].length < lowest) lowest = match[1].length;
		});
		let head;
		lines.slice(0, firstLineNum).reverse().some(line => {
			let match = line.match(re);
			if (match && match[1].length < lowest) {
				head = match[2];
				return true;
			}
		});
		head = head && head
			.replace(/'''(.+?)'''|\[\[:?(?:[^\|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|tt|u|var)(?:\s[^[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
			.replace(/''(.+?)''/g, '$1')
			.trim();
		let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
		if (!match[1]) match[1] = '';
		if (match[1] === head) return;
		input.setValue((head ? '/* ' + head + ' */ ' : '') + match[2]);
		button.setData([match[1], head]).toggle(true);
		updatePreview(head);
	});
	let updatePreview = head => {
		let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
		if (!$preview.length) return;
		let url = head && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
		let text = head && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + head;
		let $ac = $preview.children('.autocomment');
		if ($ac.length && !$ac[0].previousSibling) {
			if (head) {
				$ac.children('a').attr('href', url).text(text);
			} else {
				let node = $ac[0].nextSibling;
				if (node && node.nodeType === Node.TEXT_NODE)
					node.textContent = node.textContent.replace(/^\s+/, '');
				$ac.remove();
			}
		} else if (head) {
			$('<span>').addClass('autocomment').append(
				$('<a>', {
					href: url,
					title: mw.config.get('wgPageName').replace(/_/g, ' '),
					text: text
				}),
				mw.messages.exists('colon-separator') ? mw.msg('colon-separator') : ': '
			).prependTo($preview);
		}
	};
	mw.hook('wikiEditor.toolbarReady').add($ta => {
		origLines = $ta.data('origtext').replace(/\s+$/, '').split('\n');
		$textarea = $ta.on('input', update);
	});
	mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
		if (on) $codeMirror[0].CodeMirror.on('change', update);
	});
});