「MediaWiki:Gadget-Twinkle.js」:各本之異

刪去的內容 新增的內容
WAN233
無編輯摘要
WAN233
// Edit via Wikiplus
第二行:
* vim: set noet sts=0 sw=8:
* +-------------------------------------------------------------------------+
* | === 警告:全局小工具文件尚未完備 === |
* | 对此文件的修改会影响许多用户。 僅供測試,尚未翻譯 |
* | 修改或翻譯请联系维护請聯繫維護,[[User:逆襲的天邪鬼]] |
* +-------------------------------------------------------------------------+
*
* 从Github导入 [https://github.com/Xi-Plusvjudge1/twinkle],branch: lzh
* 所有修改都應該在儲存庫中進行,否則將在下次更新時遺失。
*
* ----------
*
* 这是Xiplus版本的Twinkle,新手、管理员及他们之间的用户的
* 好帮手搭档。请参见[[zh:WP:TW]]以获取更多信息。
*
* 维护者:[[User:逆襲的天邪鬼]](文言維基)、[[User:Jimmy Xu]](白話維基)
*/
// <nowiki>
 
//<nowiki>
/* global Morebits */
 
( function ( window, document, $, undefined ) { // Wrap with anonymous function
 
// Check if account is experienced enough to use Twinkle
if (!Morebits.userIsInGroup('autoconfirmed') && !Morebits.userIsInGroup('confirmed')) {
return;
}
 
var Twinkle = {};
window.Twinkle = Twinkle; // allow global access
 
// Check if account is experienced enough to use Twinkle
Twinkle.userAuthorized = Morebits.userIsInGroup( "autoconfirmed" ) || Morebits.userIsInGroup( "confirmed" );
 
// for use by custom modules (normally empty)
Twinkle.initCallbacks = [];
Twinkle.addInitCallback = function twinkleAddInitCallback( func ) {
Twinkle.initCallbacks.push( func );
};
 
Twinkle.defaultConfig = {};
/**
* Twinkle.defaultConfig.twinkle and Twinkle.defaultConfig.friendly
* This holds the default set of preferences used by Twinkle.
*
* This holds the default set of preferences used by Twinkle. (The |friendly| object holds preferences stored in the FriendlyConfig object.)
* It is important that all new preferences added here, especially admin-only ones, are also added to
* |Twinkle.config.sections| in twinkleconfig.js, so they are configurable via the Twinkle preferences panel.
* For help on the actual preferences, see the comments in twinkleconfig.js.
*
* Formerly Twinkle.defaultConfig.twinkle and Twinkle.defaultConfig.friendly
*/
Twinkle.defaultConfig.twinkle = {
// General
summaryAd: ' ([[WP:TW|TW]])'"",
deletionSummaryAd: ' ("([[WP:TW|TW]])')",
protectionSummaryAd: ' ("([[WP:TW|TW]])')",
userTalkPageMode: "tab",
blockSummaryAd: ' ([[WP:TW|TW]])',
userTalkPageMode: 'tab',
dialogLargeFont: false,
// Block
disabledModules: [],
disabledSysopModules: [],
 
// Block
defaultToPartialBlocks: false,
blankTalkpageOnIndefBlock: false,
// Fluff (revert and rollback)
customBlockReasonList: [],
openTalkPage: [ ],
 
// Fluff (revert and rollback)
openTalkPage: [ ],
openTalkPageOnAutoRevert: false,
markRevertedPagesAsMinor: [ '"vand'" ],
watchRevertedPages: [ ],
offerReasonOnNormalRevert: true,
confirmOnFluff: false,
showRollbackLinks: [ '"diff'", '"others'" ],
// DI (twinkleimage)
customRevertSummary: [],
 
// DI (twinkleimage)
notifyUserOnDeli: true,
deliWatchPage: '"default'",
deliWatchUser: '"default'",
// CSD
 
speedySelectionStyle: "buttonClick",
// CSD
speedySelectionStyle: 'buttonClick',
watchSpeedyPages: [ ],
markSpeedyPagesAsPatrolled: true,
 
// these next two should probably be identical by default
notifyUserOnSpeedyDeletionNomination: [ '"db'", 'g1'"g3", 'g2'"g4", 'g3', '"g5'", 'g11'"g8", 'g12', 'g13', 'g16', '"a1'", '"a2'", 'a5'"a3", 'a6'"a4", 'f6', '"r2', 'r3', 'r7'" ],
welcomeUserOnSpeedyDeletionNotification: [ '"db', 'g1', 'g2', 'g3', 'g5', 'g11', 'g12', 'g13', 'g16', 'a1', 'a2', 'a5', 'a6', 'f6', 'r2', 'r3', 'r7'" ],
promptForSpeedyDeletionSummary: [],
openUserTalkPageOnSpeedyDelete: [ ],
deleteTalkPageOnDelete: true,
deleteRedirectsOnDelete: true,
deleteSysopDefaultToDeletedeleteSysopDefaultToTag: false,
speedyWindowHeight: 500,
speedyWindowWidth: 800,
logSpeedyNominations: false,
speedyLogPageName: 'CSD日志'"提刪之誌",
noLogOnSpeedyNomination: [ 'o1'"g1" ],
enlargeG11Input: falsetrue,
// Unlink
 
unlinkNamespaces: [ "0", "10", "100", "118" ],
// Unlink
// Warn
unlinkNamespaces: [ '0', '10', '100', '118' ],
defaultWarningGroup: "1",
 
// Warn
defaultWarningGroup: '1',
combinedSingletMenus: false,
showSharedIPNotice: true,
watchWarnings: false,
oldSelect: false,
customWarningList: [],
// XfD
autoMenuAfterRollback: false,
xfdWatchDiscussion: "default",
 
xfdWatchPage: "default",
// XfD
xfdWatchUser: "default",
logXfdNominations: false,
xfdLogPageName: 'AFD日志',
noLogOnXfdNomination: [],
xfdWatchDiscussion: 'default',
xfdWatchPage: 'default',
xfdWatchUser: 'default',
markXfdPagesAsPatrolled: true,
// Hidden preferences
FwdCsdToXfd: Morebits.userIsSysop,
afdDefaultCategory: 'delete',
afdFameDefaultReason: '沒有足夠的可靠資料來源能夠讓這個條目符合[[Wikipedia:關注度]]中的標準',
afdSubstubDefaultReason: '過期小小作品',
XfdClose: Morebits.userIsSysop ? 'all' : 'hide',
 
// Copyvio
copyvioWatchPage: 'default',
copyvioWatchUser: 'default',
markCopyvioPagesAsPatrolled: true,
 
// Hidden preferences
revertMaxRevisions: 50,
batchMax: 5000,
batchdeleteChunks: 50,
batchMax: 5000,
batchProtectChunks: 50,
batchundeleteChunks: 50,
proddeleteChunks: 50,
};
revisionTags: 'Twinkle',
configPage: 'Wikipedia:Twinkle/参数设置',
projectNamespaceName: mw.config.get('wgFormattedNamespaces')[4],
sandboxPage: 'Wikipedia:沙盒',
 
// now some skin dependent config.
// Formerly defaultConfig.friendly:
if ( mw.config.get( "skin" ) === "vector" ) {
Twinkle.defaultConfig.twinkle.portletArea = "right-navigation";
Twinkle.defaultConfig.twinkle.portletId = "p-twinkle";
Twinkle.defaultConfig.twinkle.portletName = "TW";
Twinkle.defaultConfig.twinkle.portletType = "menu";
Twinkle.defaultConfig.twinkle.portletNext = "p-search";
} else {
Twinkle.defaultConfig.twinkle.portletArea = null;
Twinkle.defaultConfig.twinkle.portletId = "p-cactions";
Twinkle.defaultConfig.twinkle.portletName = null;
Twinkle.defaultConfig.twinkle.portletType = null;
Twinkle.defaultConfig.twinkle.portletNext = null;
}
 
Twinkle.defaultConfig.friendly = {
// Tag
// Tag
groupByDefault: true,
watchTaggedPages: false,
第一四六行 ⟶ 第一二四行:
markTaggedPagesAsMinor: false,
markTaggedPagesAsPatrolled: true,
tagArticleSortOrder: '"cat'",
 
// Stub
enableStub: true,
customTagList: [],
// Talkback
watchStubbedPages: false,
markStubbedPagesAsMinor: false,
stubArticleSortOrder: 'cat',
customStubList: [],
 
// Talkback
markTalkbackAsMinor: true,
insertTalkbackSignature: true, // always sign talkback templates
talkbackHeading: wgULS('回复通告', '"回覆通告')",
mailHeading: wgULS('您有新邮件!', '"您有新郵件!')",
 
// Shared
markSharedIPAsMinor: true
};
 
Twinkle.getPref = function twinkleGetPref( name ) {
// now some skin dependent config.
var result;
switch (mw.config.get('skin')) {
if ( typeof Twinkle.prefs === "object" && typeof Twinkle.prefs.twinkle === "object" ) {
case 'vector':
// look in Twinkle.prefs (twinkleoptions.js)
Twinkle.defaultConfig.portletArea = 'right-navigation';
Twinkle.defaultConfig.portletIdresult = 'p-Twinkle.prefs.twinkle'[name];
} else if ( typeof window.TwinkleConfig === "object" ) {
Twinkle.defaultConfig.portletName = 'TW';
// look in TwinkleConfig
Twinkle.defaultConfig.portletType = 'menu';
result = window.TwinkleConfig[name];
Twinkle.defaultConfig.portletNext = 'p-search';
}
break;
case 'timeless':
Twinkle.defaultConfig.portletArea = '#page-tools .sidebar-inner';
Twinkle.defaultConfig.portletId = 'p-twinkle';
Twinkle.defaultConfig.portletName = 'Twinkle';
Twinkle.defaultConfig.portletType = null;
Twinkle.defaultConfig.portletNext = 'p-userpagetools';
break;
default:
Twinkle.defaultConfig.portletArea = null;
Twinkle.defaultConfig.portletId = 'p-cactions';
Twinkle.defaultConfig.portletName = null;
Twinkle.defaultConfig.portletType = null;
Twinkle.defaultConfig.portletNext = null;
}
 
if ( result === undefined ) {
return Twinkle.defaultConfig.twinkle[name];
}
return result;
};
 
Twinkle.getPrefgetFriendlyPref = function twinkleGetPreftwinkleGetFriendlyPref(name) {
var result;
// Temporarily disable summaryAd
if ( typeof Twinkle.prefs === "object" && typeof Twinkle.prefs.friendly === "object" ) {
if ($.inArray(name, ['summaryAd', 'deletionSummaryAd', 'protectionSummaryAd', 'blockSummaryAd']) !== -1) {
// look in Twinkle.prefs (twinkleoptions.js)
return '';
result = Twinkle.prefs.friendly[ name ];
} else if ( typeof window.FriendlyConfig === "object" ) {
// look in FriendlyConfig
result = window.FriendlyConfig[ name ];
}
 
if ( result === undefined ) {
if (typeof Twinkle.prefs === 'object' && Twinkle.prefs[name] !== undefined) {
return Twinkle.prefsdefaultConfig.friendly[ name ];
}
return result;
// Old preferences format, used before twinkleoptions.js was a thing
if (typeof window.TwinkleConfig === 'object' && window.TwinkleConfig[name] !== undefined) {
return window.TwinkleConfig[name];
}
if (typeof window.FriendlyConfig === 'object' && window.FriendlyConfig[name] !== undefined) {
return window.FriendlyConfig[name];
}
return Twinkle.defaultConfig[name];
};
 
 
 
第二一九行 ⟶ 第一七五行:
*
* Available navigation areas depend on the skin used.
* Vector:
* For each option, the outer div class contains "vector-menu", the inner div class is "vector-menu-content", and the ul is "vector-menu-content-list"
* "mw-panel", outer div class contains "vector-menu-portal". Existing portlets/elements: "p-logo", "p-navigation", "p-interaction", "p-tb", "p-coll-print_export"
* "left-navigation", outer div class contains "vector-menu-tabs" or "vector-menu-dropdown". Existing portlets: "p-namespaces", "p-variants" (menu)
* "right-navigation", outer div class contains "vector-menu-tabs" or "vector-menu-dropdown". Existing portlets: "p-views", "p-cactions" (menu), "p-search"
* Special layout of p-personal portlet (part of "head") through specialized styles.
* Monobook:
* "column-one", outer div class "portlet", inner div class "pBody". Existing portlets: "p-cactions", "p-personal", "p-logo", "p-navigation", "p-search", "p-interaction", "p-tb", "p-coll-print_export"
* Special layout of p-cactions and p-personal through specialized styles.
* Vector:
* "mw-panel", outer div class "portal", inner div class "body". Existing portlets/elements: "p-logo", "p-navigation", "p-interaction", "p-tb", "p-coll-print_export"
* "left-navigation", outer div class "vectorTabs" or "vectorMenu", inner div class "" or "menu". Existing portlets: "p-namespaces", "p-variants" (menu)
* "right-navigation", outer div class "vectorTabs" or "vectorMenu", inner div class "" or "menu". Existing portlets: "p-views", "p-cactions" (menu), "p-search"
* Special layout of p-personal portlet (part of "head") through specialized styles.
* Modern:
* "mw_contentwrapper" (top nav), outer div class "portlet", inner div class "pBody". Existing portlets or elements: "p-cactions", "mw_content"
第二四〇行 ⟶ 第一九五行:
* @return Node -- the DOM node of the new item (a DIV element) or null
*/
Twinkle.addPortlet = function( navigation, id, text, type, nextnodeid) {)
{
// sanity checks, and get required DOM nodes
//sanity checks, and get required DOM nodes
var root = document.getElementById(navigation) || document.querySelector(navigation);
var root = document.getElementById( navigation );
if (!root) {
if ( !root ) {
return null;
}
 
var item = document.getElementById( id );
if ( item ) {
if ( item.parentNode && item.parentNode === root ) {
return item;
}
第二五六行 ⟶ 第二一二行:
 
var nextnode;
if ( nextnodeid ) {
nextnode = document.getElementById(nextnodeid);
}
 
// verify/normalize input
var skin = mw.config.get('"skin'");
iftype = ( skin !=== '"vector'" ||&& type === "menu" && ( navigation !=== '"left-navigation'" &&|| navigation !=== '"right-navigation'" )) {? "menu" : "";
var outerDivClass;
type = null; // menu supported only in vector's #left-navigation & #right-navigation
var innerDivClass;
}
switch ( skin )
var outerDivClass, innerDivClass;
{
switch (skin) {
case '"vector'":
if ( navigation !== "portal" && navigation !== "left-navigation" && navigation !== "right-navigation" ) {
// XXX: portal doesn't work
navigation = "mw-panel";
if (navigation !== 'portal' && navigation !== 'left-navigation' && navigation !== 'right-navigation') {
navigation = 'mw-panel';
}
outerDivClass = 'vector-menu( vector-menu-' + (navigation === '"mw-panel'" ) ? '"portal'" : ( type === '"menu'" ? 'dropdown'"vectorMenu" : 'tabs'"vectorTabs" );
innerDivClass = 'vector( navigation === "mw-panel" ) ? "body" : ( type === "menu-content'" ? "menu" : "" );
break;
case '"modern'":
if ( navigation !== '"mw_portlets'" && navigation !== '"mw_contentwrapper'" ) {
navigation = '"mw_portlets'";
}
outerDivClass = '"portlet'";
innerDivClass = "pBody";
break;
case 'timeless':
outerDivClass = 'mw-portlet';
innerDivClass = 'mw-portlet-body';
break;
default:
navigation = '"column-one'";
outerDivClass = '"portlet'";
innerDivClass = "pBody";
break;
}
 
// Build the DOM elements.
var outerDiv = document.createElement('nav' "div" );
outerDiv.className = outerDivClass + " emptyPortlet";
outerDiv.setAttribute('aria-labelledby', id + '-label');
// Vector getting vector-menu-empty FIXME TODO
outerDiv.className = outerDivClass + ' emptyPortlet';
outerDiv.id = id;
if ( nextnode && nextnode.parentNode === root ) {
root.insertBefore( outerDiv, nextnode );
} else {
root.appendChild( outerDiv );
}
 
var h3h5 = document.createElement(' "h3'" );
if ( type === "menu" ) {
h3.id = id + '-label';
var ulspan = document.createElement('ul' "span" );
span.appendChild( document.createTextNode( text ) );
h5.appendChild( span );
 
var a = document.createElement( "a" );
if (skin === 'vector') {
a.href = "#";
// add invisible checkbox to keep menu open when clicked
// similar to the p-cactions ("More") menu
if (outerDivClass.indexOf('vector-menu-dropdown') !== -1) {
var chkbox = document.createElement('input');
chkbox.className = 'vectorMenuCheckbox vector-menu-checkbox'; // remove vectorMenuCheckbox after 1.35-wmf.37 goes live
chkbox.setAttribute('type', 'checkbox');
chkbox.setAttribute('aria-labelledby', id + '-label');
outerDiv.appendChild(chkbox);
 
$( a ).click(function ( e ) {
var span = document.createElement('span');
e.preventDefault();
span.appendChild(document.createTextNode(text));
h3.appendChild(span);
 
if ( !Twinkle.userAuthorized ) {
var a = document.createElement('a');
alert("抱歉,您需达自动确认后方可使用Twinkle。");
a.href = '#';
}
});
 
h5.appendChild( a );
$(a).click(function(e) {
e.preventDefault();
});
 
h3.appendChild(a);
}
 
outerDiv.appendChild(h3);
ul.className = 'menu vector-menu-content-list'; // remove menu after 1.35-wmf.37 goes live
} else {
h3h5.appendChild( document.createTextNode( text ) );
outerDiv.appendChild(h3);
}
outerDiv.appendChild( h5 );
 
var innerDiv = null;
if (innerDivClass) {
if ( type === "menu" ) {
var innerDiv = document.createElement('div');
innerDiv = document.createElement( "div" );
innerDiv.className = innerDivClass;
innerDiv.appendChild(ul);
outerDiv.appendChild(innerDiv);
} else {
outerDiv.appendChild(ul);
}
 
var ul = document.createElement( "ul" );
(innerDiv || outerDiv).appendChild( ul );
 
return outerDiv;
 
};
 
第三五八行 ⟶ 第二九六行:
* @param task: Either a URL for the portlet link or a function to execute.
*/
Twinkle.addPortletLink = function( task, text, id, tooltip) {)
{
if (Twinkle.getPref('portletArea') !== null) {
if ( Twinkle.getPref("portletArea") !== null ) {
Twinkle.addPortlet( Twinkle.getPref(' "portletArea'" ), Twinkle.getPref(' "portletId'" ), Twinkle.getPref(' "portletName'" ), Twinkle.getPref(' "portletType'" ), Twinkle.getPref(' "portletNext'" ));
}
var link = mw.util.addPortletLink( Twinkle.getPref(' "portletId'" ), typeof task === '"string'" ? task : '"#'", text, id, tooltip );
if ( $.isFunction( task ) ) {
$('.client-js .skin-vector #p-cactions').css('margin-right', 'initial');
$( link ).click(function ( ev ) {
if ($.isFunction(task)) {
$(link).click(function (ev) {
task();
ev.preventDefault();
});
}
if ( $.collapsibleTabs ) {
$.collapsibleTabs.handleResize();
}
第三八一行 ⟶ 第三一九行:
*/
 
var scriptpathbefore = mw.util.wikiScript(' "index'" ) + '"?title='",
scriptpathafter = '"&action=raw&ctype=text/javascript&happy=yes'";
 
// Retrieve the user's Twinkle preferences
$.ajax({
url: scriptpathbefore + '"User:'" + encodeURIComponent( mw.config.get('"wgUserName'")) + '"/twinkleoptions.js'" + scriptpathafter,
dataType: '"text'"
})
.fail(function () { mw.util.jsMessage( "未能載入twinkleoptions.js" ); })
.done(function ( optionsText ) {
mw.notify(wgULS('未能加载您的Twinkle参数设置', '未能載入您的Twinkle偏好設定'), {type: 'error'});
})
.done(function (optionsText) {
 
// Quick pass if user has no options
if ( optionsText === ''"" ) {
return;
}
 
// Twinkle options are basically a JSON object with some comments. Strip those:
optionsText = optionsText.replace( /(?:^(?:\/\/[^\n]*\n)*\n*|(?:\/\/[^\n]*(?:\n|$))*$)/g, ''"" );
 
// First version of options had some boilerplate code to make it eval-able -- strip that too. This part may become obsolete down the line.
if ( optionsText.lastIndexOf(' "window.Twinkle.prefs = '", 0 ) === 0 ) {
optionsText = optionsText.replace( /(?:^window.Twinkle.prefs = |;\n*$)/g, ''"" );
}
 
try {
var options = JSON$.parseparseJSON( optionsText );
 
if (options) {
// Assuming that our options evolve, we will want to transform older versions:
if (options.twinkle || options.friendly) { // Old preferences format
//if ( options.optionsVersion === undefined ) {
Twinkle.prefs = $.extend(options.twinkle, options.friendly);
}// else {...
Twinkle// options.prefsoptionsVersion = options1;
//}
//if ( options.optionsVersion === 1 ) {
// v2 established after unification of Twinkle/Friendly objects
// ...
Twinkle.prefs.optionsVersion = Twinkle.prefs.optionsVersion || 1;
// options.optionsVersion = 2;
//}
// At the same time, twinkleconfig.js needs to be adapted to write a higher version number into the options.
 
if ( options ) {
Twinkle.prefs = options;
}
}
catch ( e ) {
mw.util.jsMessage("未能解析twinkleoptions.js");
mw.notify(wgULS('未能解析您的Twinkle参数设置', '未能解析您的Twinkle偏好設定'), {type: 'error'});
}
})
.always(function () {
$( Twinkle.load );
});
 
第四三〇行 ⟶ 第三七三行:
 
Twinkle.load = function () {
// Don't activate on special pages other than those"Contributions" listedso herethat they load faster, soespecially the watchlist.
var isSpecialPage = ( mw.config.get('wgNamespaceNumber') === -1 &&
// that others load faster, especially the watchlist.
mw.config.get('wgCanonicalSpecialPageName') !== "Contributions" &&
var activeSpecialPageList = [ 'Block', 'Contributions', 'AbuseLog', 'Recentchanges', 'Recentchangeslinked' ]; // wgRelevantUserName defined for non-sysops on Special:Block
mw.config.get('wgCanonicalSpecialPageName') !== "Prefixindex" ),
if (Morebits.userIsSysop) {
 
activeSpecialPageList = activeSpecialPageList.concat([ 'DeletedContributions', 'Prefixindex', 'BrokenRedirects' ]);
// Also, Twinkle is incompatible with Internet Explorer versions 8 or lower, so don't load there either.
}
isOldIE = ( $.client.profile().name === 'msie' );
if (mw.config.get('wgNamespaceNumber') === -1 &&
activeSpecialPageList.indexOf(mw.config.get('wgCanonicalSpecialPageName')) === -1) {
return;
}
 
// Prevent users that are not autoconfirmed from loading Twinkle as well.
// Prevent clickjacking
if ( isSpecialPage || isOldIE || !Twinkle.userAuthorized ) {
if (window.top !== window.self) {
return;
}
 
// Set custom Api-User-Agent header, for server-side logging purposes
Morebits.wiki.api.setApiUserAgent( 'Twinkle~zh~lzh/20.0 (' + mw.config.get( 'wgDBname' ) + ')' );
 
// Load all the modules in the order that the tabs should appearappears
// User/user talk-related
var twinkleModules = [
Twinkle.warn();
// User/user talk-related
// if ( Morebits.userIsInGroup('sysop') ) {
'arv', 'warn', 'block', 'talkback',
// Twinkle.block();
// Deletion
// }
'speedy', 'copyvio', 'xfd', 'image',
// Deletion
// Maintenance
Twinkle.speedy();
'protect', 'tag', 'stub',
Twinkle.xfd();
// Misc. ones last
// Maintenance
'diff', 'unlink', 'fluff', 'batchdelete', 'batchundelete'
// Twinkle.protect();
];
Twinkle.tag();
// Don't load modules users have disabled
// Misc. ones last
var disabledModules = Twinkle.getPref('disabledModules').concat(Twinkle.getPref('disabledSysopModules'));
Twinkle.diff();
twinkleModules.filter(function(mod) {
Twinkle.unlink();
return disabledModules.indexOf(mod) === -1;
Twinkle.config.init();
}).forEach(function(module) {
Twinkle[module].fluff.init();
if ( Morebits.userIsInGroup('sysop') ) {
});
Twinkle.batchdelete();
 
Twinkle.batchundelete();
if (Twinkle.getPref('XfdClose') !== 'hide') {
Twinkle.close();
}
Twinkle.config.init(); // Can't turn off
 
Twinkle.addPortletLink(mw.util.wikiScript('index') + '?title=' + Twinkle.getPref('configPage'), wgULS('设置', '設定'), 'tw-config', wgULS('设置Twinkle参数', '設定Twinkle參數'));
 
// Run the initialization callbacks for any custom modules
$( Twinkle.initCallbacks ).forEacheach(function (func k, v ) { v(); });
Twinkle.addInitCallback = function ( func ) { func(); };
func();
});
Twinkle.addInitCallback = function (func) {
func();
};
 
// Increases text size in Twinkle dialogs, if so configured
if ( Twinkle.getPref(' "dialogLargeFont'" ) ) {
mw.util.addCSS(' ".morebits-dialog-content, .morebits-dialog-footerlinks { font-size: 100% !important; } '" +
'".morebits-dialog input, .morebits-dialog select, .morebits-dialog-content button { font-size: inherit !important; }'" );
}
};
 
} ( window, document, jQuery )); // End wrap with anonymous function
 
// </nowiki>