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

“MediaWiki:Gadget-inspect.js”的版本间差异

来自LLWiki
跳转到导航 跳转到搜索
第1行: 第1行:
// 由[[special:mypage/vector.js]]调用,可使用ES6语法
// 由ResourceLoader直接调用,可使用ES6语法
/**
/**
* @Author: [[User:Bhsd]]
* @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";
"use strict";
/*global mw, $, OO, CodeMirror*/
/*global mw, $, OO, CodeMirror, wgULS*/
const id = mw.config.get( 'wgArticleId' ),
mw.loader.using( 'mediawiki.util' ).then(() => {
script = mw.config.get('wgScript'),
let dialog, actionP, actionD;
gadgets = mw.gadgets || {},
const $content = $('#mw-content-text, #mw-imagepage-content').last(),
inspect = gadgets.inspect || {},
original = $content.children( '.mw-parser-output' ),
rule = inspect.rule || true;
placeholder = $('<div>', {class: "mw-parser-output"}).css('display', 'none'),
script = mw.config.get('wgScript'),
if (id > 0 && mw.config.get( 'wgNamespaceNumber' ) != 10 && mw.config.get('wgAction') == 'view' &&
mw.config.get( 'wgPageContentModel' ) == 'wikitext' && !mw.util.getParamValue( 'oldid' ) &&
id = mw.config.get( 'wgArticleId' ),
!mw.util.getParamValue( 'diff' ) && rule) {
urlDisplay = $('<a>', {href: "#"}).click(e => { e.preventDefault(); }),
const api = new mw.Api(),
css = mw.util.addCSS( '#mw-content-text .mw-parser-output p { border:1px dashed; }' +
getJSON = $.ajax({ dataType: 'json', cache: true,
url: script + '?title=mediawiki:gadget-CodeMirror.json&action=raw&ctype=application/json' });
mw.request = mw.request || api.get({action: 'query', revids: mw.config.get('wgRevisionId'), prop: 'revisions',
rvprop: 'content', curtimestamp: 1, formatversion: 2});
const 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; }'),
'#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; }' +
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); }' );
'.inspector { position:fixed; right:24px; left:unset !important; width:calc(50% - 7rem - 0.5px); }' );
cssHide.disabled = true;
cssHide.disabled = true;
var dialog, actionP, actionD, text, editor, wrapper, nextid;
const outer = $('<div>', {class: 'inspector mw-ajax-loader'}).insertBefore( original )
const $content = $('#mw-content-text, #mw-imagepage-content').last(),
original = $content.children( '.mw-parser-output' ),
placeholder = $('<div>', {class: "mw-parser-output"}).css('display', 'none'),
urlDisplay = $('<a>', {href: "#"}).click(function(e) { e.preventDefault(); }),
outer = $('<div>', {class: 'inspector mw-ajax-loader'}).insertBefore( original )
.on('contextmenu', '.cm-mw-template-name, .cm-mw-link-pagename', function(e) {
.on('contextmenu', '.cm-mw-template-name, .cm-mw-link-pagename', function(e) {
e.preventDefault();
e.preventDefault();
const ele = $(this),
const ele = $(this);
let url = ele.text();
promise = dialog ? Promise.resolve() : mw.loader.using( 'oojs-ui-windows' ).then(() => {
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 );
if (!mw.windowManager) {
mw.windowManager = new OO.ui.WindowManager();
$('body').append( mw.windowManager.$element );
}
if (!dialog) {
dialog = new OO.ui.MessageDialog();
dialog = new OO.ui.MessageDialog();
actionP = new OO.ui.ActionWidget({label: '是', target: '_blank', flags: 'progressive'});
actionP = new OO.ui.ActionWidget({label: '是', target: '_blank', flags: 'progressive'});
actionD = new OO.ui.ActionWidget({label: '否', flags: 'destructive'});
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] );
mw.windowManager.addWindows( [dialog] );
dialog.message.$label.html( ["要打开", urlDisplay, "吗?"] );
dialog.message.$label.html( [wgULS('在新标签页打开', '要在新標籤頁打開'), urlDisplay, wgULS('吗?', '嗎?')] );
}
actionP.setHref( script + '/' + url );
mw.windowManager.openWindow( dialog, {actions: [actionP, actionD]}).opening.then(function() {
actionP.$button.off( 'click' ).click(function() { dialog.close(); });
});
});
}),
let url = ele.text();
btns = [new OO.ui.ButtonWidget({label: '提交', flags: ['primary', 'progressive']}).on('click', function() {
if (ele.hasClass( 'cm-mw-template-name' )) { url = `模板:${url}`; }
btns[0].setDisabled( true );
else if (ele.next( '.cm-mw-link' ).text() == '#') {
mw.safeEdit(api, mw.request.curtimestamp, {pageid: id, text: editor.getValue(),
url += `#${ele.next().next( '.cm-mw-link-tosection' ).text()}`;
summary: wgULS('使用页面/文本对比查看器快速编辑', '使用頁面/文本對比察看器快速編輯')}).then(function() {
window.location.reload();
}, function(reason) { if (reason != 'editConflict') { btns[0].setDisabled( false ); }
});
}), new OO.ui.ButtonWidget({label: wgULS('预览', '預覽')}).on('click', function() {
btns[1].setDisabled( true );
console.log('API request: 请求预览');
const now = mw.now();
api.parse( editor.getValue(), {title: mw.config.get('wgPageName'), disablelimitreport: 1,
disableeditsection: 1} ).then(function(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);
}, function(reason) { mw.apiFailure(reason, wgULS('预览', '預覽')); }).then(function() {
btns[1].setDisabled( false );
});
}), new OO.ui.ButtonWidget({label: wgULS('还原', '復原'), flags: 'destructive'}).on('click', function() {
editor.setValue( text );
$content.children( '.mw-parser-output' ).replaceWith( original );
}), new OO.ui.ButtonWidget({label: wgULS('隐藏', '隱藏')}).on('click', function() {
css.disabled = !css.disabled;
cssHide.disabled = !cssHide.disabled;
wrapper.toggle();
btns[3].setLabel( css.disabled ? wgULS('显示', '顯示') : wgULS('隐藏', '隱藏'));
}), new OO.ui.ButtonWidget({flags: 'progressive', icon: 'next'})],
list = mw.storage.getObject( 'inspect-category' );
if (!list) { nextid = id + 1; }
else {
if (list[0][ list[1] ] == id) {
list[1]++;
mw.storage.setObject( 'inspect-category', list );
}
}
urlDisplay.text( url );
nextid = list[0][ list[1] ];
}
promise.then(() => {
btns[4].setHref( '/?redirect=no&curid=' + nextid ).setDisabled( !nextid ).$element.contextmenu(function(e) {
actionP.setHref( `${script}/${url}` );
e.preventDefault();
mw.windowManager.openWindow( dialog, {actions: [actionP, actionD]}).opening.then(() => {
OO.ui.prompt( wgULS('请输入分类名:', '請輸入分類名:') ).then(function(cat) {
actionP.$button.off( 'click' ).click(() => { dialog.close(); });
});
if (cat === null) { return; }
});
if (cat === '') {
mw.storage.remove( 'inspect-category' );
});
btns[4].setHref( '/?redirect=no&curid=' + (id + 1) ).setDisabled( false );
mw.loader.using( 'jquery.ui' ).then(() => { outer.resizable({handles: 'w', minWidth: 350}); });
return;
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 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'})],
next = function() {
const list = mw.storage.getObject( 'inspect-category' );
let nextid = '';
if (!list) { nextid = id + 1; }
else {
if (list[0][ list[1] ] == id) {
list[1]++;
mw.storage.setObject( 'inspect-category', list );
}
nextid = list[0][ list[1] ];
if (!nextid) {
btns[4].setDisabled( true );
return;
}
}
}
btns[4].setDisabled( false );
if (!/^([Cc]ategory|分[类類]):/.test( cat )) { cat = 'Category:' + cat; }
console.log('API request: 查询标准的页面名');
btns[4].setHref( `/?redirect=no&curid=${nextid}` );
},
let now = mw.now();
api.get({action: 'query', titles: cat, converttitles: 1, formatversion: 2}).then(function(response) {
getJSON = $.ajax({ dataType: 'json', cache: true,
const target = response.query.pages[0];
url: '/zh?title=mediawiki:gadget-CodeMirror.json&action=raw&ctype=application/json' });
if (target.missing) {
btns[4].$element.contextmenu(e => {
mw.notify(wgULS('错误的分类名!', '錯誤的分類名!'), {type: 'error'});
e.preventDefault();
OO.ui.prompt( '请输入分类名:' ).then(cat => {
if (cat === null) { return; }
btns[4].setDisabled( false );
if (cat === '') {
mw.storage.remove( 'inspect-category' );
btns[4].setHref( `/?redirect=no&curid=${id + 1}` );
return;
return;
}
}
console.log('End API request: 已获得标准的页面名,用时 ' + (mw.now() - now) + ' ms');
if (!/^([Cc]ategory|分[类類]):/.test( cat )) { cat = `Category:${cat}`; }
console.log('API request: 查询标准的页面');
console.log('API request: 查询分类下的页面列表');
let now = mw.now();
now = mw.now();
api.get({action: 'query', titles: cat, converttitles: 1, formatversion: 2}).then(response => {
api.get({action: 'query', list: 'categorymembers', cmtitle: target.title, cmprop: 'ids',
const target = response.query.pages[0];
cmlimit: 'max', cmsort: 'timestamp', cmdir: 'older', formatversion: 2}).then(function(cm) {
console.log('End API request: 已获得分类下的页面列表,用时 ' + (mw.now() - now) + ' ms');
if (target.missing) {
mw.notify('错误的分类名!', {type: 'error'});
const pages = cm.query.categorymembers.map(function(ele) { return ele.pageid; });
if (pages.length === 0) {
mw.notify('该分类下无页面!', {type: 'warn'});
return;
return;
}
}
console.log(`End API request: 已获得标准的页面名,用时 ${mw.now() - now} ms`);
const currentIndex = pages[0] == id ? 1 : 0;
console.log('API request: 查询分类下的页面列表');
mw.storage.setObject( 'inspect-category', [pages, currentIndex] );
now = mw.now();
btns[4].setHref( '/?redirect=no&curid=' + pages[ currentIndex ] ).setDisabled( false );
}, function(reason) { mw.apiFailure(reason, wgULS('该分类下的页面列表', '該分類下的頁面列表')); });
api.get({action: 'query', list: 'categorymembers', cmtitle: target.title, cmprop: 'ids', cmlimit: 'max',
}, function(reason) { mw.apiFailure(reason, wgULS('标准页面名称', '標準頁面名稱')); });
cmsort: 'timestamp', cmdir: 'older', formatversion: 2}).then(cm => {
console.log(`End API request: 已获得分类下的页面列表,用时 ${mw.now() - now} ms`);
const pages = cm.query.categorymembers.map(ele => ele.pageid);
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].setDisabled( false ).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 );
next();
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'}); });
});
});
});
});
$.when(getJSON, mw.request).then(function(data) {
});
console.log('End API request: 已获得页面Wikitext');
text = data[1].query.pages[0].revisions[0].content;
outer.removeClass( 'mw-ajax-loader' );
editor = new CodeMirror(outer[0], {value: text, mode: 'text/mediawiki', mwConfig: data[0],
lineWrapping: true});
wrapper = $( editor.getWrapperElement() );
$('<div>', {html: btns.map(function(ele) { return ele.$element; })}).appendTo( outer );
}, function(reason) { mw.apiFailure(reason, 'CodeMirror' + wgULS('设置或页面', '設置或頁面') + 'Wikitext'); });
}

