LLWiki正在建设中,欢迎加入我们

MediaWiki:Gadget-inspect.js

来自LLWiki
Bhsd讨论 | 贡献2020年12月22日 (二) 01:06的版本
跳转到导航 跳转到搜索

注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件
// 由[[special:mypage/vector.js]]调用,可以使用ES6语法
/**
 * @dependencies: mediawiki.api, mediawiki.storage, mediawiki.util, oojs-ui-core, oojs-windows, oojs-styles.icons-movement, jquery.ui, ext.CodeMirror.lib, ext.CodeMirror.mode.mediawiki
 */
"use strict";
/*global mw, $, OO, CodeMirror*/
mw.loader.using( 'mediawiki.util' ).then(() => {
    let dialog, actionP, actionD;
    const $content = $('#mw-content-text, #mw-imagepage-content').last(),
        original = $content.children( '.mw-parser-output' ),
        placeholder = $('<div>', {class: "mw-parser-output"}).css('display', 'none'),
        script = mw.config.get('wgScript'),
        id = mw.config.get( 'wgArticleId' ),
        urlDisplay = $('<a>', {href: "#"}).click(e => { e.preventDefault(); }),
        css = mw.util.addCSS( '#mw-content-text .mw-parser-output p { border:1px dashed; }' +
        '#mw-content-text .mw-parser-output { display:flow-root; overflow:hidden; word-wrap:break-word; }'),
        cssHide = mw.util.addCSS( '.inspector > div:last-child { margin-bottom:0.5em; }' +
        '.inspector { position:fixed; right:24px; left:unset !important; width:calc(50% - 7rem - 0.5px); }' );
    cssHide.disabled = true;
    const outer = $('<div>', {class: 'inspector mw-ajax-loader'}).insertBefore( original )
        .on('contextmenu', '.cm-mw-template-name, .cm-mw-link-pagename', function(e) {
        e.preventDefault();
        const ele = $(this),
            promise = dialog ? Promise.resolve() : mw.loader.using( 'oojs-ui-windows' ).then(() => {
            dialog = new OO.ui.MessageDialog();
            actionP = new OO.ui.ActionWidget({label: '是', target: '_blank', flags: 'progressive'});
            actionD = new OO.ui.ActionWidget({label: '否', flags: 'destructive'});
            if (!mw.windowManager) {
                mw.windowManager = new OO.ui.WindowManager();
                $('body').append( mw.windowManager.$element );
            }
            mw.windowManager.addWindows( [dialog] );
            dialog.message.$label.html( ["要打开", urlDisplay, "吗?"] );
        });
        let url = ele.text();
        if (ele.hasClass( 'cm-mw-template-name' )) { url = `模板:${url}`; }
        else if (ele.next( '.cm-mw-link' ).text() == '#') {
            url += `#${ele.next().next( '.cm-mw-link-tosection' ).text()}`;
        }
        urlDisplay.text( url );
        promise.then(() => {
            actionP.setHref( `${script}/${url}` );
            mw.windowManager.openWindow( dialog, {actions: [actionP, actionD]}).opening.then(() => {
                actionP.$button.off( 'click' ).click(() => { dialog.close(); });
            });
        });
    });
    mw.loader.using( 'jquery.ui' ).then(() => { outer.resizable({handles: 'w', minWidth: 350}); });
    mw.loader.using( ['mediawiki.api', 'mediawiki.storage', 'oojs-ui-core', 'oojs-ui.styles.icons-movement'] )
        .then(() => {
        const api = new mw.Api();
        mw.request = mw.request || api.get({action: 'query', revids: mw.config.get('wgRevisionId'), prop: 'revisions',
            rvprop: 'content', curtimestamp: 1, formatversion: 2});
        let text, editor, wrapper;
        const next = function() {
            const list = mw.storage.getObject( 'inspect-category' );
            if (!list) { return id + 1; }
            if (list[0][ list[1] ] == id) {
                list[1]++;
                mw.storage.setObject( 'inspect-category', list );
            }
            return list[0][ list[1] ];
        },
            btns = [new OO.ui.ButtonWidget({label: '提交', flags: ['primary', 'progressive']}).on('click', () => {
            btns[0].setDisabled( true );
            console.log('API request: 查询最新编辑时间戳');
            const now = mw.now();
            api.get({action: 'query', prop: 'revisions', pageids: id, rvprop: 'timestamp', formatversion: 2})
                .then(res => {
                console.log(`End API request: 已获得最新编辑时间戳,用时 ${mw.now() - now} ms`);
                if (new Date(res.query.pages[0].revisions[0].timestamp) > new Date(mw.request.curtimestamp)) {
                    mw.notify('编辑冲突!', {type: 'error'});
                    return;
                }
                api.postWithEditToken({action: 'edit', pageid: id, text: editor.getValue(),
                    summary: '使用页面/文本对比查看器快速编辑'}).then(() => {
                    window.location.reload();
                }, reason => { mw.notify(`编辑失败!错误信息:${reason}`, {type: 'error'}); });
            }, reason => { mw.notify(`无法获得最新编辑时间戳!错误信息:${reason}`, {type: 'error'}); });
        }), new OO.ui.ButtonWidget({label: '预览'}).on('click', () => {
            btns[1].setDisabled( true );
            console.log('API request: 请求预览');
            const now = mw.now();
            api.parse( editor.getValue(), { disablelimitreport: 1, disableeditsection: 1} ).then(html => {
                console.log(`End API request: 已生成预览,用时 ${mw.now() - now} ms`);
                if ($.contains( $content[0], original[0] )) { original.after( placeholder ).detach(); }
                $content.children( '.mw-parser-output' ).replaceWith( html );
                mw.hook( 'wikipage.content' ).fire($content);
                btns[1].setDisabled( false );
            }, reason => { mw.notify(`无法生成预览!错误信息:${reason}`, {type: 'error'}); });
        }), new OO.ui.ButtonWidget({label: '还原', flags: 'destructive'}).on('click', () => {
            editor.setValue( text );
            $content.children( '.mw-parser-output' ).replaceWith( original );
        }), new OO.ui.ButtonWidget({label: '隐藏'}).on('click', () => {
            css.disabled = !css.disabled;
            cssHide.disabled = !cssHide.disabled;
            wrapper.toggle();
            btns[3].setLabel( css.disabled ? '显示' : '隐藏');
        }), new OO.ui.ButtonWidget({flags: 'progressive', icon: 'next', href: `/?redirect=no&curid=${next()}`})],
            getJSON = $.ajax({ dataType: 'json', cache: true,
            url: '/zh?title=mediawiki:gadget-CodeMirror.json&action=raw&ctype=application/json' });
        btns[4].$element.contextmenu(e => {
            e.preventDefault();
            OO.ui.prompt( '请输入分类名:' ).then(cat => {
                if (!cat) { return; }
                if (!/^([Cc]ategory|分[类類]):/.test( cat )) { cat = `Category:${cat}`; }
                console.log('API request: 查询标准的页面名');
                let now = mw.now();
                api.get({action: 'query', titles: cat, converttitles: 1, formatversion: 2}).then(response => {
                    const target = response.query.pages[0];
                    if (target.missing) {
                        mw.notify('错误的分类名!', {type: 'error'});
                        return;
                    }
                    console.log(`End API request: 已获得标准的页面名,用时 ${mw.now() - now} ms`);
                    console.log('API request: 查询分类下的页面列表');
                    now = mw.now();
                    api.get({action: 'query', list: 'categorymembers', cmtitle: target.title, cmprop: 'ids', cmlimit: 'max',
                        formatversion: 2}).then(cm => {
                        console.log(`End API request: 已获得分类下的页面列表,用时 ${mw.now() - now} ms`);
                        const pages = cm.query.categorymembers.map(ele => ele.pageid).sort((a, b) => a > b);
                        if (pages.length === 0) {
                            mw.notify('该分类下无页面!', {type: 'warn'});
                            return;
                        }
                        const currentIndex = pages[0] == id ? 1 : 0;
                        mw.storage.setObject( 'inspect-category', [pages, currentIndex] );
                        btns[4].setHref( `/?redirect=no&curid=${pages[ currentIndex ]}` );
                    }, reason => { mw.notify(`无法获得该分类下的页面列表!错误信息:${reason}`, {type: 'error'}); });
                }, reason => { mw.notify(`无法获得页面名称!错误信息:${reason}`, {type: 'error'}); });
            });
        });
        $.when(getJSON, mw.loader.using( ['ext.CodeMirror.lib', 'ext.CodeMirror.mode.mediawiki'] )).then(config => {
            outer.removeClass( 'mw-ajax-loader' );
            editor = new CodeMirror(outer[0], {mode: 'text/mediawiki', mwConfig: config[0], lineWrapping: true});
            wrapper = $( editor.getWrapperElement() );
            $('<div>', {html: btns.map(ele => ele.$element)}).appendTo( outer );
            mw.request.then(data => {
                console.log('End API request: 已获得页面Wikitext');
                text = data.query.pages[0].revisions[0].content;
                editor.setValue( text );
            }, reason => { mw.notify(`无法获得页面Wikitext!错误信息:${reason}`, {type: 'error'}); });
        });
    });
});