MediaWiki

Difference between revisions of "Common.js"

From Joomla! Documentation

(No longer needed with pure CSS way of hiding page titles.)
(Common.js to improve collapsible tables and allow user their own custom js for the wiki, keeping js to a minimum)
Line 1: Line 1:
 
/* Any JavaScript here will be loaded for all users on every page load. */
 
/* Any JavaScript here will be loaded for all users on every page load. */
 +
/**
 +
* 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.)
 +
*
 +
* Since common.js isn't a gadget, there is no place to declare its
 +
* dependencies, so we have to lazy load them with mw.loader.using on demand and
 +
* then execute the rest in the callback. In most cases these dependencies will
 +
* be loaded (or loading) already and the callback will not be delayed. In case a
 +
* dependency hasn't arrived yet it'll make sure those are loaded before this.
 +
*/
 +
mw.loader.using( 'mediawiki.util', function() {
 +
/* Begin of mw.loader.using callback */
 +
 +
/**
 +
* Redirect User:Name/skin.js and skin.css to the current skin's pages
 +
* (unless the 'skin' page really exists)
 +
* @source: http://www.mediawiki.org/wiki/Snippets/Redirect_skin.js
 +
* @rev: 2
 +
*/
 +
if ( mw.config.get( 'wgArticleId' ) === 0 && mw.config.get( 'wgNamespaceNumber' ) == 2 ) {
 +
var titleParts = mw.config.get( 'wgPageName' ).split( '/' );
 +
// Make sure there was a part before and after the slash
 +
// And that the latter is 'skin.js' or 'skin.css'
 +
if ( titleParts.length == 2 ) {
 +
var userSkinPage = titleParts.shift() + '/' + mw.config.get( 'skin' );
 +
if ( titleParts.slice(-1) == 'skin.js' ) {
 +
window.location.href = mw.util.wikiGetlink( userSkinPage + '.js' );
 +
} else if ( titleParts.slice(-1) == 'skin.css' ) {
 +
window.location.href = mw.util.wikiGetlink( userSkinPage + '.css' );
 +
}
 +
}
 +
}
 +
 +
/** Collapsible tables *********************************************************
 +
*
 +
*  Description: Allows tables to be collapsed, showing only the header. See
 +
*              [[Wikipedia:NavFrame]].
 +
*  Maintainers: [[User:R. Koot]]
 +
*/
 +
 +
var autoCollapse = 2;
 +
var collapseCaption = "hide";
 +
var expandCaption = "show";
 +
 +
window.collapseTable = function( tableIndex ){
 +
    var Button = document.getElementById( "collapseButton" + tableIndex );
 +
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
 +
 +
    if ( !Table || !Button ) {
 +
        return false;
 +
    }
 +
 +
    var Rows = Table.rows;
 +
 +
    if ( Button.firstChild.data == collapseCaption ) {
 +
        for ( var i = 1; i < Rows.length; i++ ) {
 +
            Rows[i].style.display = "none";
 +
        }
 +
        Button.firstChild.data = expandCaption;
 +
    } else {
 +
        for ( var i = 1; i < Rows.length; i++ ) {
 +
            Rows[i].style.display = Rows[0].style.display;
 +
        }
 +
        Button.firstChild.data = collapseCaption;
 +
    }
 +
}
 +
 +
function createCollapseButtons(){
 +
    var tableIndex = 0;
 +
    var NavigationBoxes = new Object();
 +
    var Tables = document.getElementsByTagName( "table" );
 +
 +
    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 */
 +
            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 );
 +
 +
            Button.className = "collapseButton";  //Styles are declared in Common.css
 +
 +
            ButtonLink.style.color = Header.style.color;
 +
            ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
 +
            ButtonLink.setAttribute( "href", "#" );
 +
            addHandler( ButtonLink,  "click", new Function( "evt", "collapseTable(" + tableIndex + " ); return killEvt( evt );") );
 +
            ButtonLink.appendChild( ButtonText );
 +
 +
            Button.appendChild( document.createTextNode( "[" ) );
 +
            Button.appendChild( ButtonLink );
 +
            Button.appendChild( document.createTextNode( "]" ) );
 +
 +
            Header.insertBefore( Button, Header.firstChild );
 +
            tableIndex++;
 +
        }
 +
    }
 +
 +
    for ( var i = 0;  i < tableIndex; i++ ) {
 +
        if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
 +
            collapseTable( i );
 +
        }
 +
        else if ( hasClass( NavigationBoxes[i], "innercollapse" ) ) {
 +
            var element = NavigationBoxes[i];
 +
            while (element = element.parentNode) {
 +
                if ( hasClass( element, "outercollapse" ) ) {
 +
                    collapseTable ( i );
 +
                    break;
 +
                }
 +
            }
 +
        }
 +
    }
 +
}
 +
 +
