MediaWiki:Common.js: Difference between revisions

From Pikipedia, the Pikmin wiki
Jump to navigation Jump to search
No edit summary
(Changed the attribute used by the switchable feature, so that it doesn't use the title. This is because using the title makes a tooltip appear when you mouse-over a switchable div. Hope this works...)
Line 9: Line 9:
var switchableSectionClass = 'switch';
var switchableSectionClass = 'switch';
var switchableTabsClass = 'switchabletabs';
var switchableTabsClass = 'switchabletabs';
var switchableSectionTitleAttr = 'title';
var switchableSectionTitleAttr = 'switchable-title';


function initialiseSwitchable () {
function initialiseSwitchable () {
Line 551: Line 551:
   } else {
   } else {
     e.setAttribute("oldContent", e.innerHTML);
     e.setAttribute("oldContent", e.innerHTML);
     e.innerHTML = e.getAttribute("title");
     e.innerHTML = e.getAttribute(switchableSectionTitleAttr);
     e.style.textDecoration = "underline dashed";
     e.style.textDecoration = "underline dashed";
   }
   }

Revision as of 14:27, August 7, 2018

/* Any JavaScript here will be loaded for all users on every page load. */

mw.loader.using( ['mediawiki.user', 'mediawiki.util', 'mediawiki.notify', 'jquery.client'] ).done( function () {

/* Content tabber, version 1.0.5 by Greenpickle (GPL3) */

var switchableAnchorPrefix = '';
var switchableClass = 'switchable';
var switchableSectionClass = 'switch';
var switchableTabsClass = 'switchabletabs';
var switchableSectionTitleAttr = 'switchable-title';

function initialiseSwitchable () {
    // get the elements we care about
    switchable = myGetElementsByClassName(document, switchableClass);

    // some functions
    switchable.createTab = function (label, isAnchor, i, j) {
        var tab = document.createElement('li');
        var child;
        if (isAnchor) {
            child = document.createElement('a');
            child.href =
                'javascript:switchable.setVisible(' + i + ', ' + j + ');';
        } else child = document.createElement('strong');
        child.appendChild(document.createTextNode(label));
        tab.appendChild(child);
        return tab;
    }

    switchable.getVisible = function (i) {
        var visible = this[i].getAttribute('visiblesection');
        if (visible) visible = parseInt(visible);
        if (visible === null || isNaN(visible)) {
            visible = 0;
            this[i].setAttribute('visiblesection', visible.toString());
        }
        return Math.max(0, Math.min(visible, this[i].sections.length - 1));
    }

    switchable.updateVisible = function (i) {
        if (isNaN(parseInt(i))) {
            // update all switchables if no valid number given
            for (var i = 0; i < this.length; i++)
                this.updateVisible(i);
        } else {
            var visible = this.getVisible(i);
            var sections = this[i].sections;
            var tc = this[i].tabContainer;
            var currentTab;
            for (var j = 0; j < sections.length; j++) {
                if (j == visible) {
                    // change 'show' link
                    currentTab = this.createTab(sections[j].sectionName,
                                                    false);
                    currentTab.j = j;
                    tc.replaceChild(currentTab, tc.tabs[j]);
                    // show section
                    sections[j].style.display = '';
                } else {
                    // change 'show' link
                    if (tc.currentTab !== undefined && tc.currentTab.j == j)
                        tc.replaceChild(tc.tabs[j], tc.currentTab);
                    // hide section
                    sections[j].style.display = 'none';
                }
            }
            if (currentTab !== undefined) tc.currentTab = currentTab;
        }
    }

    switchable.setVisible = function (i, j) {
        this[i].setAttribute('visiblesection', j);
        this.updateVisible(i);
    }

    // initialise
    for (var i = 0; i < switchable.length; i++) {
        var sections = myGetElementsByClassName(switchable[i],
                                                switchableSectionClass);
        switchable[i].sections = sections;
        // create show/hide anchors
        var tabContainer = document.createElement('ul');
        tabContainer.className = switchableTabsClass;
        switchable[i].appendChild(tabContainer);
        switchable[i].tabContainer = tabContainer;
        tabContainer.tabs = [];
        for (var j = 0; j < sections.length; j++) {
            // re-append section to place it after links
            switchable[i].appendChild(sections[j]);
            // use section's name if it has one
            var sectionName = sections[j].getAttribute(
                                                switchableSectionTitleAttr);
            if (!sectionName) sectionName = j.toString();
            sections[j].sectionName = sectionName;
            // create anchor
            var tab = switchable.createTab(
                            switchableAnchorPrefix + sectionName, true, i, j);
            tabContainer.appendChild(tab);
            tabContainer.tabs.push(tab);
        }
    }
    this.switchable = switchable;
    // initial show/hide
    switchable.updateVisible();
}

initialiseSwitchable();

// I'd extend Node.prototype, but apparently IE fails...
function myGetElementsByClassName (node, cls) {
    var result = [];
    var pool = node.getElementsByTagName("*");
    var re = new RegExp('\\b' + cls + '\\b');
    for (var i = 0; i < pool.length; i++)
        if (re.test(pool[i].className)) result.push(pool[i]);
    return result;
}

/* table.hideable, version 1.1.1 by Greenpickle (GPL3) */

var hideImageURL = '/images/hide.png';
var showImageURL = '/images/show.png';
var hideableColClass = 'hideable';
var hiddenColClass = 'hidden';
var hideableShowClass = 'showcol';

function getElementsByTagNames (node) {
    // return an array of elements in the node with the given tag names
    var nodes = [];
    for (var i = 1; i < arguments.length; i++) {
        var newNodes = node.getElementsByTagName(arguments[i]);
        try {
            // no idea where this'll fail if it does
            newNodes = Array.prototype.slice.call(newNodes);
            nodes = nodes.concat(newNodes);
        } catch (e) {
            // do it the slow way
            for (var j = 0; j < newNodes.length; j++) nodes.push(newNodes[j]);
        }
    }
    return nodes;
}

function matchTagName (node) {
    // check if node.tagName is one of given names, case-insensitively
    if (node.tagName === undefined) return false;
    tag = node.tagName.toLowerCase();
    for (var i = 1; i < arguments.length; i++) {
        if (arguments[i].toLowerCase() == tag) return true;
    }
    return false;
}

function getContainer (node, tag) {
    // return nearest parent with given tag name
    tag = tag.toLowerCase();
    var container = node;
    do {
        container = container.parentNode;
        if (container === document) return undefined;
    } while (container.tagName.toLowerCase() != tag);
    return container;
}

function nextElement (e) {
    do e = e.nextSibling;
    while (e !== null && e.nodeType != 1);
    return e;
}

function previousElement (e) {
    do e = e.previousSibling;
    while (e !== null && e.nodeType != 1);
    return e;
}

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

var hideable = {};

hideable.showCallback = function () {
    hideable.show(this.parentNode);
    return false;
};

hideable.hideCallback = function () {
    hideable.hide(this.parentNode);
    return false;
};

hideable.createLink = function (isHide) {
    // create a show/hide link
    var lnk = document.createElement('a');
    lnk.href = '#';
    lnk.onclick = isHide ? hideable.hideCallback : hideable.showCallback;
    var img = document.createElement('img');
    img.alt = isHide ? 'hide' : 'show';
    img.src = isHide ? hideImageURL : showImageURL;
    lnk.appendChild(img);
    return lnk;
};

hideable.getColSpan = function (cell, orig) {
    return orig ? cell.origColSpan || cell.colSpan : cell.colSpan;
};

hideable.setColSpan = function (cell, colSpan) {
    if (cell.origColSpan === undefined)
        // store original colspan
        cell.origColSpan = cell.colSpan;
    cell.colSpan = colSpan;
};

hideable.getCol = function (targetCell, orig) {
    var row = getContainer(targetCell, 'tr');
    if (row === undefined) throw('cell not in a table row');
    // sum colspans along row
    var col = 0;
    var children = getElementsByTagNames(row, 'th', 'td');
    for (var i = 0; i < children.length; i++) {
        var cell = children[i];
        if (cell === targetCell) break;
        if (orig || cell.style.display != 'none')
            // cell is not hidden, or we want hidden cells: add its colspan
            col += hideable.getColSpan(cell, orig);
    }
    return col;
};

hideable.cellAtCol = function (row, targetCol, orig) {
    var col = 0;
    var cells = getElementsByTagNames(row, 'th', 'td');
    for (var i = 0; i < cells.length; i++) {
        var cell = cells[i];
        if (orig || cell.style.display != 'none') {
            // cell is not hidden, or we want hidden cells: add its colspan
            col += hideable.getColSpan(cell, orig);
            if (col > targetCol) return cell;
        }
    }
}

hideable.cellsInCol = function (cell) {
    // return array of cells in the same column as the given one
    if (!matchTagName(cell, 'td', 'th')) throw('not a table cell');
    var table = getContainer(cell, 'table');
    if (table === undefined) throw('cell not in a table');
    var col = hideable.getCol(cell, true);
    var rows = table.getElementsByTagName('tr');
    var cells = [];
    for (var i = 0; i < rows.length; i++) {
        cells.push(hideable.cellAtCol(rows[i], col, true));
    }
    return cells;
};

hideable.hide = function (cell) {
    var cells = hideable.cellsInCol(cell);
    for (var i = 0; i < cells.length; i++) {
        if (i == 0) {
            // replace header with 'show' button
            var showCell = document.createElement(cells[i].tagName);
            showCell.colspan = cells[i].colSpan;
            showCell.className = hideableShowClass;
            showCell.appendChild(hideable.createLink(false));
            hideable.hiddenHeaders[hideable.getCol(cells[i], false)] =
                cells[i].parentNode.replaceChild(showCell, cells[i]);
        } else {
            // hide this column's cells
            cells[i].style.display = 'none';
            // expand next visible column's cells, if any, to this one
            var expand = cells[i];
            do expand = nextElement(expand);
            while (expand !== null &&
                (expand.nodeType != 1 || expand.style.display == 'none'))
            if (expand === null) {
                // couldn't find a next column: look for a previous one
                expand = cells[i];
                do expand = previousElement(expand);
                while (expand !== null &&
                    (expand.nodeType != 1 || expand.style.display == 'none'))
            }
            if (expand !== null)
                hideable.setColSpan(expand, expand.colSpan + cells[i].colSpan);
        }
    }
};

hideable.show = function (cell) {
    var cells = hideable.cellsInCol(cell);
    for (var i = 0; i < cells.length; i++) {
        // show this column's cells
        cells[i].style.display = '';
        if (i == 0) {
            // remove 'show' button
            var col = hideable.getCol(cells[i], false);
            var origCell = hideable.hiddenHeaders[col];
            cells[i] = cells[i].parentNode.replaceChild(origCell, cells[i]);
        } else {
            cell = cells[i];
            // work out where we want the ends of the cell to be
            var leftEdge = hideable.getCol(cell, true);
            var rightEdge = leftEdge + (cell.origColSpan || cell.colSpan);
            var change = 0;
            var prevCell = previousElement(cell);
            while (prevCell !== null) {
                if (prevCell.style.display == 'none')
                    // move left to cover hidden cells directly to the left
                    leftEdge -= prevCell.origColSpan || prevCell.colSpan;
                else {
                    // shrink the first visible cell to the left if it covers
                    // any hidden cells we want this cell to cover
                    var pos = hideable.getCol(prevCell, false);
                    if (pos + prevCell.colSpan > leftEdge) {
                        change = pos + prevCell.colSpan - leftEdge;
                        hideable.setColSpan(prevCell, leftEdge - pos);
                    }
                    break;
                }
                prevCell = previousElement(prevCell);
            }
            var nextCell = nextElement(cell);
            var flowRight = 0;
            // need to explicitly set to undefined as we reuse it
            var nextVisible = undefined;
            while (nextCell !== null) {
                if (nextCell.style.display == 'none')
                    // expand to cover hidden cells to the right
                    flowRight += nextCell.origColSpan || nextCell.colSpan;
                else {
                    // until we encounter a visible one, which should cover
                    // them instead
                    flowRight = 0;
                    nextVisible = nextCell;
                    break;
                }
                nextCell = nextElement(nextCell);
            }
            rightEdge += flowRight;
            // expand cell as far right as needed
            hideable.setColSpan(cell, rightEdge - leftEdge);
            change -= cell.colSpan;
            if (nextVisible !== undefined)
                // expand or shrink the visible cell directly to the right to
                // adjust for the changes we've made
                hideable.setColSpan(nextVisible, nextVisible.colSpan + change);
        }
    }
};

hideable.init = function () {
    var tables = document.getElementsByTagName('table');
    if (tables.length == 0) return;
    hideable.hiddenHeaders = [];
    // load images
    new Image().src = hideImageURL;
    new Image().src = showImageURL;
    for (var i = 0; i < tables.length; i++) {
        // operate on first row
        var row = tables[i].getElementsByTagName('tr')[0];
        if(row === undefined) return;
        var cells = getElementsByTagNames(row, 'th', 'td');
        for (var j = 0; j < cells.length; j++) {
            if (hasClass(cells[j], hideableColClass)) {
                // add 'hide' button
                cells[j].appendChild(hideable.createLink(true));
                // hide column now if want to
                if (hasClass(cells[j], hiddenColClass))
                    hideable.hide(cells[j]);
            }
        }
    }
};

$( hideable.init );


// JavaScript countdown timer 2.0, by Splarka
//
//  <span class="countdown" style="display:none;">
//  Only <span class="countdowndate">January 01 2013 00:00:00 PST</span> until New years.
//  </span>
//  <span class="nocountdown">Javascript disabled.</span>

if ($('body.page-Main_Page').length) {

;(function (module, mw, $) {
    
    'use strict';
    
    var translations = $.extend(true, {
        en: {
            and: 'and',
            second: 'second',
            seconds: 'seconds',
            minute: 'minute',
            minutes: 'minutes',
            hour: 'hour',
            hours: 'hours',
            day: 'day',
            days: 'days'
        }
    }, module.translations || {}),
    i18n = translations[
        mw.config.get('wgContentLanguage')
    ] || translations.en;

    var countdowns = [];
    
    var NO_LEADING_ZEROS = 1;
    
    function output (i, diff) {
        /*jshint bitwise:false*/
        var delta, result, parts = [];
        delta = diff % 60;
        parts.unshift(delta + ' ' + i18n[delta === 1 ? 'second' : 'seconds']);
        diff = Math.floor(diff / 60);
        delta = diff % 60;
        parts.unshift(delta + ' ' + i18n[delta === 1 ? 'minute' : 'minutes']);
        diff = Math.floor(diff / 60);
        delta = diff % 24;
        parts.unshift(delta + ' ' + i18n[delta === 1 ? 'hour'   : 'hours'  ]);
        diff = Math.floor(diff / 24);
        parts.unshift(diff  + ' ' + i18n[diff  === 1 ? 'day'    : 'days'   ]);
        result = parts.pop();
        if (countdowns[i].opts & NO_LEADING_ZEROS) {
            while (parts.length && parts[0][0] === '0') {
                parts.shift();
            }
        }
        if (parts.length) {
            result = parts.join(', ') + ' ' + i18n.and + ' ' + result;
        }
        countdowns[i].node.text(result);
    }
    
    function end(i) {
        var c = countdowns[i].node.parent();
        switch (c.attr('data-end')) {
            case 'remove':
                c.remove();
                countdowns.splice(i, 1);
                return;
            case 'stop':
                output(i, 0);
                countdowns.splice(i, 1);
                return;
            case 'toggle':
                var toggle = c.attr('data-toggle');
                if (toggle && $(toggle).length) {
                    $(toggle).css('display', 'inline');
                    c.css('display', 'none');
                    countdowns.splice(i, 1);
                    return;
                }
                break;
            case 'callback':
                var callback = c.attr('data-callback');
                if (callback && $.isFunction(module[callback])) {
                    output(i, 0);
                    countdowns.splice(i, 1);
                    module[callback].call(c);
                    return;
                }
                break;
        }
        countdowns[i].countup = true;
        output(i, 0);
    }
    
    function update () {
        var now = Date.now();
        $.each(countdowns.slice(0), function (i, countdown) {
            var diff = Math.floor((countdown.date - now) / 1000);
            if (diff <= 0 && !countdown.countup) {
                end(i);
            } else {
                output(i, Math.abs(diff));
            }
        });
        if (countdowns.length) {
            window.setTimeout(function () {
                update();
            }, 1000);
        }
    }
    
    function getOptions (node) {
        /*jshint bitwise:false*/
        var text = node.parent().attr('data-options'),
            opts = 0;
        if (text) {
            if (/no-leading-zeros/.test(text)) {
                opts |= NO_LEADING_ZEROS;
            }
        }
        return opts;
    }
    
    $(function () {
        var countdown = $('.countdown');
        if (!countdown.length) return;
        $('.nocountdown').css('display', 'none');
        countdown
        .css('display', 'inline')
        .find('.countdowndate')
        .each(function () {
            var $this = $(this),
                date = (new Date($this.text())).valueOf();
            if (isNaN(date)) {
                $this.text('BAD DATE');
                return;
            }
            countdowns.push({
                node: $this,
                opts: getOptions($this),
                date: date,
            });
        });
        if (countdowns.length) {
            update();
        }
    });
    
}(window.countdownTimer = window.countdownTimer || {}, mediaWiki, jQuery));

}

/* Make it so users can click on "explain" spans to toggle their content.
   Useful for mobile users, since there's no mouse-over. */
var explain_spans = document.getElementsByClassName("explain");
for(var e = 0; e < explain_spans.length; e++) {
  explain_spans[e].onclick = function(){ toggleExplain(this); };
}

function toggleExplain(e) {
  var old = e.getAttribute("oldContent");
  
  if(old && old.length > 0) {
    e.innerHTML = old;
    e.setAttribute("oldContent", "");
    e.style.textDecoration = "underline dotted";
  } else {
    e.setAttribute("oldContent", e.innerHTML);
    e.innerHTML = e.getAttribute(switchableSectionTitleAttr);
    e.style.textDecoration = "underline dashed";
  }
}

/* move game icons into #content for more consistent positioning */
$(function () {$('#game-icons').css('margin-top', '5px').insertBefore($('#firstHeading'))})

/* Pikan */
$.getScript('/index.php?title=User:Espyo/pikan-core.js'
+ '&action=raw&ctype=text/javascript', function () {
  mw.loader.load('/index.php?title=User:Espyo/pikan-pikipedia.js'
  + '&action=raw&ctype=text/javascript');
});

/* Upload page script */
mw.loader.load('/index.php?title=MediaWiki:PikipediaUpload.js'
+ '&action=raw&ctype=text/javascript');


/* End of mw.loader.using callback */
} );
/* DO NOT ADD CODE BELOW THIS LINE */