User:Mikevoir/betterDiff.js

$(function {   // Load dependencies and cache    importScriptPage('User:Mikevoir/lib.js', 'community');	var lib;	var api = new mw.Api;	var config = mw.config.get(['wgDiffNewId', 'wgAction', 'wgCanonicalSpecialPageName']);	// Main class	var betterDiff = {		init: function {			// Each mutation array represents a reload (e.g., through filter change)			var observer = new MutationObserver(function (mutations, me) { if (					mutations[0] &&					mutations[0].target &&					mutations[0].target.classList.contains('mw-rcfilters-ui-changesListWrapperWidget')				) {betterDiff.newDiffLink;} });			// Check we're in Special:RecentChanges			if (config.wgCanonicalSpecialPageName == 'Recentchanges') {				lib.waitFor('.mw-changeslist div', this.newDiffLink);				// start observing				observer.observe(document.querySelector('.mw-changeslist'), { childList: true, subtree: true });			}			// Check we're in Special:Contributions			else if (config.wgCanonicalSpecialPageName == 'Contributions') {				lib.waitFor('ul.mw-contributions-list li', this.newDiffLink);				// start observing				observer.observe(document.querySelector('ul.mw-contributions-list'), { childList: true, subtree: true });			}			// Check we're in a history page			else if (config.wgAction == 'history') {				lib.waitFor('.mw-history-histlinks', this.newDiffLink);			}			// Check we're in a diff page			else if (config.wgDiffNewId) {				lib.waitFor('#mw-diff-ntitle1', this.newDiff);			}		},		// Properly build diff links with page creation edits		newDiffLink: function {			var newDiffLink = {				searchRevid: function (row) {					var O = {						row: row,						revid: []					};					// Special:Contributions					if ( O.row.nodeName == 'LI' && O.row.getAttribute('data-mw-revid')) { 						O.revid.push(O.row.getAttribute('data-mw-revid')); // Page creation revision					// Special:RecentChanges					} else {						// sole edit						if (O.row.getAttribute('data-mw-revid')) { 							O.revid.push(O.row.getAttribute('data-mw-revid'));						// Top edit						} else if (O.row.classList.contains('mw-rcfilters-ui-highlights-enhanced-toplevel')) { O.revid.push(O.row.nextElementSibling.getAttribute('data-mw-revid')); // Last revision O.revid.push(O.row.parentElement.lastElementChild.getAttribute('data-mw-revid')); // Page creation revision }					}					if (O.revid.length>0) { return newDiffLink.buildLink(O); } else { return; }				},				buildLink: function(options) { var target = newDiffLink.getTarget(options.row); var page = newDiffLink.getTitle(options.row); if (target) { var link = document.createElement('a'); var from = options.revid[options.revid.length-1]; var to = options.revid[0]; var href = '/wiki/' + page + '?diff=' + to; if (from == to) { link.classList.add('mw-changeslist-diff'); } else { href = href + '&oldid=' + from; options.label = options.revid.length + ' changes'; link.classList.add('mw-changeslist-groupdiff'); }						link.href = href; link.title = page; if (target.nodeType == 3) { var split = /^([^\d\w]*)([\d\w\s]*)([^\d\w]*)$/.exec(target.textContent); link.innerHTML = split[2]; if (split[1].length>0) {target.parentNode.insertBefore(document.createTextNode(split[1]), target);} target.parentNode.insertBefore(link, target); if (split[3].length>0) {target.parentNode.insertBefore(document.createTextNode(split[3]), target);} target.remove; return; } else { link.innerHTML = options.label; target.replaceChildren(link); return; }					} else { return; } },				getTitle: function(row) { var title; var queries = [ '.mw-changeslist-title', // Normal Special:RecentChanges '.mw-changeslist-date', // Nested Special:RecentChanges '.mw-enhanced-rc-time > a' // Special:Contributions ];					queries.forEach(function(query) {						if (!title && row.querySelector(query) && row.querySelector(query).getAttribute('title')) {							title = row.querySelector(query).getAttribute('title');						}					}); return title || ''; },				getTarget: function(row) { var target; var queries = [ '.mw-changeslist-links:not(.mw-history-histlinks, .mw-usertoollinks) > span:first-child', // Special:Contributions && Normal Special:RecentChanges '.mw-changeslist-diff-cur + .mw-changeslist-separator', // Nested Special:RecentChanges '.mw-changeslist-links.mw-history-histlinks:not(.mw-usertoollinks) > span:last-child', // ?action=history ];					queries.forEach(function(query) {						var test = row.querySelector(query);						if (!target && test && test.classList.length==0) {							target = test.firstChild;						} else if (!target && test && test.classList.length>0 && test.classList.length>0) {							target = test.previousSibling;						}					}); return target; }			};			// Check we're in Special:RecentChanges if (config.wgCanonicalSpecialPageName == 'Recentchanges') { if (					document.querySelector('.mw-changeslist-src-mw-new') &&					( !document.querySelector('.mw-changeslist-src-mw-new .mw-changeslist-groupdiff') || !document.querySelector('.mw-changeslist-src-mw-new .mw-changeslist-diff') )				){					document.querySelectorAll('.mw-changeslist-src-mw-new').forEach(function(node){if (node) {newDiffLink.searchRevid(node);}}); }			}			// Check we're in Special:Contributions else if (config.wgCanonicalSpecialPageName == 'Contributions') { if (document.querySelector('ul.mw-contributions-list abbr.newpage')) { document.querySelectorAll('ul.mw-contributions-list abbr.newpage').forEach(function(node){						var row = node.parentElement;						if (row) {newDiffLink.searchRevid(row);}					}); }			}			// Check we're in a history page else if (config.wgAction == 'history') { if (!document.querySelector('ul.mw-contributions-list:last-of-type li:last-of-type .mw-history-histlinks > span:nth-child(2) > a')) { var node = document.querySelector('ul.mw-contributions-list:last-of-type li:last-of-type'); if (node) {newDiffLink.searchRevid(node);} }			}			if (nodes.length>0) { nodes.forEach(function(node){ }); }		},		// Properly display diff for page creation edits newDiff: function { if (document.querySelector('#mw-diff-ntitle1 > strong > a')) { var table = document.querySelector('.diff'); var revid = document.querySelector('#mw-diff-ntitle1 > strong > a').href.replace(/^.+\?oldid=/g, ''); var api_opt = { action: 'compare', torev: revid, fromslots: 'main', 'fromtext-main': '', prop: 'diff|ids', formatversion: 2 };				if ( revid && document.querySelector('#mw-diff-otitle1 > strong > a') && !document.querySelector('#differences-prevlink') ) { //Add edit link to page creation diff table.querySelector('#mw-diff-otitle4').innerHTML = ' strong > a').title +					'?diff=' +					document.querySelector('#mw-diff-otitle1 > strong > a').href.replace(/^.+\?oldid=/g, '') +					'&oldid=0" title="' +					document.querySelector('#mw-diff-otitle1 > strong > a').title +					'" id="differences-prevlink">← Older edit'; } else if (revid && !document.querySelector('#differences-prevlink')) { table.querySelector('.diff-ntitle').colSpan = 4; table.querySelector('.diff-notice').parentNode.remove; api.get(api_opt).then(function(data) {						table.innerHTML = '  ' + table.innerHTML;						table.querySelector('tbody').innerHTML = table.querySelector('tbody').innerHTML + data.compare.body;					}); }			}		}	};	// Start when API and LIB are loaded mw.loader.using('mediawiki.api').then(function{		mw.hook('userjs._LIB').add(function(_LIB){ lib = _LIB; betterDiff.init; });	}); });