$( createCollapseButtons );
 +
 +
 +
/** Dynamic Navigation Bars (experimental) *************************************
 +
*
 +
*  Description: See [[Wikipedia:NavFrame]].
 +
*  Maintainers: UNMAINTAINED
 +
*/
 +
 +
// set up the words in your language
 +
var NavigationBarHide = '[' + collapseCaption + ']';
 +
var NavigationBarShow = '[' + expandCaption + ']';
 +
 +
// shows and hides content and picture (if available) of navigation bars
 +
// Parameters:
 +
//    indexNavigationBar: the index of navigation bar to be toggled
 +
window.toggleNavigationBar = function(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 (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
 +
                NavChild.style.display = 'none';
 +
            }
 +
        }
 +
    NavToggle.firstChild.data = NavigationBarShow;
 +
 +
    // if hidden now
 +
    } else if (NavToggle.firstChild.data == NavigationBarShow) {
 +
        for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
 +
            if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
 +
                NavChild.style.display = 'block';
 +
            }
 +
        }
 +
        NavToggle.firstChild.data = NavigationBarHide;
 +
    }
 +
}
 +
 +
// adds show/hide-button to navigation bars
 +
function createNavigationBarToggleButton(){
 +
    var indexNavigationBar = 0;
 +
    // iterate over all < div >-elements
 +
    var divs = document.getElementsByTagName("div");
 +
    for (var i = 0; NavFrame = divs[i]; i++) {
 +
        // if found a navigation bar
 +
        if (hasClass(NavFrame, "NavFrame")) {
 +
 +
            indexNavigationBar++;
 +
            var NavToggle = document.createElement("a");
 +
            NavToggle.className = 'NavToggle';
 +
            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
 +
            NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
 +
 +
            var isCollapsed = hasClass( NavFrame, "collapsed" );
 +
            /*
 +
            * Check if any children are already hidden.  This loop is here for backwards compatibility:
 +
            * the old way of making NavFrames start out collapsed was to manually add style="display:none"
 +
            * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
 +
            * the content visible without JavaScript support), the new recommended way is to add the class
 +
            * "collapsed" to the NavFrame itself, just like with collapsible tables.
 +
            */
 +
            for (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) {
 +
                if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
 +
                    if ( NavChild.style.display == 'none' ) {
 +
                        isCollapsed = true;
 +
                    }
 +
                }
 +
            }
 +
            if (isCollapsed) {
 +
                for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
 +
                    if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
 +
                        NavChild.style.display = 'none';
 +
                    }
 +
                }
 +
            }
 +
            var NavToggleText = document.createTextNode(isCollapsed ? NavigationBarShow : NavigationBarHide);
 +
            NavToggle.appendChild(NavToggleText);
 +
 +
            // 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++) {
 +
                if (hasClass(NavFrame.childNodes[j], "NavHead")) {
 +
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
 +
                    NavFrame.childNodes[j].appendChild(NavToggle);
 +
                }
 +
            }
 +
            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
 +
        }
 +
    }
 +
}
 +
 +
$( createNavigationBarToggleButton );

Revision as of 21:16, 22 September 2012

/* Any JavaScript here will be loaded for all users on every page load. */
/**
 * 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.)
 *
 * Since common.js isn't a gadget, there is no place to declare its
 * dependencies, so we have to lazy load them with mw.loader.using on demand and
 * then execute the rest in the callback. In most cases these dependencies will
 * be loaded (or loading) already and the callback will not be delayed. In case a
 * dependency hasn't arrived yet it'll make sure those are loaded before this.
 */
