User:Mikevoir/global.js

importArticles({   type: 'script',    articles: [        'u:dev:MediaWiki:AjaxBatchDelete.js',        'u:dev:MediaWiki:Bang.js',        'u:dev:MediaWiki:FileUsageAuto-update/code.js',        'u:dev:MediaWiki:LastEdited/code.js',        'u:dev:MediaWiki:MassRename/code.js',        'u:dev:MediaWiki:MassNullEdit/code.js',        'u:dev:MediaWiki:PurgeButton.js',        'u:dev:MediaWiki:Wikimarks/code.js',    ] }); var config = mw.config.get(['wgDiffNewId', 'wgAction', 'wgCanonicalSpecialPageName', 'wgNamespaceNumber']);

// Load functions upon page load if (/comp|inter|loaded/.test(document.readyState)) { // Check we're in the editor screen if (['edit', 'submit'].includes(config.wgAction)) { waitFor('.wikiEditor-ui-linkSuggest', noBlankLinkSuggest); waitFor('.group-insert', quickOL); }	// Check we're in RC	if (config.wgCanonicalSpecialPageName == 'Recentchanges') { waitFor('.mw-thanks-thank-link', noThank); waitFor('.mw-changeslist-links > span:first-child', properLink); }	// Check we're in a diff or history page if (config.wgDiffNewId || config.wgAction == 'history') { waitFor('.mw-thanks-thank-link', noThank); properDiff; }	// Check we're in MessageWall or Main namespace if (config.wgNamespaceNumber == 1200 || config.wgNamespaceNumber == 0) { waitFor('.ProseMirror', messageLinkSuggest); } } else { document.addEventListener('DOMContentLoaded', function {		// Check we're in the editor screen		if (['edit', 'submit'].includes(config.wgAction)) {			waitFor('.wikiEditor-ui-linkSuggest', noBlankLinkSuggest);			waitFor('.group-insert', quickOL);		}		// Check we're in RC		if (config.wgCanonicalSpecialPageName == 'Recentchanges') {			waitFor('.mw-thanks-thank-link', noThank);			waitFor('.mw-changeslist-links > span:first-child', properLink);			document.addEventListener('mouseup', function(event){ // console.log(event); if (					event.target &&					event.target.classList.contains('oo-ui-labelElement-label') &&					event.target.innerHTML.match(/^View new changes since/g)				) { setTimeout(noThank, 7000); setTimeout(properLink, 7000); }			});		}		// Check we're in a diff or history page		if (config.wgDiffNewId || config.wgAction == 'history') {			waitFor('.mw-thanks-thank-link', noThank);			properDiff;		}	}); }

// No thanks function noThank { document.querySelectorAll('.mw-thanks-thank-link').forEach(function(el) {		if (el.parentNode.nodeName === 'SPAN'){			el.parentNode.remove;		}else{			if ( el.previousSibling.data === '( ' && el.nextSibling.data === ' )' ) {				el.nextSibling.remove;				el.previousSibling.remove;			}			el.remove;		}	}); }

// Make RC properly give links on diffs that include page creations function properLink { document.querySelectorAll('.mw-changeslist-links > span:first-child').forEach(		function(el) {			if (el.childNodes.length === 1 && el.childElementCount === 0){				var row = el.parentNode.parentNode.parentNode.parentNode.parentNode;				if (row.nodeName == 'TBODY') { row = row.parentNode; }				var pageName = row.querySelectorAll('.mw-changeslist-title')[0].attributes.title.nodeValue;				el.removeChild(el.firstChild); // delete plain text				var row_revid = row.getAttributeNode('data-mw-revid');				if (row_revid && row_revid.value) {					// single edit diff					el.appendChild(buildLink([row_revid.value, 0], pageName));				}else{					// multiple edit diff					var revisions = [];					row.querySelectorAll('tr.mw-rcfilters-ui-highlights-enhanced-nested.mw-changeslist-edit').forEach(function(edit) { // console.log(edit); //debug var edit_revid = edit.getAttributeNode('data-mw-revid'); if (edit_revid && edit_revid.value) { revisions[revisions.length] = edit_revid.value; }					});					// console.log(revisions); //debug					el.appendChild(buildLink(revisions, pageName));				}			}		}	); document.querySelectorAll('tr.mw-changeslist-src-mw-new.mw-rcfilters-ui-highlights-enhanced-nested').forEach(		function(row) {			if (!row.querySelector('.mw-changeslist-diff')){				var el = row.querySelector('td.mw-enhanced-rc-nested');				var pageName = row.querySelector('.mw-enhanced-rc-time a').title;				var targetNode = el.childNodes[3];				// console.log(targetNode);				var row_revid = row.getAttributeNode('data-mw-revid').value;				targetNode.parentNode.insertBefore(document.createTextNode(' | '), targetNode);				targetNode.parentNode.insertBefore(buildLink([row_revid.value, 0], pageName, 'prev'), targetNode);				targetNode.parentNode.insertBefore(document.createTextNode(')'), targetNode); targetNode.remove; }		}	);	function buildLink(revisions, page, label) {		// console.log(revisions); //debug		var link = document.createElement('a');		var from = revisions[revisions.length-1];		var to = revisions[0];

