MediaWiki:Gadget-readableRC-core.js
Jump to navigation
Jump to search
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// <nowiki> // Formats the rows on Special:RecentChanges where all the information runs together // into three columns (page, diff/byte change, and user links) to make it more readable // // @author Iiii_I_I_I // // @TODO: support "Group changes by page" option being unchecked in Special:Preferences? (function ($, mw) { function runReadableRC($content) { if (!$content.hasClass('mw-changeslist')) { return; } $content.addClass('gadget-rc-enabled'); var rows = document.querySelectorAll('.mw-changeslist-line, ' + // does not include grouped edits '.mw-rcfilters-ui-highlights-enhanced-toplevel, ' + // first child in grouped edits '.mw-rcfilters-ui-highlights-enhanced-nested'); // subsequent children in grouped edits for (var i = 0; i < rows.length; i++) { var row = rows[i]; // nested rows (only visible after expanding grouped edits) if (row.classList.contains('mw-rcfilters-ui-highlights-enhanced-nested')) { row.classList.add('gadget-rc-nested'); if (row.classList.contains('mw-changeslist-edit')) { cleanNestedEdit(row); } else if (row.classList.contains('mw-changeslist-log')) { cleanNestedLog(row); } } // top-level rows (visible without uncollapsing any groups) else { // ignore parent element of grouped edits (text is in children, not container) if (row.classList.contains('mw-collapsible')) { continue; } // top-level row in grouped edits/log entries if (row.classList.contains('mw-rcfilters-ui-highlights-enhanced-toplevel')) { var parent = row.closest('.mw-collapsible'); if (parent.classList.contains('mw-changeslist-edit')) { cleanMultipleEdits(row); } else if (parent.classList.contains('mw-changeslist-log')) { cleanMultipleLogs(row); } } // row for single edit/log entries else { if (row.classList.contains('mw-changeslist-edit')) { cleanSingleEdit(row); } else if (row.classList.contains('mw-changeslist-log')) { cleanSingleLog(row); } } } } } function insert(row, newNode, referenceNode) { return row.querySelector(referenceNode).parentNode.insertBefore(row.querySelector(newNode), row.querySelector(referenceNode)); } function wrap(referenceNode, wrapperEl, wrapperClass) { var wrapper = document.createElement(wrapperEl); referenceNode.parentNode.insertBefore(wrapper, referenceNode); wrapper.appendChild(referenceNode); wrapper.classList.add(wrapperClass); } function cleanNestedLog(row) { // wrap "log name" (actually timestamp) together wrap(row.querySelector('.mw-enhanced-rc-time'), 'td', 'gadget-rc-logname'); // placeholder column with separator dots wrap(row.querySelector('.mw-changeslist-separator'), 'td', 'gadget-rc-logdots'); cleanUserLinks(row); // rename <td> row.querySelector('td.mw-enhanced-rc-nested').className = 'gadget-rc-logentry'; // rearrange newly created <td>s insert(row, '.gadget-rc-logname', '.gadget-rc-logentry'); insert(row, '.gadget-rc-logdots', '.gadget-rc-logentry'); } function cleanNestedEdit(row) { // wrap "page name" (actually revision links) together wrap(row.querySelector('.mw-enhanced-rc-time'), 'td', 'gadget-rc-pagename'); // remove two dot separators row.querySelector('.mw-changeslist-separator').remove(); row.querySelector('.mw-changeslist-separator').remove(); // wrap user stuff together $('.mw-userlink, .mw-usertoollinks, .comment, .mw-rollback-link, .mw-tag-markers, .history-deleted', row).wrapAll('<td class="gadget-rc-userlinks" />'); cleanUserLinks(row); // "rollback x edit(s)" -> "rollback" // link does not exist if it is a page creation or user does not have the right if (row.querySelector('.mw-rollback-link')) { row.querySelector('.mw-rollback-link a').textContent = 'rollback'; } // rename <td> row.querySelector('td.mw-enhanced-rc-nested').className = 'gadget-rc-diff'; // rearrange newly created <td>s insert(row, '.gadget-rc-userlinks', '.gadget-rc-diff'); insert(row, '.gadget-rc-pagename', '.gadget-rc-userlinks'); insert(row, '.gadget-rc-diff', '.gadget-rc-userlinks'); } function cleanMultipleLogs(row) { // log name wrap(row.querySelector('.mw-rc-unwatched'), 'td', 'gadget-rc-logname'); // remove square brackets from grouped usernames; cannot simply use remove() // since there might be other text in the same node, eg. "(4×)]" var users = row.querySelector('.changedby').childNodes; users[0].textContent = users[0].textContent.slice(1); // [ users[users.length - 1].textContent = users[users.length - 1].textContent.slice(0, -1); // ] // placeholder column with separator dots wrap(row.querySelector('.mw-changeslist-separator'), 'td', 'gadget-rc-logdots'); // rename <td> row.querySelector('.mw-changeslist-line-inner').className = 'gadget-rc-logentry'; // rearrange newly created <td>s insert(row, '.gadget-rc-logname', '.gadget-rc-logentry'); insert(row, '.gadget-rc-logdots', '.gadget-rc-logentry'); // stupid empty node row.querySelector('.gadget-rc-logentry').childNodes[0].remove(); } function cleanMultipleEdits(row) { // page name wrap(row.querySelector('.mw-title'), 'td', 'gadget-rc-pagename'); // "x changes" -> "diff" if (row.querySelector('.mw-changeslist-groupdiff')) { row.querySelector('.mw-changeslist-groupdiff').textContent = 'diff'; } // new pages have a text node instead of a link else { row.querySelector('.mw-changeslist-links span:first-child').textContent = 'diff'; } // "history" -> "hist" if (row.querySelector('.mw-changeslist-history')) { row.querySelector('.mw-changeslist-history').textContent = 'hist'; } // nonexistent pages (redirect-suppressed move or deleted) have a text node instead of a link else { var newHist = row.querySelector('.mw-changeslist-line-inner').childNodes[4].nodeValue.replace('history', 'hist'); row.querySelector('.mw-changeslist-line-inner').childNodes[4].nodeValue = newHist; } // list of user(s) wrap(row.querySelector('.changedby'), 'td', 'gadget-rc-userlinks'); // remove square brackets from grouped usernames; cannot simply use remove() // since there might be other text in the same node, eg. "(4×)]" var users = row.querySelector('.changedby').childNodes; users[0].textContent = users[0].textContent.slice(1); // [ users[users.length - 1].textContent = users[users.length - 1].textContent.slice(0, -1); // ] // rename <td> row.querySelector('.mw-changeslist-line-inner').className = 'gadget-rc-diff'; // rearrange newly created <td>s insert(row, '.gadget-rc-userlinks', '.gadget-rc-diff'); insert(row, '.gadget-rc-pagename', '.gadget-rc-userlinks'); insert(row, '.gadget-rc-diff', '.gadget-rc-userlinks'); } function cleanSingleLog(row) { // log name wrap(row.querySelector('.mw-changeslist-line-inner-logLink'), 'td', 'gadget-rc-logname'); // placeholder column with separator dots wrap(row.querySelector('.mw-changeslist-line-inner-separatorAfterLinks'), 'td', 'gadget-rc-logdots'); cleanUserLinks(row); // rename <td> row.querySelector('.mw-changeslist-line-inner').className = 'gadget-rc-logentry'; // rearrange newly created <td>s insert(row, '.gadget-rc-logname', '.gadget-rc-logentry'); insert(row, '.gadget-rc-logdots', '.gadget-rc-logentry'); } function cleanSingleEdit(row) { // page name wrap(row.querySelector('.mw-title'), 'td', 'gadget-rc-pagename'); // "rollback x edit(s)" -> "rollback" // link does not exist if it is a page creation or user does not have the right if (row.querySelector('.mw-rollback-link')) { row.querySelector('.mw-rollback-link a').textContent = 'rollback'; } // user info $('.mw-userlink, .mw-usertoollinks, .comment, .mw-rollback-link, .mw-tag-markers, .history-deleted', row).wrapAll('<td class="gadget-rc-userlinks" />'); cleanUserLinks(row); // rename <td> row.querySelector('.mw-changeslist-line-inner').className = 'gadget-rc-diff'; // rearrange newly created <td>s insert(row, '.gadget-rc-userlinks', '.gadget-rc-diff'); insert(row, '.gadget-rc-pagename', '.gadget-rc-userlinks'); insert(row, '.gadget-rc-diff', '.gadget-rc-userlinks'); } // (talk | contribs | block) -> (t|c|b) // possible variations: (talk), (talk | contribs), (talk | block), (talk | contribs | block), (username removed) function cleanUserLinks(row) { // if username has been revdeled (shows "(username removed)"), then exit if (row.querySelector('.history-deleted')) { return; } row.querySelector('.mw-usertoollinks-talk').textContent = 't'; // IPs don't have dedicated contribs link - it's linked in their username if (row.querySelector('.mw-usertoollinks-contribs')) { row.querySelector('.mw-usertoollinks-contribs').textContent = 'c'; } // non-admins don't have block link if (row.querySelector('.mw-usertoollinks-block')) { row.querySelector('.mw-usertoollinks-block').textContent = 'b'; } } function init() { var info = new OO.ui.PopupButtonWidget({ classes: ['gadget-rc-button'], framed: false, label: 'Broken?', popup: { head: true, label: 'Is the RecentChanges layout broken?', $content: $("<p><a href='/w/MediaWiki:Gadget-readableRC-core.js'>ReadableRC</a>, which formats this " + "page into columns, might have an error. If something looks wrong, disable this gadget in " + "your preferences and report the issue to <a href='/w/User_talk:Iiii_I_I_I'>Iiii I I I</a>.</p>"), padded: true, align: 'force-right', hideCloseButton: true } }) mw.hook('structuredChangeFilters.ui.initialized').add(function () { runReadableRC($('.mw-changeslist')); mw.hook('wikipage.content').add(runReadableRC); $('.mw-rcfilters-ui-liveUpdateButtonWidget').append(info.$element); }); } $(init); })(jQuery, mediaWiki); // </nowiki>