mw.loader.using( 'mediawiki.util', function() {
/* Begin of mw.loader.using callback */
 
/**
 * Redirect User:Name/skin.js and skin.css to the current skin's pages
 * (unless the 'skin' page really exists)
 * @source: http://www.mediawiki.org/wiki/Snippets/Redirect_skin.js
 * @rev: 2
 */
if ( mw.config.get( 'wgArticleId' ) === 0 && mw.config.get( 'wgNamespaceNumber' ) == 2 ) {
	var titleParts = mw.config.get( 'wgPageName' ).split( '/' );
	// Make sure there was a part before and after the slash
	// And that the latter is 'skin.js' or 'skin.css'
	if ( titleParts.length == 2 ) {
		var userSkinPage = titleParts.shift() + '/' + mw.config.get( 'skin' );
		if ( titleParts.slice(-1) == 'skin.js' ) {
			window.location.href = mw.util.wikiGetlink( userSkinPage + '.js' );
		} else if ( titleParts.slice(-1) == 'skin.css' ) {
			window.location.href = mw.util.wikiGetlink( userSkinPage + '.css' );
		}
	}
}

/** Collapsible tables *********************************************************
 *
 *  Description: Allows tables to be collapsed, showing only the header. See
 *               [[Wikipedia:NavFrame]].
 *  Maintainers: [[User:R. Koot]]
 */
 
var autoCollapse = 2;
var collapseCaption = "hide";
var expandCaption = "show";
 
window.collapseTable = function( tableIndex ){
    var Button = document.getElementById( "collapseButton" + tableIndex );
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
 
    if ( !Table || !Button ) {
        return false;
    }
 
    var Rows = Table.rows;
 
    if ( Button.firstChild.data == collapseCaption ) {
        for ( var i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = "none";
        }
        Button.firstChild.data = expandCaption;
    } else {
        for ( var i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = Rows[0].style.display;
        }
        Button.firstChild.data = collapseCaption;
    }
}
 
function createCollapseButtons(){
    var tableIndex = 0;
    var NavigationBoxes = new Object();
    var Tables = document.getElementsByTagName( "table" );
 
    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 */
            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 );
 
            Button.className = "collapseButton";  //Styles are declared in Common.css
 
            ButtonLink.style.color = Header.style.color;
            ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
            ButtonLink.setAttribute( "href", "#" );
            addHandler( ButtonLink,  "click", new Function( "evt", "collapseTable(" + tableIndex + " ); return killEvt( evt );") );
            ButtonLink.appendChild( ButtonText );
 
            Button.appendChild( document.createTextNode( "[" ) );
            Button.appendChild( ButtonLink );
            Button.appendChild( document.createTextNode( "]" ) );
 
            Header.insertBefore( Button, Header.firstChild );
            tableIndex++;
        }
    }
 
    for ( var i = 0;  i < tableIndex; i++ ) {
        if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
            collapseTable( i );
        } 
        else if ( hasClass( NavigationBoxes[i], "innercollapse" ) ) {
            var element = NavigationBoxes[i];
            while (element = element.parentNode) {
                if ( hasClass( element, "outercollapse" ) ) {
                    collapseTable ( i );
                    break;
                }
            }
        }
    }
}
 
$( createCollapseButtons );
 
 
/** Dynamic Navigation Bars (experimental) *************************************
 *
 *  Description: See [[Wikipedia:NavFrame]].
 *  Maintainers: UNMAINTAINED
 */
 
// set up the words in your language
var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
 
// shows and hides content and picture (if available) of navigation bars
// Parameters:
//     indexNavigationBar: the index of navigation bar to be toggled
window.toggleNavigationBar = function(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 (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
                NavChild.style.display = 'none';
            }
        }
    NavToggle.firstChild.data = NavigationBarShow;
 
    // if hidden now
    } else if (NavToggle.firstChild.data == NavigationBarShow) {
        for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
            if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
                NavChild.style.display = 'block';
            }
        }
        NavToggle.firstChild.data = NavigationBarHide;
    }
}
 
// adds show/hide-button to navigation bars
function createNavigationBarToggleButton(){
    var indexNavigationBar = 0;
    // iterate over all < div >-elements 
    var divs = document.getElementsByTagName("div");
    for (var i = 0; NavFrame = divs[i]; i++) {
        // if found a navigation bar
        if (hasClass(NavFrame, "NavFrame")) {
 
            indexNavigationBar++;
            var NavToggle = document.createElement("a");
            NavToggle.className = 'NavToggle';
            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
            NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
 
            var isCollapsed = hasClass( NavFrame, "collapsed" );
            /*
             * Check if any children are already hidden.  This loop is here for backwards compatibility:
             * the old way of making NavFrames start out collapsed was to manually add style="display:none"
             * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
             * the content visible without JavaScript support), the new recommended way is to add the class
             * "collapsed" to the NavFrame itself, just like with collapsible tables.
             */
            for (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) {
                if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
                    if ( NavChild.style.display == 'none' ) {
                        isCollapsed = true;
                    }
                }
            }
            if (isCollapsed) {
                for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
                    if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
                        NavChild.style.display = 'none';
                    }
                }
            }
            var NavToggleText = document.createTextNode(isCollapsed ? NavigationBarShow : NavigationBarHide);
            NavToggle.appendChild(NavToggleText);
 
            // 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++) {
                if (hasClass(NavFrame.childNodes[j], "NavHead")) {
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
                    NavFrame.childNodes[j].appendChild(NavToggle);
                }
            }
            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
        }
    }
}
 
$( createNavigationBarToggleButton );