if (from == 0) { if (!label){label = 'diff';} link.classList.add('mw-changeslist-diff'); } else { if (!label){label = revisions.length + ' changes';} link.classList.add('mw-changeslist-groupdiff'); }

link.href = '/wiki/' + page + '?diff=' + to + '&oldid=' + from; link.title = page; link.innerHTML = label; return link; } }

// Properly display diff for page creation edits function properDiff { if (document.querySelectorAll('#mw-diff-ntitle1 > strong > a').item(0)) { var table = document.getElementsByClassName('diff')[0]; var api = new mw.Api; var revid = document.querySelectorAll('#mw-diff-ntitle1 > strong > a').item(0).href.replace(/^.+\?oldid=/g, ''); var api_opt = { action: 'compare', torev: revid, fromslots: 'main', 'fromtext-main': '', prop: 'diff|ids', formatversion: 2 };		if ( revid && document.querySelectorAll('#mw-diff-otitle1 > strong > a').item(0) && !document.querySelectorAll('#differences-prevlink').item(0) ) { //Add edit link to page creation diff table.querySelectorAll('#mw-diff-otitle4')[0].innerHTML = ' strong > a')[0].title +			'?diff=' +			document.querySelectorAll('#mw-diff-otitle1 > strong > a')[0].href.replace(/^.+\?oldid=/g, '') +			'&oldid=0" title="' +			document.querySelectorAll('#mw-diff-otitle1 > strong > a')[0].title +			'" id="differences-prevlink">← Older edit';

}else if (revid && !document.querySelectorAll('#differences-prevlink').item(0)) { //Render proper diff table.getElementsByClassName('diff-ntitle')[0].colSpan = 4; table.getElementsByClassName('diff-notice')[0].parentNode.remove; api.get(api_opt).then(function(data) {				table.innerHTML = '  ' + table.innerHTML;				table.querySelectorAll('tbody')[0].innerHTML = table.querySelectorAll('tbody')[0].innerHTML + data.compare.body;			}); }	} }

// Hide blank link suggestion popup as fandom cant be bothered to fix it function noBlankLinkSuggest { var parent = document.querySelector('.wikiEditor-ui-linkSuggest'); if (parent) { var targetNode = parent.querySelector('.oo-ui-selectWidget'); // console.log(targetNode); var hideIfBlank = function(mutations) { mutations.forEach(function(mutation){				var node = mutation.target;				if (node.childElementCount == 0) {					parent.classList.add('oo-ui-element-hidden');				}			}); };		var observer = new MutationObserver(hideIfBlank); observer.observe(targetNode, { childList: true }); } }

// Add buttons to add empty OL call with or without _tl params function quickOL { // Where button gets added var row = document.querySelector('.group-insert');

// Call insertions var $textbox = $( '#wpTextbox' ); var handler = function(event) { if (event.target.innerHTML == 'OL'){ $textbox.textSelection('replaceSelection', ''); }else if (event.target.innerHTML == 'OL_tl'){ $textbox.textSelection('replaceSelection', ''); }	};

// OL call with translation params var OL_TL = document.createElement('span'); OL_TL.classList.add('tool', 'oo-ui-widget', 'oo-ui-widget-enabled', 'oo-ui-buttonElement', 'oo-ui-buttonElement-frameless', 'oo-ui-iconElement', 'oo-ui-buttonWidget'); var OL_TL_button = document.createElement('a'); OL_TL_button.classList.add('oo-ui-buttonElement-button'); OL_TL_button.innerHTML = 'OL_tl'; OL_TL_button.role = 'button'; OL_TL_button.addEventListener('mousedown', handler); OL_TL.appendChild(OL_TL_button); row.insertBefore(OL_TL, row.children[0]); // console.log(OL_TL);

// OL call without translation params var OL = document.createElement('span'); OL.classList.add('tool', 'oo-ui-widget', 'oo-ui-widget-enabled', 'oo-ui-buttonElement', 'oo-ui-buttonElement-frameless', 'oo-ui-iconElement', 'oo-ui-buttonWidget'); var OL_button = document.createElement('a'); OL_button.classList.add('oo-ui-buttonElement-button'); OL_button.innerHTML = 'OL'; OL_button.role = 'button'; OL_button.addEventListener('mousedown', handler); OL.appendChild(OL_button); row.insertBefore(OL, row.children[0]); // console.log(OL); }

// Helper function to delay function until anchor element exists function waitFor(query, THEN, extraDelay) { // set up the mutation observer var observer = new MutationObserver(function (mutations, me) {		// `mutations` is an array of mutations that occurred		// `me` is the MutationObserver instance		var targetNode = document.querySelector(query);		if (targetNode) {			if (extraDelay) {setTimeout(THEN, extraDelay);}			else {THEN;}			me.disconnect; // stop observing			return;		}	}); // start observing observer.observe(document, {	 childList: true,	  subtree: true	}); }

function messageLinkSuggest { var textbox = document.querySelector('.ProseMirror'); var api = new mw.Api; var ooui = 0; var SEARCH = {}; // Add necessary styles that dont load outside editor screen var styleEl = document.createElement('style'); document.head.appendChild(styleEl); styleEl.sheet.insertRule(		'.wikiEditor-ui-linkSuggest-suggestion.oo-ui-optionWidget-highlighted, .wikiEditor-ui-linkSuggest-suggestion:hover {\n' +		'background-color: rgba(var(--theme-link-color--rgb),.15);\n' +		'color: var(--theme-link-color);\n' +		'}',		0	); // Suggestion list var suggestBox = document.createElement('div'); suggestBox.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget oo-ui-selectWidget-unpressed'; suggestBox.setAttribute('role', 'list'); suggestBox.setAttribute('aria-multiselectable', 'false'); // Build suggestion list's box var box__ = document.createElement('div'); box__.className = 'oo-ui-clippableElement-clippable oo-ui-popupWidget-body'; box__.style.width = '320px'; box__.style['max-width'] = '1889px'; box__.style.height = 'auto'; box__.style['max-height'] = '250px'; box__.style['overflow-y'] = 'scroll'; box__.appendChild(suggestBox); var box_ = document.createElement('div'); box_.className = 'oo-ui-popupWidget-popup wikiEditor-ui-linkSuggest-popup'; box_.style.padding = 0; box_.appendChild(box__); var anchorArrow = document.createElement('div'); anchorArrow.className = 'oo-ui-popupWidget-anchor'; anchorArrow.style.left = '12px'; var box = document.createElement('div'); box.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-floatableElement-floatable oo-ui-popupWidget-anchored oo-ui-popupWidget wikiEditor-ui-linkSuggest oo-ui-popupWidget-anchored-top'; box.style.position = 'absolute'; box.style['margin-top'] = '21px'; box.appendChild(box_); box.appendChild(anchorArrow); // Hide by default box.classList.add('mobile-only', 'hidden'); // Append box to area document.body.insertBefore(box, document.body.children[0]); // Hide and empty out when unfocusing list document.addEventListener('click', function(event) {		// console.log(event);		if (!event.target.closest('.wikiEditor-ui-linkSuggest')) {			suggestBox.removeAttribute('aria-activedescendant');			box.classList.add('mobile-only', 'hidden');			suggestBox.replaceChildren;		}	}); suggestBox.addEventListener('mouseover', function(event){		if ( event.target.classList.contains('oo-ui-labelElement-label') && event.target.closest('.wikiEditor-ui-linkSuggest-suggestion') ) {			handleOOUI(event);			event.target.closest('.wikiEditor-ui-linkSuggest-suggestion').classList.add('oo-ui-optionWidget-highlighted');		}	}); suggestBox.addEventListener('mouseout', function(event){		if ( event.target.classList.contains('oo-ui-labelElement-label') && event.target.closest('.wikiEditor-ui-linkSuggest-suggestion') && event.target.closest('.wikiEditor-ui-linkSuggest-suggestion').classList.contains('oo-ui-optionWidget-highlighted') ) {			event.target.closest('.wikiEditor-ui-linkSuggest-suggestion').classList.remove('oo-ui-optionWidget-highlighted');		}	}); // Start looking document.addEventListener('mouseup', function(event){		// console.log('mouse event: ', event);		if ( event.target.classList.contains('oo-ui-labelElement-label') || (				event.target.parentNode &&				event.target.parentNode.classList.contains('wikiEditor-ui-linkSuggest-suggestion')			) ) {dispatchLink;}		else if (event.target.closest('.ProseMirror')) {suggestLink(event);}	}); document.addEventListener('keydown', function(event){		if (['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(event.key) && event.target.classList.contains('ProseMirror')) {			//console.log('key event: ', event);			if (box.classList.contains('hidden')) {				suggestLink(event);			} else if (!box.classList.contains('hidden') && ['ArrowLeft', 'ArrowRight'].includes(event.key)) {				box.classList.add('mobile-only', 'hidden');				suggestBox.removeAttribute('aria-activedescendant');				suggestBox.replaceChildren;				suggestLink(event);			} else if (!box.classList.contains('hidden') && ['ArrowDown', 'ArrowUp'].includes(event.key)) {				event.preventDefault;				handleOOUI(event);			}		} else if (event.key == 'Enter' && event.target.classList.contains('ProseMirror') && suggestBox.getAttribute('aria-activedescendant')) {			event.preventDefault;			dispatchLink;		} 	}); function dispatchLink { var clickedNode = suggestBox.querySelector('#'+suggestBox.getAttribute('aria-activedescendant')); var targetPage = clickedNode.children[0].innerHTML; var linkNode = document.createElement('a'); var newNode = SEARCH.node.splitText(SEARCH.offset); linkNode.href = clickedNode.getAttribute('link-to'); linkNode.innerText = targetPage; textbox.appendChild(linkNode); // can't be added directly to the as the  will get stripped and return only plain text for some reason newNode.remove; // Close suggestion list suggestBox.removeAttribute('aria-activedescendant'); box.classList.add('mobile-only', 'hidden'); suggestBox.replaceChildren; }	function handleOOUI(event) { if (!suggestBox.getAttribute('aria-activedescendant')) { var firstOpt = suggestBox.querySelector('.oo-ui-labelElement'); if (!firstOpt.id) { ooui = ooui + 1; firstOpt.id = 'ooui-' + ooui; }			firstOpt.classList.add('oo-ui-optionWidget-highlighted'); suggestBox.setAttribute('aria-activedescendant', firstOpt.id); } else if (suggestBox.getAttribute('aria-activedescendant')) { var Tooui = suggestBox.getAttribute('aria-activedescendant'); var currentNode = suggestBox.querySelector('#'+Tooui); var newNode; var scrollChange = 0; if (event.type == 'keydown' && event.key == 'ArrowUp' && currentNode && currentNode.previousSibling) { newNode = currentNode.previousSibling; }			else if (event.type == 'keydown' && event.key == 'ArrowDown' && currentNode && currentNode.nextSibling) { newNode = currentNode.nextSibling; } else if (event.type == 'mouseover' && currentNode && event.target.closest('.wikiEditor-ui-linkSuggest-popup .oo-ui-selectWidget')){ newNode = event.target; if (newNode.classList.contains('oo-ui-labelElement-label')) { newNode = event.target.parentNode; } }			if (newNode) { if (box__.clientHeight < (newNode.offsetTop+newNode.clientHeight)) {scrollChange = newNode.clientHeight;} else if (box__.scrollTop > newNode.offsetTop) {scrollChange = -currentNode.clientHeight;} currentNode.classList.remove('oo-ui-optionWidget-highlighted'); newNode.classList.add('oo-ui-optionWidget-highlighted'); if (!newNode.id) { ooui = ooui + 1; newNode.id = 'ooui-' + ooui; }				box__.scrollTop = box__.scrollTop + scrollChange; suggestBox.setAttribute('aria-activedescendant', newNode.id); }		}	}	function suggestLink(event) { var caret; var link_regex = new RegExp('^.*\\[\\['); var ext_link_regex = new RegExp('^.*\\[([^\\[\\]]+)\\]$'); var raw_str = ''; var link_str = ''; while (true) { caret = getCaret(event.target); if ( caret && caret.data && caret.data.focusNode ) { break; }		}		if ( caret && caret.data && caret.data.focusNode && caret.data.focusNode.nodeValue ) { if (link_regex.test(caret.data.focusNode.nodeValue)) { raw_str = caret.data.focusNode.nodeValue; link_str = raw_str.slice(0, caret.position).replace(/^.*\[\[/, ''); SEARCH.str = link_str; SEARCH.offset = raw_str.indexOf('[['+link_str);				SEARCH.node = caret.data.focusNode;				if (caret.data.type == 'Caret' && caret.position > 0 && link_str.length > 0 && raw_str.length > link_str.length) {					getPages(link_str);					document.querySelector('.wikiEditor-ui-linkSuggest').style.top = (event.pageY) + 'px';					document.querySelector('.wikiEditor-ui-linkSuggest').style.left = (event.pageX-12) + 'px';				} else if (caret.data.type == 'Range') {					getPages(link_str);					document.querySelector('.wikiEditor-ui-linkSuggest').style.top  = (event.pageY) + 'px';					document.querySelector('.wikiEditor-ui-linkSuggest').style.left = (event.pageX-12) + 'px';				}			} else if (ext_link_regex.test(caret.data.focusNode.nodeValue.slice(0, caret.position))) {				raw_str = caret.data.focusNode.nodeValue.slice(0, caret.position);				link_str = raw_str.replace(ext_link_regex, '$1').split(' ');				var url = link_str.shift;				if (link_str.length > 0) { link_str = link_str.join(' '); }				else { link_str = url; }				buildSuggestions([{					title: link_str,					linkto: url				}]);			}		}	}	function getCaret(element) {		//console.log(element);		var caretOffset = 0;		var doc = element.ownerDocument || element.document;		var win = doc.defaultView || doc.parentWindow;		var sel;		if (typeof win.getSelection != "undefined") {		    sel = win.getSelection;		    if (sel.rangeCount > 0) {		        var range = win.getSelection.getRangeAt(0);		        var preCaretRange = range.cloneRange;		        preCaretRange.selectNodeContents(element);		        preCaretRange.setEnd(range.endContainer, range.endOffset);		        caretOffset = preCaretRange.toString.length;		    }		} else if ( (sel = doc.selection) && sel.type != "Control") {		    var textRange = sel.createRange;		    var preCaretTextRange = doc.body.createTextRange;		    preCaretTextRange.moveToElementText(element);		    preCaretTextRange.setEndPoint("EndToEnd", textRange);		    caretOffset = preCaretTextRange.text.length;		}		return {			data: sel,			position: caretOffset		};	}	function getPages(prefix) {		api.get({			action: 'query',			list: 'prefixsearch',			pssearch: prefix		}).then(function(data) {			if (data && data.query && data.query.prefixsearch.length > 0) {				buildSuggestions(data.query.prefixsearch);			} else {				return;			}		});	}	function buildSuggestions(pages) {		// Build list		pages.forEach(			function(page){				var link = document.createElement('div');				link.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget wikiEditor-ui-linkSuggest-suggestion';				link.role = 'option';				link.tabindex = -1;				link.setAttribute('link-to', (page.linkto || ('https://genshin-impact.fandom.com/wiki/' + page.title)));				var label = document.createElement('span');				label.className = 'oo-ui-labelElement-label';				label.innerHTML = page.title;				link.appendChild(label);				suggestBox.appendChild(link);			}		);		document.querySelector('.wikiEditor-ui-linkSuggest-suggestion').focus;		box.classList.remove('mobile-only', 'hidden');	} }