2020年12月23日 (三) 01:10的版本

// 由ResourceLoader直接调用,不可使用ES6语法
/**
 * @Author: [[User:Bhsd]]
 */
"use strict";
/*global mw, $, OO, CodeMirror, wgULS*/
const id = mw.config.get( 'wgArticleId' ),
    script = mw.config.get('wgScript'),
    gadgets = mw.gadgets || {},
    inspect = gadgets.inspect || {},
    rule = inspect.rule || true;
if (id > 0 && mw.config.get( 'wgNamespaceNumber' ) != 10 && mw.config.get('wgAction') == 'view' &&
    mw.config.get( 'wgPageContentModel' ) == 'wikitext' && !mw.util.getParamValue( 'oldid' ) &&
    !mw.util.getParamValue( 'diff' ) && rule) {
    const api = new mw.Api(),
        getJSON = $.ajax({ dataType: 'json', cache: true,
        url: script + '?title=mediawiki:gadget-CodeMirror.json&action=raw&ctype=application/json' });
    mw.request = mw.request || api.get({action: 'query', revids: mw.config.get('wgRevisionId'), prop: 'revisions',
        rvprop: 'content', curtimestamp: 1, formatversion: 2});
    const 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;
    var dialog, actionP, actionD, text, editor, wrapper, nextid;
    const $content = $('#mw-content-text, #mw-imagepage-content').last(),
        original = $content.children( '.mw-parser-output' ),
        placeholder = $('<div>', {class: "mw-parser-output"}).css('display', 'none'),
        urlDisplay = $('<a>', {href: "#"}).click(function(e) { e.preventDefault(); }),
        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);
        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 );
        if (!mw.windowManager) {
            mw.windowManager = new OO.ui.WindowManager();
            $('body').append( mw.windowManager.$element );
        }
        if (!dialog) {
            dialog = new OO.ui.MessageDialog();
            actionP = new OO.ui.ActionWidget({label: '是', target: '_blank', flags: 'progressive'});
            actionD = new OO.ui.ActionWidget({label: '否', flags: 'destructive'});
            mw.windowManager.addWindows( [dialog] );
            dialog.message.$label.html( [wgULS('要在新标签页打开', '要在新標籤頁打開'), urlDisplay, wgULS('吗?', '嗎?')] );
        }
        actionP.setHref( script + '/' + url );
        mw.windowManager.openWindow( dialog, {actions: [actionP, actionD]}).opening.then(function() {
            actionP.$button.off( 'click' ).click(function() { dialog.close(); });
        });
    }),
        btns = [new OO.ui.ButtonWidget({label: '提交', flags: ['primary', 'progressive']}).on('click', function() {
        btns[0].setDisabled( true );
        mw.safeEdit(api, mw.request.curtimestamp, {pageid: id, text: editor.getValue(),
            summary: wgULS('使用页面/文本对比查看器快速编辑', '使用頁面/文本對比察看器快速編輯')}).then(function() {
            window.location.reload();
        }, function(reason) { if (reason != 'editConflict') { btns[0].setDisabled( false ); }
        });
    }), new OO.ui.ButtonWidget({label: wgULS('预览', '預覽')}).on('click', function() {
        btns[1].setDisabled( true );
        console.log('API request: 请求预览');
        const now = mw.now();
        api.parse( editor.getValue(), {title: mw.config.get('wgPageName'), disablelimitreport: 1,
            disableeditsection: 1} ).then(function(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);
        }, function(reason) { mw.apiFailure(reason, wgULS('预览', '預覽')); }).then(function() {
            btns[1].setDisabled( false );
        });
    }), new OO.ui.ButtonWidget({label: wgULS('还原', '復原'), flags: 'destructive'}).on('click', function() {
        editor.setValue( text );
        $content.children( '.mw-parser-output' ).replaceWith( original );
    }), new OO.ui.ButtonWidget({label: wgULS('隐藏', '隱藏')}).on('click', function() {
        css.disabled = !css.disabled;
        cssHide.disabled = !cssHide.disabled;
        wrapper.toggle();
        btns[3].setLabel( css.disabled ? wgULS('显示', '顯示') : wgULS('隐藏', '隱藏'));
    }), new OO.ui.ButtonWidget({flags: 'progressive', icon: 'next'})],
        list = mw.storage.getObject( 'inspect-category' );
    if (!list) { nextid = id + 1; }
    else {
        if (list[0][ list[1] ] == id) {
            list[1]++;
            mw.storage.setObject( 'inspect-category', list );
        }
        nextid = list[0][ list[1] ];
    }
    btns[4].setHref( '/?redirect=no&curid=' + nextid ).setDisabled( !nextid ).$element.contextmenu(function(e) {
        e.preventDefault();
        OO.ui.prompt( wgULS('请输入分类名:', '請輸入分類名:') ).then(function(cat) {
            if (cat === null) { return; }
            if (cat === '') {
                mw.storage.remove( 'inspect-category' );
                btns[4].setHref( '/?redirect=no&curid=' + (id + 1) ).setDisabled( false );
                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(function(response) {
                const target = response.query.pages[0];
                if (target.missing) {
                    mw.notify(wgULS('错误的分类名!', '錯誤的分類名!'), {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', cmsort: 'timestamp', cmdir: 'older', formatversion: 2}).then(function(cm) {
                    console.log('End API request: 已获得分类下的页面列表,用时 ' + (mw.now() - now) + ' ms');
                    const pages = cm.query.categorymembers.map(function(ele) { return ele.pageid; });
                    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 ] ).setDisabled( false );
                }, function(reason) { mw.apiFailure(reason, wgULS('该分类下的页面列表', '該分類下的頁面列表')); });
            }, function(reason) { mw.apiFailure(reason, wgULS('标准页面名称', '標準頁面名稱')); });
        });
    });
    $.when(getJSON, mw.request).then(function(data) {
        console.log('End API request: 已获得页面Wikitext');
        text = data[1].query.pages[0].revisions[0].content;
        outer.removeClass( 'mw-ajax-loader' );
        editor = new CodeMirror(outer[0], {value: text, mode: 'text/mediawiki', mwConfig: data[0],
            lineWrapping: true});
        wrapper = $( editor.getWrapperElement() );
        $('<div>', {html: btns.map(function(ele) { return ele.$element; })}).appendTo( outer );
    }, function(reason) { mw.apiFailure(reason, 'CodeMirror' + wgULS('设置或页面', '設置或頁面') + 'Wikitext'); });
}