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 08:19, 20 November 2021 (suppress runs). 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('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function autoSectionLink() {
	if ($('input[name="wpSection"]').val() === 'new') return;
	let $widget = $('#wpSummaryWidget');
	if (!$widget.length) return;
	mw.loader.using([
		'jquery.textSelection', 'mediawiki.Title', 'mediawiki.util',
		'oojs-ui-core', 'oojs-ui.styles.icons-editing-core'
	], () => {
		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('change', update);
		});
		mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
			if (on) $codeMirror[0].CodeMirror.on('change', update);
		});
	});
});