MediaWiki:Common.js

/** * Keep code in MediaWiki:Common.js to a minimum as it is unconditionally * loaded for all users on every wiki page. If possible create a gadget that is * enabled by default instead of adding it here (since gadgets are fully * optimized ResourceLoader modules with possibility to add dependencies etc.) **/

/** * JSconfig * * Global configuration options to enable/disable and configure * specific script features from MediaWiki:Common.js and MediaWiki:Monobook.js * This framework adds config options (saved as cookies) to Special:Preferences * For a more permanent change you can override the default settings in your * Special:Mypage/monobook.js * for Example: JSconfig.keys[loadAutoInformationTemplate] = false; * * Maintainer: User:Dschwen */ var JSconfig = { prefix: 'jsconfig_', keys: {}, meta: {}, // Register a new configuration item // * name      : String, internal name // * default_value : String or Boolean (type determines configuration widget) // * description  : String, text appearing next to the widget in the preferences, or an hash-object //   containing translations of the description indexed by the language code // * prefpage    : Integer (optional), section in the preferences to insert the widget: //   0 : User profile     User profile //   1 : Skin  Appearance //   2 : Math  Date and Time //   3 : Files  Editing //   4 : Date and time     Recent Changes //   5 : Editing Watchlist //   6 : Recent changes    Search Options //   7 : Watchlist       Misc //   8 : Search Gadgets //   9 : Misc // // Access keys through JSconfig.keys[name] registerKey: function (name, default_value, description, prefpage) { if (typeof JSconfig.keys[name] == 'undefined') { JSconfig.keys[name] = default_value; } else { // all cookies are read as strings, // convert to the type of the default value switch (typeof default_value) { case 'boolean': JSconfig.keys[name] = (JSconfig.keys[name] == 'true'); break; case 'number': JSconfig.keys[name] = JSconfig.keys[name] / 1; break; } }  JSconfig.meta[name] = { 'description': description[wgUserLanguage] || description.en || (typeof description == 'string' && description) || 'en translation missing', 'page': prefpage || 0, 'default_value': default_value }; // if called after setUpForm, we'll have to add an extra input field if (JSconfig.prefsTabs) { JSconfig.addPrefsInput(name); } }, readCookies: function { var cookies = document.cookie.split('; '); var p = JSconfig.prefix.length; var i; for (var key = 0; cookies && key < cookies.length; key++) { if (cookies[key].substring(0, p) == JSconfig.prefix) { i = cookies[key].indexOf('='); //alert( cookies[key] + ',' + key + ',' + cookies[key].substring(p,i) ); JSconfig.keys[cookies[key].substring(p, i)] = cookies[key].substring(i + 1); } } }, writeCookies: function  { var expdate = new Date; expdate.setTime(expdate.getTime + 1000 * 60 * 60 * 24 * 3650); // expires in 3560 days for (var key in JSconfig.keys) { document.cookie = JSconfig.prefix + key + '=' + JSconfig.keys[key] + '; path=/; expires=' + expdate.toUTCString; } }, evaluateForm: function { var w_ctrl, wt; //alert('about to save JSconfig'); for (var key in JSconfig.meta) { w_ctrl = document.getElementById(JSconfig.prefix + key); if (w_ctrl) { wt = typeof JSconfig.meta[key].default_value; switch (wt) { case 'boolean': JSconfig.keys[key] = w_ctrl.checked; break; case 'string': JSconfig.keys[key] = w_ctrl.value; break; }  }  }  JSconfig.writeCookies; return true; }, prefsTabs: false, setUpForm: function { var prefChild = document.getElementById('preferences'); if (!prefChild) { return; } prefChild = prefChild.childNodes; // // make a list of all preferences sections // var tabs = []; var len = prefChild.length; for (var key = 0; key < len; key++) { if (prefChild[key].tagName && prefChild[key].tagName.toLowerCase == 'fieldset') { tabs.push(prefChild[key]); } }  JSconfig.prefsTabs = tabs; // // Create Widgets for all registered config keys // for (var wkey in JSconfig.meta) { JSconfig.addPrefsInput(wkey); } addEvent(document.getElementById('preferences').parentNode, 'submit', JSconfig.evaluateForm); }, addPrefsInput: function (key) { var w_div = document.createElement('DIV'); var w_label = document.createElement('LABEL'); var wt = typeof JSconfig.meta[key].default_value; switch (wt) { case 'boolean': JSconfig.meta[key].description = ' ' + JSconfig.meta[key].description; break; default: //case 'string': JSconfig.meta[key].description += ': '; break; } w_label.appendChild(document.createTextNode(JSconfig.meta[key].description)); w_label.htmlFor = JSconfig.prefix + key; var w_ctrl = document.createElement('INPUT'); w_ctrl.id = JSconfig.prefix + key; // before insertion into the DOM tree switch (wt) { case 'boolean': w_ctrl.type = 'checkbox'; w_div.appendChild(w_ctrl); w_div.appendChild(w_label); break; default: //case 'string': w_ctrl.type = 'text'; w_div.appendChild(w_label); w_div.appendChild(w_ctrl); break; } JSconfig.prefsTabs[JSconfig.meta[key].page].appendChild(w_div); // after insertion into the DOM tree switch (wt) { case 'boolean': w_ctrl.defaultChecked = w_ctrl.checked = JSconfig.keys[key]; break; case 'string': w_ctrl.defaultValue = w_ctrl.value = JSconfig.keys[key]; break; } } }; JSconfig.readCookies; if (wgCanonicalSpecialPageName == 'Preferences') { $(document).ready(JSconfig.setUpForm); } /** extract a URL parameter from the current URL ********** * From en:User:Lupin/autoedit.js * * paramName : the name of the parameter to extract * url       : optional URL to extract the parameter from, document.location.href if not given. * * Local Maintainer: User:Dschwen, User:Lupo */ function getParamValue( paramName, url) { if (typeof (url) == 'undefined' || url === null) url = document.location.href; var cmdRe=RegExp( '[&?]' + paramName + '=([^&#]*)' ); // Stop at hash var m=cmdRe.exec(url); if (m && m.length > 1) return decodeURIComponent(m[1]); return null; } /** &withJS= URL parameter ******* * Allow to try custom scripts on the MediaWiki namespace without * editing Special:Mypage/monobook.js * * Maintainer: User:Platonides, User:Lupo */ var extraJS = getParamValue("withJS"); // Leave here for backwards compatibility (function (extraJS) { if (!extraJS) return; if (extraJS.match("^MediaWiki:[^&<>=%#]*\\.js$")) // Disallow some characters in file name importScript (extraJS); else {  // Dont use alert but the jsMsg system. Run jsMsg only once the DOM is ready.  addOnloadHook (function  { jsMsgAppend (document.createTextNode (extraJS + " javascript not allowed to be loaded."),'error'); }); } })(extraJS); /** Attach (or remove) an Event to a specific object ********** * Cross-browser event attachment (John Resig) * http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html * * obj : DOM tree object to attach the event to * type : String, event type ("click", "mouseover", "submit", etc.) * fn  : Function to be called when the event is triggered (the this *        keyword points to obj inside fn when the event is triggered) * * Local Maintainer: User:Dschwen */ function addEvent( obj, type, fn ) { if (obj.addEventListener) obj.addEventListener( type, fn, false ); else if (obj.attachEvent) { obj["e"+type+fn] = fn; obj[type+fn] = function { obj["e"+type+fn]( window.event ); } obj.attachEvent( "on"+type, obj[type+fn] ); } } function removeEvent( obj, type, fn ) { if (obj.removeEventListener) obj.removeEventListener( type, fn, false ); else if (obj.detachEvent) { obj.detachEvent( "on"+type, obj[type+fn] ); obj[type+fn] = null; obj["e"+type+fn] = null; } }

/** * Collapsible tables * * @version 2.0.2 (2014-03-14) * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js * @author User:R. Koot * @author User:Krinkle * @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which * is supported in MediaWiki core. */ /*global $, mw */ var autoCollapse = 2; var collapseCaption = '▲'; var expandCaption = '▼'; function collapseTable( tableIndex ) { var Button = document.getElementById( 'collapseButton' + tableIndex ); var Table = document.getElementById( 'collapsibleTable' + tableIndex ); if ( !Table || !Button ) { return false; }	var Rows = Table.rows; var i;	if ( Button.firstChild.data === collapseCaption ) { for ( i = 1; i < Rows.length; i++ ) { Rows[i].style.display = 'none'; }		Button.firstChild.data = expandCaption; } else { for ( i = 1; i < Rows.length; i++ ) { Rows[i].style.display = Rows[0].style.display; }		Button.firstChild.data = collapseCaption; } } function createClickHandler( tableIndex ) { return function ( e ) { e.preventDefault; collapseTable( tableIndex ); }; } function createCollapseButtons { var tableIndex = 0; var NavigationBoxes = {}; var Tables = document.getElementsByTagName( 'table' ); var i;	for ( i = 0; i < Tables.length; i++ ) { if ( $( Tables[i] ).hasClass( 'collapsible' ) ) { /* only add button and increment count if there is a header row to work with */ var HeaderRow = Tables[i].getElementsByTagName( 'tr' )[0]; if ( !HeaderRow ) { continue; }			var Header = HeaderRow.getElementsByTagName( 'th' )[0]; if ( !Header ) { continue; }			NavigationBoxes[tableIndex] = Tables[i]; Tables[i].setAttribute( 'id', 'collapsibleTable' + tableIndex ); var Button = document.createElement( 'span' ); var ButtonLink = document.createElement( 'a' ); var ButtonText = document.createTextNode( collapseCaption ); // TODO: Declare styles in MediaWiki:Gadget-collapsibleTables.css // Button.className = 'collapseButton'; Button.style.styleFloat = 'right'; Button.style.cssFloat = 'right'; Button.style.fontWeight = 'normal'; Button.style.textAlign = 'right'; Button.style.width = '6em'; ButtonLink.style.color = Header.style.color; ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex ); ButtonLink.setAttribute( 'href', '#' ); $( ButtonLink ).on( 'click', createClickHandler( tableIndex ) ); ButtonLink.appendChild( ButtonText ); Button.appendChild( document.createTextNode( '[' ) ); Button.appendChild( ButtonLink ); Button.appendChild( document.createTextNode( ']' ) ); Header.insertBefore( Button, Header.firstChild ); tableIndex++; }	}	for ( i = 0; i < tableIndex; i++ ) { if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) ||			( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) )		) { collapseTable( i ); }	} } mw.hook( 'wikipage.content' ).add( createCollapseButtons );

/**** Special:Upload enhancements ****** * moved to MediaWiki:Upload.js * *  Maintainer: User:Lupo ****/ JSconfig.registerKey('UploadForm_loadform', true, {  'bg': 'Използване на логиката на новия формуляр за качвания',  'en': 'Use new upload form logic', // default  'ru': 'Использовать новую логику формы загрузки' }, 3); JSconfig.registerKey('UploadForm_newlayout', true, {  'bg': 'Използване на облика на новия формуляр за качвания',  'en': 'Use new form layout', // default  'ru': 'Использовать новый интерфейс формы загрузки' }, 3);

function enableNewUploadForm { var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/); if (match) { var webKitVersion = parseInt(match[1], 10); if (webKitVersion < 420) return; // Safari 2 crashes hard with the new upload form... }

// honor JSConfig user settings if( !JSconfig.keys['UploadForm_loadform'] ) return;

importScript( 'MediaWiki:UploadForm.js' ); }

if (wgPageName == 'Special:Upload') { importScript( 'MediaWiki:Upload.js' ); // Uncomment the following line (the call to enableNewUploadForm) to globally enable the // new upload form. Leave the line *above* (the include of MediaWiki:Upload.js) untouched; // that script provides useful default behavior if the new upload form is disabled or // redirects to the old form in case an error occurs. enableNewUploadForm ; }

function WEAddStyles(a) { var ss = document.createElement('style'); ss.type = 'text/css'; ss.media = 'screen'; ss.title = 'WE'; if (ss.stylesheet) ss.stylesheet.cssText = a; //IE else ss.appendChild(document.createTextNode(a)); document.getElementsByTagName('head')[0].appendChild(ss); }

$(function { var g;  /* hide some navigation and other unnecessary elements if displayed in an iFrame */  if (window.self != window.top) {    var content = document.getElementById('content');    if (content) {      content.style.margin = 0;      content.style.borderStyle = 'none';    }    var reva = /(\d+:\d+, \d+ \w+ \d+)/.exec($('#mw-revision-info').text);    var revinfo = reva ? reva[0] : ;    reva = /oldid=(\d+)/.exec($('#mw-revision-nav').find('a').attr('href'));    var oldid = reva ? reva[1] : ;    var removals = ['mw-page-base', 'mw-head-base', 'mw-navigation', 'mw-head', 'mw-panel', 'column-one', 'siteNotice', 'contentSub', 'siteSub', 'catlinks', 'page-base', 'head-base', 'head', 'panel', 'firstHeading', 'footer-info-lastmod', 'footer-info-viewcount', 'footer-places', 'footer-icon-poweredby', 'f-poweredbyico', 'lastmod', 'viewcount', 'privacy', 'about', 'disclaimer', 'notiframe']; for (var i=0; i<removals.length; i++) { g = document.getElementById(removals[i]); if (g) { g.style.display = 'none'; }   }    $('.editsection,.mw-editsection').css('visibility', 'hidden'); $('#content, #footer').css('background-image', 'none'); document.body.style.background='none'; $('.iframeonly').removeClass('iframeonly'); var q = {}; var qs = document.location.search; qs = qs.substring(1).toLowerCase.split('&'); for (i=0; i<qs.length; i++) { g = qs[i].split('='); q[g[0]] = (g.length === 1) ? true : g[1]; }   if (q.nonav) { var divs = document.getElementsByTagName('div'); for (i=0; i<divs.length; i++) { if (divs[i].className.match(/navigation/i)) { divs[i].style.display = 'none'; }     }    }    g = document.getElementById('footer'); if (g) { g.style.marginLeft = 0; /* g.style.position = 'absolute'; g.style.bottom = 0; g.style.width = "98%"; */ }   var foot = document.getElementById('f-list') || document.getElementById('footer-info'); if (foot) { var li = document.createElement('li'); var wgServer = window.self.location.origin + '/'; g = wgServer + wgPageName; var footerfrom; if (revinfo) { footerfrom = 'Revision of ' + revinfo + ' retrieved from ' + g + '';     li.style.display = 'block';      foot.insertBefore(li, document.getElementById('copyright') || document.getElementById('footer-info-copyright'));    }    if ((wgCanonicalNamespace == 'Special') && (wgCanonicalSpecialPageName == 'Userlogin')) {      $('#footer-icon-copyright').hide;    }    if (q.links) {      var largs = q.links.split('|');      for (var j=0; j<largs.length; j++) {        q[largs[j]] = true;      }      var hilight = q.highlight ? ' background: yellow;' : ;      var hover = q.hover ? ' background: yellow;' : ;      if (q.none || q.highlight || q.hover) {        WEAddStyles('a.link {text-decoration: none; padding: 0px; background: none; ' + hilight + '} a.visited {text-decoration: none;' + hilight +'} a:active {text-decoration: none;' + hilight + '} a:hover {text-decoration: none;' + hilight + hover + '}');      } var as = document.getElementsByTagName('a'); for (j=0; j<as.length; j++) { var href = as[j].getAttribute('href'); if (href) { if (q.none || q.show || q.hover || q.highlight) { as[j].setAttribute('onclick', 'return false;'); }         if (q.window) { as[j].setAttribute('target', '_WE'); }       }      }    }    if (q.editable) { $('.editsection,.mw-editsection').css('visibility', 'visible'); }   if (q.noheading) { $('#firstHeading').css('display', 'none'); }   // if postMessage is supported, try to let the parent know our size if (parent.postMessage) { var ht = content.offsetHeight; var ftr = document.getElementById('footer'); if (ftr) { ht = ht + ftr.offsetHeight; } var loc = document.location.href; parent.postMessage('height^' + ht + '^' + loc, "*"); } } });

// BEGIN Dynamic Navigation Bars // NEEDS Enable multiple onload functions // set up the words in your language var NavigationBarHide = 'Collapse'; var NavigationBarShow = 'Expand'; // set up max count of Navigation Bars on page, // if there are more, all will be hidden // NavigationBarShowDefault = 0; // all bars will be hidden // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden var NavigationBarShowDefault = 0; // shows and hides content and picture (if available) of navigation bars // Parameters: //    indexNavigationBar: the index of navigation bar to be toggled function toggleNavigationBar(indexNavigationBar) {   var NavToggle = document.getElementById("NavToggle" + indexNavigationBar); var NavFrame = document.getElementById("NavFrame" + indexNavigationBar); if (!NavFrame || !NavToggle) { return false; }   // if shown now if (NavToggle.firstChild.data == NavigationBarHide) { for (               var NavChild = NavFrame.firstChild;                NavChild != null;                NavChild = NavChild.nextSibling            ) { if (NavChild.className == 'NavPic') { NavChild.style.display = 'none'; }           if (NavChild.className == 'NavContent') { NavChild.style.display = 'none'; }           if (NavChild.className == 'NavToggle') { NavChild.firstChild.data = NavigationBarShow; }       }    // if hidden now } else if (NavToggle.firstChild.data == NavigationBarShow) { for (               var NavChild = NavFrame.firstChild;                NavChild != null;                NavChild = NavChild.nextSibling            ) { if (NavChild.className == 'NavPic') { NavChild.style.display = 'block'; }           if (NavChild.className == 'NavContent') { NavChild.style.display = 'block'; }           if (NavChild.className == 'NavToggle') { NavChild.firstChild.data = NavigationBarHide; }       }    } } // adds show/hide-button to navigation bars function createNavigationBarToggleButton {   var indexNavigationBar = 0; // iterate over all -elements for(           var i=0;             NavFrame = document.getElementsByTagName("div")[i];             i++        ) { // if found a navigation bar if (NavFrame.className == "NavFrame") { indexNavigationBar++; var NavToggle = document.createElement("a"); NavToggle.className = 'NavToggle'; NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar); NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');'); var NavToggleText = document.createTextNode(NavigationBarHide); NavToggle.appendChild(NavToggleText); // add NavToggle-Button as first div-element // in            NavFrame.insertBefore(                NavToggle,                NavFrame.firstChild            ); NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar); }   }    // if more Navigation Bars found than Default: hide all if (NavigationBarShowDefault < indexNavigationBar) { for(               var i=1;                 i<=indexNavigationBar;                 i++        ) { toggleNavigationBar(i); }   } } $(createNavigationBarToggleButton);

// if logged in, and visiting an existing File: page with no description if (wgAction === 'edit' && wgUserName && (wgNamespaceNumber === 6) && wgArticleId) { $.getScript('/skins/common/we/file_information.js'); }