Jump to content

MediaWiki:Common.js: Difference between revisions

adding autosort feature and touching up existing code style
(moving sort script to my personal JS so I can test it more)
(adding autosort feature and touching up existing code style)
Line 4: Line 4:
  * paramName  : the name of the parameter to extract
  * paramName  : the name of the parameter to extract
  */
  */
function getURLParamValue( paramName, url)  
function getURLParamValue(paramName, url)  
{
{
     if (typeof (url) == 'undefined' || url === null) url = document.location.href;
     if (typeof (url) == 'undefined' || url === null)
     var cmdRe=RegExp( '[&?]' + paramName + '=([^&#]*)' ); // Stop at hash
        url = document.location.href;
     var m=cmdRe.exec(url);
     var cmdRe = RegExp('[&?]' + paramName + '=([^&#]*)'); // Stop at hash
     if (m && m.length > 1) return decodeURIComponent(m[1]);
     var m = cmdRe.exec(url);
return null;
     if (m && m.length > 1)
        return decodeURIComponent(m[1]);
    return null;
}
}
   
   
Line 18: Line 20:
  */
  */
var extraJS = getURLParamValue("withJS");
var extraJS = getURLParamValue("withJS");
if ( extraJS && extraJS.match("^MediaWiki:[^&<>=%]*\.js$") ) {
if (extraJS && extraJS.match("^MediaWiki:[^&<>=%]*\.js$"))
{
     importScript(extraJS);
     importScript(extraJS);
}
}
Line 24: Line 27:


/* Import more specific scripts if necessary */
/* Import more specific scripts if necessary */
if (wgAction == "edit" || wgAction == "submit" || wgPageName == "Special:Upload") //scripts specific to editing pages
if (wgAction == "edit" || wgAction == "submit" || wgPageName == "Special:Upload") // load script specific to editing and upload pages
{
{
     importScript("MediaWiki:Common.js/edit.js")
     importScript("MediaWiki:Common.js/edit.js")
}
}
else if (wgPageName == "Special:Search") //search scripts
else if (wgPageName == "Special:Search") // load script for augmenting search page
{
{
     importScript("MediaWiki:Common.js/search.js")
     importScript("MediaWiki:Common.js/search.js")
Line 35: Line 38:


/* Scripts specific to Internet Explorer */
/* Scripts specific to Internet Explorer */
if (navigator.appName == 'Microsoft Internet Explorer'){
if (navigator.appName == 'Microsoft Internet Explorer')
{
     /** Internet Explorer bug fix **************************************************
     /** Internet Explorer bug fix **************************************************
     *
     *
Line 45: Line 49:
     var docEl = document.documentElement;
     var docEl = document.documentElement;
      
      
     var fixIEScroll = function() {
     var fixIEScroll = function()
         if (!oldWidth || docEl.clientWidth > oldWidth) {
    {
         if (!oldWidth || docEl.clientWidth > oldWidth)
        {
             doFixIEScroll();
             doFixIEScroll();
         } else {
         }
        else
        {
             setTimeout(doFixIEScroll, 1);
             setTimeout(doFixIEScroll, 1);
         }
         }
Line 55: Line 63:
     };
     };
      
      
     var doFixIEScroll = function () {
     var doFixIEScroll = function()
    {
         docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : "";
         docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : "";
     };
     };
Line 63: Line 72:
      
      
     // In print IE (7?) does not like line-height
     // In print IE (7?) does not like line-height
     appendCSS( '@media print { sup, sub, p, .documentDescription { line-height: normal; }}');
     appendCSS('@media print {sup, sub, p, .documentDescription {line-height: normal;}}');


     // IE overflow bug
     // IE overflow bug
     appendCSS('div.overflowbugx { overflow-x: scroll !important; overflow-y: hidden !important; } div.overflowbugy { overflow-y: scroll !important; overflow-x: hidden !important; }');
     appendCSS('div.overflowbugx {overflow-x: scroll !important; overflow-y: hidden !important;} div.overflowbugy {overflow-y: scroll !important; overflow-x: hidden !important;}');


     // IE zoomfix
     // IE zoomfix
     // Use to fix right floating div/table inside tables
     // Use to fix right floating div/table inside tables
     appendCSS('.iezoomfix div, .iezoomfix table { zoom: 1;}');
     appendCSS('.iezoomfix div, .iezoomfix table {zoom: 1;}');
      
      
     // Import scripts specific to Internet Explorer 6
     // Import scripts specific to Internet Explorer 6
     if (navigator.appVersion.substr(22, 1) == '6') {
     if (navigator.appVersion.substr(22, 1) == '6')
    {
         importScript('MediaWiki:Common.js/IE60Fixes.js');
         importScript('MediaWiki:Common.js/IE60Fixes.js');
     }
     }
Line 85: Line 95:
  */
  */


var hasClass = (function () {
var hasClass = (function ()
{
     var reCache = {};
     var reCache = {};
     return function (element, className) {
     return function (element, className)
    {
         return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
         return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
     };
     };
Line 193: Line 205:
var expandCaption = "show";
var expandCaption = "show";


function collapseTable( tableIndex ){
function collapseTable(tableIndex)
     var Button = document.getElementById( "collapseButton" + tableIndex );
{
     var Table = document.getElementById( "collapsibleTable" + tableIndex );
     var Button = document.getElementById("collapseButton" + tableIndex);
     var Table = document.getElementById("collapsibleTable" + tableIndex);


     if ( !Table || !Button ) {
     if (!Table || !Button)
    {
         return false;
         return false;
     }
     }
Line 203: Line 217:
     var Rows = Table.rows;
     var Rows = Table.rows;


     if ( Button.firstChild.data == collapseCaption ) {
     if (Button.firstChild.data == collapseCaption)
         for ( var i = 1; i < Rows.length; i++ ) {
    {
         for (var i = 1; i < Rows.length; i++)
        {
             Rows[i].style.display = "none";
             Rows[i].style.display = "none";
         }
         }
         Button.firstChild.data = expandCaption;
         Button.firstChild.data = expandCaption;
     } else {
     }
         for ( var i = 1; i < Rows.length; i++ ) {
    else
    {
         for (var i = 1; i < Rows.length; i++)
        {
             Rows[i].style.display = Rows[0].style.display;
             Rows[i].style.display = Rows[0].style.display;
         }
         }
Line 216: Line 235:
}
}


function createCollapseButtons(){
function createCollapseButtons()
{
     var tableIndex = 0;
     var tableIndex = 0;
     var NavigationBoxes = new Object();
     var NavigationBoxes = new Object();
     var Tables = document.getElementsByTagName( "table" );
     var Tables = document.getElementsByTagName("table");
 
    for ( var i = 0; i < Tables.length; i++ ) {
        if ( hasClass( Tables[i], "collapsible" ) ) {


    for (var i = 0; i < Tables.length; i++)
    {
        if (hasClass(Tables[i], "collapsible"))
        {
             /* only add button and increment count if there is a header row to work with */
             /* only add button and increment count if there is a header row to work with */
             var HeaderRow = Tables[i].getElementsByTagName( "tr" )[0];
             var HeaderRow = Tables[i].getElementsByTagName("tr")[0];
             if (!HeaderRow) continue;
             if (!HeaderRow) continue;
             var Header = HeaderRow.getElementsByTagName( "th" )[0];
             var Header = HeaderRow.getElementsByTagName("th")[0];
             if (!Header) continue;
             if (!Header) continue;


             NavigationBoxes[ tableIndex ] = Tables[i];
             NavigationBoxes[tableIndex] = Tables[i];
             Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
             Tables[i].setAttribute("id", "collapsibleTable" + tableIndex);


             var Button    = document.createElement( "span" );
             var Button    = document.createElement("span");
             var ButtonLink = document.createElement( "a" );
             var ButtonLink = document.createElement("a");
             var ButtonText = document.createTextNode( collapseCaption );
             var ButtonText = document.createTextNode(collapseCaption);


             Button.className = "collapseButton"; //Styles are declared in Common.css
             Button.className = "collapseButton"; // styles are declared in Common.css


             ButtonLink.style.color = Header.style.color;
             ButtonLink.style.color = Header.style.color;
             ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
             ButtonLink.setAttribute("id", "collapseButton" + tableIndex);
             ButtonLink.setAttribute( "href", "#" );
             ButtonLink.setAttribute("href", "#");
             addHandler( ButtonLink, "click", new Function( "evt", "collapseTable(" + tableIndex + " ); return killEvt( evt );") );
             addHandler(ButtonLink, "click", new Function("evt", "collapseTable(" + tableIndex + " ); return killEvt(evt);"));
             ButtonLink.appendChild( ButtonText );
             ButtonLink.appendChild(ButtonText);


             Button.appendChild( document.createTextNode( "[" ) );
             Button.appendChild(document.createTextNode("["));
             Button.appendChild( ButtonLink );
             Button.appendChild(ButtonLink);
             Button.appendChild( document.createTextNode( "]" ) );
             Button.appendChild(document.createTextNode("]"));


             Header.insertBefore( Button, Header.childNodes[0] );
             Header.insertBefore(Button, Header.childNodes[0]);
             tableIndex++;
             tableIndex++;
         }
         }
     }
     }


     for ( var i = 0;  i < tableIndex; i++ ) {
     for (var i = 0;  i < tableIndex; i++)
         if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
    {
             collapseTable( i );
         if (hasClass(NavigationBoxes[i], "collapsed") || (tableIndex >= autoCollapse && hasClass(NavigationBoxes[i], "autocollapse")))
        {
             collapseTable(i);
         }  
         }  
         else if ( hasClass( NavigationBoxes[i], "innercollapse" ) ) {
         else if (hasClass(NavigationBoxes[i], "innercollapse"))
        {
             var element = NavigationBoxes[i];
             var element = NavigationBoxes[i];
             while (element = element.parentNode) {
             while (element = element.parentNode)
                 if ( hasClass( element, "outercollapse" ) ) {
            {
                     collapseTable ( i );
                 if (hasClass(element, "outercollapse"))
                {
                     collapseTable (i);
                     break;
                     break;
                 }
                 }
Line 270: Line 296:
}
}


addOnloadHook( createCollapseButtons );
addOnloadHook(createCollapseButtons);




Line 286: Line 312:
// Parameters:
// Parameters:
//    indexNavigationBar: the index of navigation bar to be toggled
//    indexNavigationBar: the index of navigation bar to be toggled
function toggleNavigationBar(indexNavigationBar){
function toggleNavigationBar(indexNavigationBar)
{
     var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
     var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
     var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);
     var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);


     if (!NavFrame || !NavToggle) {
     if (!NavFrame || !NavToggle)
         return false;
         return false;
    }


     // if shown now
     // if shown now
     if (NavToggle.firstChild.data == NavigationBarHide) {
     if (NavToggle.firstChild.data == NavigationBarHide)
         for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
    {
             if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
         for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling)
        {
             if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic'))
            {
                 NavChild.style.display = 'none';
                 NavChild.style.display = 'none';
             }
             }
Line 304: Line 333:


     // if hidden now
     // if hidden now
     } else if (NavToggle.firstChild.data == NavigationBarShow) {
     }
         for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
    else if (NavToggle.firstChild.data == NavigationBarShow)
             if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
    {
         for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling)
        {
             if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic'))
            {
                 NavChild.style.display = 'block';
                 NavChild.style.display = 'block';
             }
             }
Line 315: Line 348:


// adds show/hide-button to navigation bars
// adds show/hide-button to navigation bars
function createNavigationBarToggleButton(){
function createNavigationBarToggleButton()
{
     var indexNavigationBar = 0;
     var indexNavigationBar = 0;
     // iterate over all < div >-elements  
     // iterate over all < div >-elements  
     var divs = document.getElementsByTagName("div");
     var divs = document.getElementsByTagName("div");
     for (var i = 0; NavFrame = divs[i]; i++) {
     for (var i = 0; NavFrame = divs[i]; i++)
    {
         // if found a navigation bar
         // if found a navigation bar
         if (hasClass(NavFrame, "NavFrame")) {
         if (hasClass(NavFrame, "NavFrame"))
 
        {
             indexNavigationBar++;
             indexNavigationBar++;
             var NavToggle = document.createElement("a");
             var NavToggle = document.createElement("a");
Line 329: Line 364:
             NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
             NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');


             var isCollapsed = hasClass( NavFrame, "collapsed" );
             var isCollapsed = hasClass(NavFrame, "collapsed");
             /*
             /*
             * Check if any children are already hidden.  This loop is here for backwards compatibility:
             * Check if any children are already hidden.  This loop is here for backwards compatibility:
Line 337: Line 372:
             * "collapsed" to the NavFrame itself, just like with collapsible tables.
             * "collapsed" to the NavFrame itself, just like with collapsible tables.
             */
             */
             for (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) {
             for (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling)
                 if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
            {
                     if ( NavChild.style.display == 'none' ) {
                 if (hasClass(NavChild, 'NavPic') || hasClass(NavChild, 'NavContent'))
                {
                     if (NavChild.style.display == 'none')
                    {
                         isCollapsed = true;
                         isCollapsed = true;
                     }
                     }
                 }
                 }
             }
             }
             if (isCollapsed) {
             if (isCollapsed)
                 for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
            {
                     if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
                 for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling)
                {
                     if (hasClass(NavChild, 'NavPic') || hasClass(NavChild, 'NavContent'))
                    {
                         NavChild.style.display = 'none';
                         NavChild.style.display = 'none';
                     }
                     }
Line 355: Line 396:


             // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
             // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
             for(var j=0; j < NavFrame.childNodes.length; j++) {
             for (var j = 0; j < NavFrame.childNodes.length; j++)
                 if (hasClass(NavFrame.childNodes[j], "NavHead")) {
            {
                 if (hasClass(NavFrame.childNodes[j], "NavHead"))
                {
                     NavToggle.style.color = NavFrame.childNodes[j].style.color;
                     NavToggle.style.color = NavFrame.childNodes[j].style.color;
                     NavFrame.childNodes[j].appendChild(NavToggle);
                     NavFrame.childNodes[j].appendChild(NavToggle);
Line 366: Line 409:
}
}


addOnloadHook( createNavigationBarToggleButton );
addOnloadHook(createNavigationBarToggleButton);




Line 459: Line 502:
  *  Maintainers: [[User:Krimpet]]
  *  Maintainers: [[User:Krimpet]]
  */
  */
function uploadwizard_newusers() {
function uploadwizard_newusers()
  if (wgNamespaceNumber == 4 && wgTitle == "Upload" && wgAction == "view") {
{
    var oldDiv = document.getElementById("autoconfirmedusers"),
    if (wgNamespaceNumber == 4 && wgTitle == "Upload" && wgAction == "view")
        newDiv = document.getElementById("newusers");
    {
    if (oldDiv && newDiv) {
        var oldDiv = document.getElementById("autoconfirmedusers"),
      if (typeof wgUserGroups == "object" && wgUserGroups) {
            newDiv = document.getElementById("newusers");
        for (i = 0; i < wgUserGroups.length; i++) {
        if (oldDiv && newDiv)
          if (wgUserGroups[i] == "autoconfirmed") {
        {
             oldDiv.style.display = "block";
            if (typeof wgUserGroups == "object" && wgUserGroups)
             newDiv.style.display = "none";
            {
                for (i = 0; i < wgUserGroups.length; i++)
                {
                    if (wgUserGroups[i] == "autoconfirmed")
                    {
                        oldDiv.style.display = "block";
                        newDiv.style.display = "none";
                        return;
                    }
                }
            }
             oldDiv.style.display = "none";
             newDiv.style.display = "block";
             return;
             return;
          }
         }
         }
      }
      oldDiv.style.display = "none";
      newDiv.style.display = "block";
      return;
     }
     }
  }
}
}
addOnloadHook(uploadwizard_newusers);
addOnloadHook(uploadwizard_newusers);
/***** autosort_sortable ********
* Auto-sorts sortable tables by first column (why is this not built-in?!)
* You must opt in for this feature by placing "autosort" in the list of
* the table's classes along with "sortable"
*
*  Maintainers: [[User:Iritscen]]
*/
function sortSortableTables()
{
    // Iterate over all <div> elements
    var divs = document.getElementsByTagName("div");
    if (!divs) return;
    for (var i = 0; i < divs.length; i++)
    {
        var theDiv = divs[i];
        var tables = theDiv.getElementsByTagName("table");
        if (!tables) continue;
        for (var j = 0; j < tables.length; j++)
        {
            var theTable = tables[j];
            // If we found a sortable table that is asking for autosort...
            if (hasClass(theTable, "sortable") && hasClass(theTable, "autosort"))
            {
                // ...Look for sort button and click it
                var allTHs = theTable.getElementsByTagName("th");
                if (!allTHs) continue;
                for (var k = 0; k < allTHs.length; k++)
                {
                    if (hasClass(allTHs[k], "headerSort"))
                    {
                        $(allTHs[k]).trigger("click"); // use jQuery's trigger() to send click event to this arrow
                        return;
                    }
                }
            }
        }
    }
}
addOnloadHook(sortSortableTables);