您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
MediaWiki巡查工具 | A patrol tool for MediaWiki
当前为
// ==UserScript== // @name QuickPatrol_v2 // @namespace qp_tool_v2 // @version 1.89 // @description MediaWiki巡查工具 | A patrol tool for MediaWiki // @author teaSummer // @match *://*/wiki/* // @match *://*/w/* // @match *://*/index.php?* // @license MIT // @grant none // ==/UserScript== (function () { 'use strict'; // 配置 | Configuration const config = { liveUpdate: false, // 全局实时更新 | Global Live Update liveUpdateInterval: 1000, // 全局实时更新间隔(毫秒) | Global Live Update Interval (Millisecond) usingIPE: false, // 使用InPageEdit | Using InPageEdit rollbackMode: 'summary', // 回退模式,值为'summary'(可编辑摘要)、'confirm'(需确认)或'default'(默认) | Rollback Mode, values are 'summary', 'confirm' or 'default' maxRetries: 5 // 获取mwApi最大重试次数 | Maximum Retries of Getting mwApi }; // 本地化 | Localization const w = { 'en': { un: 'This edit has not yet been patrolled', ing: 'Quick patrolling...', done: 'Quick patrolled', t_un: 'Unpatrolled', g_un: 'Unpatrolled', hl: 'Highlighted: ' }, 'zh-hans': { un: '该编辑尚未巡查', ing: '快速巡查中…', done: '已快速巡查', t_un: '未巡查', g_un: '尚未巡查', hl: '已高亮:' }, 'zh-hant': { un: '該編輯尚未巡查', ing: '快速巡查中…', done: '已快速巡查', t_un: '未巡查', g_un: '尚未巡查', hl: '已明顯標示:' }, }; let mwApi, mwLang, rights, l, fail = 0, load = false; async function rollback_gadget() { if (config.rollbackMode == 'default') return; if (!(OO && OO.ui && OO.ui.confirm)) { await $('head').first().append('<link rel="stylesheet" type="text/css" href="https://fastly.jsdelivr.net/npm/oojs-ui/dist/oojs-ui-windows-wikimediaui.min.css" />'); await mw.loader.load('https://fastly.jsdelivr.net/npm/oojs-ui/dist/oojs-ui-windows.min.js'); } if (config.rollbackMode == 'summary') await mw.loader.load(`https://fastly.jsdelivr.net/gh/teaSummer/mcw@main/rollback/${mwLang}/Gadget-editableRollback.js`); if (config.rollbackMode == 'confirm') await mw.loader.load(`https://fastly.jsdelivr.net/gh/teaSummer/mcw@main/rollback/${mwLang}/Gadget-confirmRollback.js`); } async function init() { if (fail >= config.maxRetries) return; try { mwApi = await new mw.Api(); mwLang = Object.keys(await mw.language.data)[0]; if (['zh-cn', 'zh-hans', 'zh-hans-cn', 'zh-cn-hans', 'zh', 'cn'].indexOf(mwLang) != -1) mwLang = 'zh-hans'; else if (mwLang.startsWith('zh-')) mwLang = 'zh-hant'; if (Object.keys(w).indexOf(mwLang) == -1) mwLang = 'en'; l = w[mwLang]; if (!load) { load = true; await $('head').first().append(`<link rel="stylesheet" type="text/css" href="https://fastly.jsdelivr.net/gh/teaSummer/mcw@main/patrol/${mwLang}/Gadget-revisionPatrol.css" />`); await mw.loader.load(`https://fastly.jsdelivr.net/gh/teaSummer/mcw@main/patrol/${mwLang}/Gadget-revisionPatrol.js`); } } catch (e) { fail = fail + 1; if (fail < config.maxRetries) console.warn(`[QuickPatrol] Failed to call MediaWiki. Retrying... (${fail}/${config.maxRetries})`); else console.error(`[QuickPatrol] Failed to call MediaWiki. (${fail}/${config.maxRetries})`); new Promise(() => setTimeout(init, 2000)); return; } console.log('[QuickPatrol] Checking rights...'); rights = ( await mwApi.get({ action: 'query', meta: 'userinfo', uiprop: 'rights' }) ).query.userinfo.rights; if (!config.liveUpdate) main(); return; } function with_IPE() { $('.diff-version:not(.diff-hidden-history):not([title])').css({ color: 'blue', cursor: 'pointer' }); $('.diff-version:not(.diff-hidden-history)').click(function () { const me = $(this); if (me.attr('title')) return; const value = me.text().replace(/[^0-9]/g, ''); $(this).attr('title', l.ing).css('color', 'deeppink'); patrol( value, () => { me.text('✔').attr('title', l.done).css({ color: 'green', cursor: 'help' }); } ); return value; }); } async function main() { if (!rights) { if (fail >= config.maxRetries || !fail) init(); return; } rollback_gadget(); if (rights.includes('patrol')) { $('.mw-changeslist-reviewstatus-unpatrolled:not(.mw-rcfilters-ui-highlights-enhanced-toplevel), .revisionpatrol-unpatrolled').attr('data-mw-revid', function (_i, value) { const that = $(this); that.find('.revisionpatrol-icon-unpatrolled').after(`<span class="unpatrolled custom-unpatrolled" title="${l.g_un}">!</span>`); that.find('.revisionpatrol-icon-unpatrolled+.custom-unpatrolled').css({ color: 'red', 'font-weight': 'bold', position: 'absolute', left: '-0.8em', 'margin-left': '-1px', 'text-decoration': 'underline dotted', 'font-family': 'sans-serif' }); that.find('.revisionpatrol-icon-unpatrolled').remove(); that.find('.unpatrolled') .css('cursor', 'pointer') .click(async function () { let me = $(this); if (me.hasClass('custom-unpatrolled')) me.css('left', '-1em'); if (me.text() == '!') { $(this).text('#').attr('title', l.ing).css('color', 'magenta'); if (!value && that.attr('data-mw-logid')) { try { value = new RegExp(`"logid":${that.attr('data-mw-logid')},.+?,"revid":([0-9]+)`).exec(JSON.stringify((await mwApi .get({ action: 'query', list: 'logevents', leprop: 'ids', letitle: that.find('td.mw-enhanced-rc-nested').attr('data-target-page'), letype: that.attr('data-mw-logaction').split('/')[0], lelimit: 'max', format: 'json' }) )))[1]; } catch (e) { $(this).text('!').attr('title', l.un).css('color', 'red'); return; } } patrol( value, () => { me.text('✔').removeClass('unpatrolled').attr('title', l.done).css({ color: 'green', cursor: 'help' }); if (me.hasClass('custom-unpatrolled')) { me.css({ left: '-1.15em', 'font-weight': 'normal' }); } else { me.css('margin-left', '-0.1em'); } that.removeClass('mw-rcfilters-highlight-color-c5').removeClass('mw-changeslist-reviewstatus-unpatrolled'); that.attr('title', that.attr('title').replace(new RegExp(`(, |、\u200B)?${l.t_un}(、\u200B|, )?`, 'g'), '')); if (that.attr('title') == l.hl) that.removeAttr('title'); }, () => { if (me.hasClass('custom-unpatrolled')) me.css('left', '-0.8em') } ); } }); return value; }); if (config.usingIPE) with_IPE(); } } function patrol(revid, successFallback, exFailFallback = () => { }) { const failFallback = () => { console.warn(`[QuickPatrol] FAILED (revid: ${value})`); me.text('!').attr('title', l.un).css({ color: 'red', cursor: 'help' }); if (me.hasClass('custom-unpatrolled')) me.attr('title', l.g_un); exFailFallback(); } console.debug(`[QuickPatrol] TRYING (revid: ${revid})`); mwApi .get({ action: 'query', meta: 'tokens', type: 'patrol', format: 'json' }) .done((data) => { mwApi .post({ action: 'patrol', revid: revid, token: data.query.tokens.patroltoken, format: 'json' }) .done(() => { console.debug(`[QuickPatrol] SUCCEEDED (revid: ${revid})`); successFallback(); }) .fail(failFallback); }) .fail(failFallback); } window.addEventListener('load', init, false); if (config.liveUpdate) { window.setInterval(main, config.liveUpdateInterval); } else if (config.usingIPE) { window.setInterval(with_IPE, config.liveUpdateInterval); } })();