MediaWiki:Common.js

/***********************************************************************************

of page in ' '. Will load immediately before Wikia.js.
 * This 'MediaWiki:Common.js' will be loaded via imported '/site' file, at the *top*

of page in ' '. Will load immediately after Common.js and before importArticles.
 * The 'MediaWiki:Wikia.js' will be loaded via imported '/site' file, at the *top*

'/load.php' file, separately appearing at the *bottom* of the page.
 * Common 'importArticles' files will be loaded together via dynamic import as


 * All files will be checked and minified nearly the same.

to be a part of the default theme and are supposed theme specific. Currently on here, there is *no* theme specific JS. Please error on the side of placing code in Common.js rather than Wikia.js. *All* js code should be tolerant of thematic changes and any degradation on the various devices.
 * 'Common' files are supposed to be theme agnostic, and 'Wikia' files are supposed



/* ***************************************    How to Navigate Common.js   ***************************************

Major section headers look like this:

*******************************************************************************************

SECTION  Namespace:File.css

*******************************************************************************************

There should be several main sections: 1) SECTION Standard Functions - a subset of the standard MediaWiki:Common.js function 2) SECTION Import - code from other files 3) SECTION Extensions - common extensions, or support/fixes for installable ones 4) SECTION Startup - code to run on start, page startup event or timer, or inlined

Major startup code is placed here usually calling the 'single use' named functions for each feature thatneeds to be loaded on page load complete.



/*******************************************************************************************

SECTION Standard Functions



function getParamValue(name) {  // Extract a URL parameter. See wikipedia:User:Lupin/autoedit.js var regex = RegExp('[&?]' + name + '=([^&]*)'); var h = document.location.href, m = regex.exec(h); if (m) { try { return decodeURIComponent(m[1]); } catch (someError) {} } return null; }

/** name - cookie name, value - 'on' or 'off' or whatever, exdays - expiry of cookie in days */ function setCookie(name, value, exdays) {  // Sets a cookie value = name + "=" + escape(value); if (exdays !== null) { var d = new Date; value += ";expires=" + d.setDate(d.getDate + exdays).toGMTString; } document.cookie = value; }

/** name - cookie name, @return - cookie or empty string */ function getCookie(name) {   // Gets a cookie var c = document.cookie; if (c.length > 0) { var s = c.indexOf(name + "="); if (s !== -1) { var e = c.indexOf(";", s = s + name.length + 1); return unescape(c.substring(s, (e !== -1) ? e : e = c.length)); } }  return ""; }

/*******************************************************************************************

SECTION Import



// AjaxRC - needed beore loading script // var ajaxIndicator = 'http://images1.wikia.nocookie.net/__cb1/wowwiki/images/0/0e/Progressbar.gif';

// Import Scripts importArticles({ type: 'script',  //debug: true,  articles: [    'MediaWiki:jquery-ui/jquery.effects.js',  // working version of ui effects. used by 'FloatingToc' and 'SlideShow'    //'MediaWiki:Test.js',    'u:dev:AjaxRC/code.js',                   // intended as common ajax dependency for user extensions, like below    'u:dev:Countdown/code.js',    'MediaWiki:FloatingToc/code.js',          // popout TOC. static as is used nearly all pages but portals, etc...    'u:dev:InactiveUsers/code.js',            // MediaWiki:Wikia.js/userRightsIcons.js appears to override    'MediaWiki:Wikiaapp.js',    'MediaWiki:MapLightbox/code.js',          // on page WoW maps support    'MediaWiki:SlideShow/code.js',            // general slide show and rotating banner support. See 'Template:Slideshow'    'MediaWiki:UserTags/userRightsIcons.js',  // puts things like "ADMINISTRATOR" or "CRAZY PERSON" tags on talk pages ] });

/*******************************************************************************************

SECTION Extensions



/* *****************************************************************  NO LONGER APPLICABLE

//FIXME: make sure then remove

// is expensive, is replaced by mw-collapsible is part of mw core. //  was always optional for wikis as coy paste install, thats inherently //   unmaintained with rest of wikia. // imputus for removal is performance and lowering maintenence burden. //see: Template:Collapsible and friendds

// **************************************** // ****   Collapsible - Deprecated    **** // ****************************************

//FIXME: remove both 'collapsible' and 'NavFrame'. // are very inefficent and superceeded by core feature 'mw-collapsible'

// Collapsible - original 'collapsible' extension var autoCollapse = 2; var collapseCaption = "hide"; var expandCaption = "show";

function collapseTable(i) { var Button = $("#collapseButton" + i); var Table = $("#collapsibleTable" + i); if (Table.length < 1 || Button.length < 1) return false; if (Button.text == collapseCaption) { Table.find("tr").not(":has('#collapseButton" + i + "')").hide; setCookie("hideTable-" + wgArticleId + "-" + i, 1, 30); Button.text(expandCaption); } else { Table.find("tr").not(":has('#collapseButton" + i + "')").show; setCookie("hideTable-" + wgArticleId + "-" + i, 0, 30); Button.text(collapseCaption); } } function createCollapseButtons { var tch = $("table.collapsible tr th:last-child"); tch.each(function (i) {   $(this).closest("table").attr("id", "collapsibleTable" + i);    $(this).prepend(' [' + collapseCaption + '] ');    if ($(this).closest("table").hasClass("collapsed") || (getCookie("hideTable-" + wgArticleId + "-" + i) == 1) || (tch.length >= autoCollapse && $(this).closest("table").hasClass("autocollapse"))) collapseTable(i);  }); }

// NavFrame - original 'collapsible' navigation extension var nbh = '[' + collapseCaption + ']'; var nbs = '[' + expandCaption + ']'; function toggleNavigationBar(i) { var NavToggle = $("#NavToggle" + i); var NavFrame = $("#NavFrame" + i); if (NavFrame.length < 1 || NavToggle.length < 1) return false; ncd = (NavToggle.text == nbh) ? 'none' : 'block'; NavFrame.children(".NavPic,.NavContent").css("display", ncd); nct = (NavToggle.text == nbh) ? nbs : nbh; NavToggle.text(nct); } // adds show/hide-button to navigation bars function createNavigationBarToggleButton { $("div.NavFrame").each(function (i) {   NavToggleText = ($(this).children(".NavPic:visible,.NavContent:visible").length > 0) ? nbh : nbs;    $(this).children(".NavHead").append('' + NavToggleText + '');    $(this).attr("id", "NavFrame" + i);  }); }

NO LONGER APPLICABLE

//**************************************** //****   Tooltips                    **** //****************************************

// See Help:Tooltips // default setting to turn tooltips on var tooltipsOn = true;

// allow users to specify an external db to change links to var extDB = "http://www.wowwiki.com/";

var $tfb; var $ttfb; var $htt;

// hides the tooltip function hideTip { $tfb.html("").removeClass("tooltip-ready").addClass("hidden").css("visibility", "hidden"); }

// displays the tooltip function displayTip(e) { $htt.not(":empty").removeClass("hidden").addClass("tooltip-ready"); moveTip(e); $htt.not(":empty").css("visibility", "visible"); }

// moves the tooltip function moveTip(e) { var newTop = e.clientY + ((e.clientY > ($(window).height / 2)) ? -($htt.not(".hidden").innerHeight + 20) : 20); var newLeft = e.clientX + ((e.clientX > ($(window).width / 2)) ? -($htt.not(".hidden").innerWidth + 20) : 20); $htt.not(".hidden").css({   "position": "fixed",    "top": newTop + "px",    "left": newLeft + "px"  }); }

// AJAX tooltips function showTip(e) { $t = $(this); $p = $t.parent; if ($p.hasClass("selflink") == false) { $t.removeAttr("title"); $p.removeAttr("title"); $tfb.load("/" + $t.data("tt").replace(/ /g, "_").replace(/\?/g, "%3F") + "?action=render div.tooltip-content", function {      if ($tfb.html == "") $tfb.html(' Error This target either has no tooltip or was not intended to have one. ');     $tfb.find(".tooltip-content").css("display", "");      displayTip(e);    }); } }

// quick tooltips function hideTemplateTip { $ttfb.html("").removeClass("tooltip-ready").addClass("hidden"); }

function showTemplateTip(e) { $ttfb.html(' ' + $(this).next.html + ' '); displayTip(e); }

// add the tooltip calls to the page function eLink(db, nm) { dbs = new Array("http://us.battle.net/wow/en/search?q=", "http://www.wowhead.com/?search=", "http://db.mmo-champion.com/search/all/", "http://www.wowdb.com/search?search="); dbTs = new Array("Armory", "Wowhead", "DB MMO-Champion", "WoWDB"); dbHs = new Array("&real; ", "&omega; ", "&delta; ", "&piv; "); el = '' + dbHs[db] + ''; return el; }

function ttBind { $t = $(this); $p = $t.parent; if ($p.hasClass("selflink") == false) { $t.data("tt", $p.attr("title").replace(" (page does not exist)", "").replace("?", "%3F")).mouseover(showTip).mouseout(hideTip).mousemove(moveTip); if ($p.hasClass("new")) { els = ' '; y = ($t.hasClass("itemlink")) ? 0 : 1;     z = ($t.hasClass("achievementlink")) ? 3 : 4;     for (x = y; x < z; x++) els += eLink(x, $t.data("tt").replace("Quest:", "")); $p.after(els + ' '); }   if (extDB != "http://www.wowwiki.com/") { fullextURL = extDB + $t.data("tt"); $p.attr("href", fullextURL); } } }

// check to see if it is active then do it function ttMouseOver(foo) { if (tooltipsOn && getCookie("wiki-tiploader") != "no") { $("#WikiaArticle").mouseover(hideTip); $("#WikiaArticle").append(' '); $tfb = $("#tfb"); $ttfb = $("#templatetfb"); $htt = $("#tfb,#templatetfb"); if (foo == 1) { $("#WikiaArticle span.ajaxttlink").each(ttBind); }   $("#WikiaArticle span.tttemplatelink").mouseover(showTemplateTip).mouseout(hideTemplateTip).mousemove(moveTip); } }

//**************************************** //****   ScribbleMap                 **** //****************************************

function wwScribbleMaps {          // see Template:ScribbleMap $("#WikiaArticle div.wwSM").each(function {    var mapID = $(this).attr("class").replace("wwSM map-", ""), width = $(this).width, height = $(this).height;    if (mapID.length > 20) mapID = ""; if (width <= 0) width = 550; if (height <= 0) height = Math.floor(width / 11 * 8);    $(this).html(' '); }); }

//**************************************** //****   AJAX tables                 **** //****************************************

ahClass = new RegExp('class="ajaxHide"', "gim"); crlf = new RegExp("\r\n", "g")

function getTableData(tablePage, tableNum) { $("body").bind("ajaxSend", function { $(this).css("cursor", "wait"); }) .bind("ajaxComplete", function { $(this).css("cursor", "auto"); }); $.get('http://' + location.hostname + '/' + tablePage + '?action=render', function (data) {   if (data) {      data = data.replace(crlf, "").replace(ahClass, 'class="ajaxHide-active"').replace('class="darktable"', "");      $("#ajaxTable" + tableNum).find("td").eq(0).html(data);      $("#ajaxTable" + tableNum).find("td").eq(0).find("table.sortable").each(function (i) { ts_makeSortable($(this)); });     $("#stl" + tableNum).html('[edit] [hide</a>]');      ttMouseOver(0);    }  }); }

/* *****************************************************************  NO LONGER APPLICABLE

//FIXME: make sure then remove

// no longer use JS version instead use CSS, for long time. //  table makers use .alt on rowns or .zebra on table using CSS, //  which is also stylizable independantly per theme

function getTableData_zebra(tablePage, tableNum) { $("body").bind("ajaxSend", function {    $(this).css("cursor", "wait");  }).bind("ajaxComplete", function  {    $(this).css("cursor", "auto");  }); $.get('http://' + location.hostname + '/' + tablePage + '?action=render', function (data) {   if (data) {      data = data.replace(crlf, "").replace(ahClass, 'class="ajaxHide-active"').replace('class="darktable"', "");      $("#ajaxTable" + tableNum).find("td").eq(0).html(data);      $("#ajaxTable" + tableNum).find("td").eq(0).find("table.sortable").each(function (i) { ts_makeSortable($(this));

zebraAJAX = $(this).find("tr"); if (zebraAJAX.eq(2).css("background-color") == "transparent" && zebraAJAX.eq(3).css("background-color") == "transparent") { zebraAJAX.find(".sortheader").click(function {            $("#WikiaArticle table.zebra > tbody > tr").css("background-color", "transparent");            ac = (skin == "monobook") ? "#e9e9ff" : "#2c2c2c";            $("#WikiaArticle table.zebra > tbody > tr:nth-child(2n+1)").css("background-color", ac);          }); }     });      zebraAJAX = $("#WikiaArticle .ajax td > table.zebra > tbody > tr");      if (zebraAJAX.eq(1).css("background-color") == "transparent" && zebraAJAX.eq(2).css("background-color") == "transparent") {        $("#WikiaArticle .ajax td > table.zebra > tbody > tr:nth-child(2n+1)").css("background-color", "#2c2c2c");        if (skin == "monobook") $("#WikiaArticle .ajax td > table.zebra > tbody > tr:nth-child(2n+1)").css("background-color", "#e9e9ff");      }      $("#stl" + tableNum).html('[edit</a>] [hide</a>]');      ttMouseOver(0);    }  }); }

NO LONGER APPLICABLE

function hideTable(tableNum) { $("#ajaxTable" + tableNum).find("tr").eq(1).hide; $("#htl" + tableNum).click(function {    showTable(tableNum);  }); $("#htl" + tableNum).text("show"); }

function showTable(tableNum) { $("#ajaxTable" + tableNum).find("tr").eq(1).show; $("#htl" + tableNum).click(function {    hideTable(tableNum);  }); $("#htl" + tableNum).text("hide"); }

function loadTableData(tableNum) { thisTable = document.getElementById("ajaxTable" + tableNum); loadPage = thisTable.className.substring(thisTable.className.indexOf("targetPage-") + 11); getTableData(loadPage, tableNum); }

function addAjaxDisplayLink { $("#WikiaArticle table.ajax").each(function (i) {   $(this).attr("id", "ajaxTable" + i);    $(this).find("td").eq(1).parent.hide;    $(this).find("td").eq(0).parent.show;    if (this.getElementsByTagName("th").length > 0) this.getElementsByTagName("th")[0].innerHTML = '<span style="float:right;" id="stl' + i + '"> ' + this.getElementsByTagName("th")[0].innerHTML;    if ($(this).find("td").eq(0).hasClass("showLinkHere")) {      $(this).find("td").eq(0).html($(this).find("td").eq(0).html.replace("[link]", '').replace("[/link]", "</a>"));    } else {      $("#stl" + i).html('[show data</a>]');    }  }); }

//**************************************** //****   Semantic Mediawiki          **** //****************************************

// this is pretty much ineffective, as I think there is no more 'mw-data-after-content' id. i cant find one. function smwToggleFacts { if ($("#SMWFactToggle").text == "hide") { $("#mw-data-after-content table.smwfacttable tr").hide; setCookie("hideSMWFacts", "true"); $("#SMWFactToggle").text("show"); } else { $("#mw-data-after-content table.smwfacttable tr").show; setCookie("hideSMWFacts", "false"); $("#SMWFactToggle").text("hide"); } }

// setup for fast on demand init, only iof page contains tag function smwInitPage { if ($("#mw-data-after-content table.smwfacttable tr").length == 0) { $("#mw-data-after-content div.smwfact").hide; } else { $("#mw-data-after-content span.smwrdflink").after(' [hide</a>] '); } if (getCookie("hideSMWFacts") == "true") { smwToggleFacts; } }

/*******************************************************************************************

SECTION Startup



/* *****************************************************************  NO LONGER APPLICABLE

//FIXME: make sure then remove

// part of no longer needed alt row JS purge. is basically build up of cruft for //  reason this is still here. alt row is in css, and configuable per theme

// Fix Alt Rows - patching in changes to table sorting and alt rows //FIXME: very expensive function changeTS { window.ts_alternate = function (table) { $(table).find("tbody").find("tr:odd").removeClass("alt"); $(table).find("tbody").find("tr:even").addClass("alt"); } window.ts_makeSortable = function (table) { var firstRow; if ($(table).find("tr").length > 0) {      firstRow = ($(table).find("th").length > 0) ? $(table).find("tr:has(th)").eq(0) : $(table).find("tr").eq(0); }   if (!firstRow) return; firstRow.children(":not('.unsortable')").append('  <img src="' + ts_image_path + ts_image_none + '" alt="&darr;"/> </a>'); if (ts_alternate_row_colors) ts_alternate(table); } }

NO LONGER APPLICABLE

// patching in changes to table sorting and alt rows function wwSortableTableInit { window.ts_makeSortable = function (table) { var firstRow; if ($(table).find("tr").length > 0) { firstRow = ($(table).find("th").length > 0) ? $(table).find("tr:has(th)").eq(0) : $(table).find("tr").eq(0); }   if (!firstRow) return; firstRow.children(":not('.unsortable')").append('  <img src="' + ts_image_path + ts_image_none + '" alt="&darr;"/> </a>'); } }

// Fix Image Form - see Special:Upload. relatively inexpensive as scoped to particular page. //FIXME: need name of page function requireImageLicense { if (wgPageName == "Special:Upload" && getParamValue("wpDestFile") == null) { $wpu = $("#mw-upload-form").find("[name=wpUpload]").not("#wpUpload"); $wpu.attr("disabled", "true"); $("#wpLicense").change(function {      if ($("#wpLicense").val) {        $wpu.removeAttr("disabled");      } else {        $wpu.attr("disabled", "true");      }    }); } }

function sortDays(a, b) { return b.substring(b.indexOf(";") + 1) - a.substring(a.indexOf(";") + 1); }

function loadGSList { if ($("#gslist").length > 0) { var timestamp = 0; var today = new Date; var tsDate = new Date; var dateRE = /(\d{4})-(\d\d)-(\d\d).*/; var pArr = new Array; $.getJSON("http://www.wowwiki.com/api.php?action=query&generator=categorymembers&gcmlimit=500&gcmsort=timestamp&gcmdir=desc&gcmtitle=Category:Guild_stubs&prop=revisions&rvprop=timestamp&format=json&callback=?", function (data) {     if (data.query) {        pages = data.query.pages;        for (pageID in pages) {          timestamp = pages[pageID].revisions[0].timestamp;          dateREd = dateRE.exec(timestamp);          tsDate.setFullYear(dateREd[1], dateREd[2] - 1, dateREd[3]);          daysElapsed = Math.round((today - tsDate) / 86400000);          pArr[pArr.length] = pages[pageID].title + ";" + daysElapsed;        }        pArr2 = pArr.sort(sortDays);        gslBuffer = "<ul>";        for (n in pArr2) {          guild = pArr2[n].substring(0, pArr2[n].indexOf(";"));          daysE = pArr2[n].substring(pArr2[n].indexOf(";") + 1);          daysE = (daysE < 0) ? 0 : daysE; daysE = (daysE > 29) ? ' (' + daysE + ' days) ' : '(' + daysE + ' days)'; gslBuffer += '<li>' + guild + '</a> ' + daysE + ' - History</a> &bull; Delete</a></li>'; }       gslBuffer += "</ul>"; $("#gslist").html(gslBuffer); }   });  } }

dil = new Array; function findDupImages(gf) { output = ""; url = "/api.php?action=query&generator=allimages&prop=duplicatefiles&gailimit=500&format=json"; if (gf) url += "&gaifrom=" + gf; $.getJSON(url, function (data) {   if (data.query) {      pages = data.query.pages;      for (pageID in pages) {        dils = "," + dil.join;        if (dils.indexOf("," + pages[pageID].title) == -1 && pages[pageID].title.indexOf("File::") == -1 && pages[pageID].duplicatefiles) {          output += " " + pages[pageID].title + "</a> \n<ul>\n";          for (x = 0; x < pages[pageID].duplicatefiles.length; x++) {            output += "<li>File:" + pages[pageID].duplicatefiles[x].name + "</a></li>\n";            dil.push("File:" + pages[pageID].duplicatefiles[x].name.replace(/_/g, " "));          }          output += "</ul>\n\n"        }      }      $("#mw-dupimages").append(output);      if (data["query-continue"]) setTimeout("findDupImages('" + data["query-continue"].allimages.gaifrom + "');", 5000); } }); }

// Startup. Needs cleanup badly. $(function {  if (wgAction == "view" && wgArticleId == 0 && wgNamespaceNumber == 0 && document.referrer.indexOf("search") == -1)    document.location = "/Special:Search?search=" + wgTitle;

// Part of AJAX RC // Comment out when using dev.wikia.com version //for (x in ajaxPages) { if (wgPageName == ajaxPages[x] && $("#ajaxToggle").length==0) ajaxRC; }

// this has been inactive since the original set of wmp 'lite' templates. --celess22 //if (wgCanonicalNamespace == "Portal") doPortals;

//createCollapseButtons;  NO LONGER APLICABLE //createNavigationBarToggleButton;  NO LONGER APLICABLE

wwSortableTableInit; requireImageLicense; loadGSList;

if ($("#mw-dupimages").length) findDupImages; if (wgUserName != null) $("span.insertusername").html(wgUserName);

$(".mw-mpt-link").html("Links to the old page title</a>"); });

/* New Coords template support - by Pecoes */ (function (mw, $) {

'use strict';

if (window.sessionStorage && window.sessionStorage.getItem('noMapLinks')) return;

$(function {    var $body = $('body.mediawiki'),      $window = $(window),

distance = 20, mapWidth = 300, mapHeight = 200, blip = 'http://images4.wikia.nocookie.net/__cb1/wowwiki/images/f/f4/Blip.png', blipWidth = 11, blipHeight = 11;

mw.util.addCSS('\     .map-img {\        display: none;\        position: absolute;\        width: ' + mapWidth + 'px;\        height: ' + mapHeight + 'px;\        z-index: 2147483647;\        margin: 0;\      }\      .map-img.map-img-show {\        display: block;\      }\      .map-img-blip {\        position: relative;\        background-image: url("' + blip + '");\        width: ' + blipWidth + 'px;\        height: ' + blipHeight + 'px;\        margin-left: -' + blipWidth / 2 + 'px;\        margin-top: -' + blipHeight / 2 + 'px;\      }\      .map-img.map-img-left {\        margin-left: ' + distance + 'px;\      }\      .map-img.map-img-right {\        margin-left: -' + (mapWidth + distance) + 'px;\      }\      .map-img.map-img-bottom {\        margin-top: ' + distance + 'px;\      }\      .map-img.map-img-top{\        margin-top: -' + (mapHeight + distance) + 'px;\      }\    ');

$('.map-link') .each(function {        var $mapLink = $(this),          $magImg = $(' ')            .appendTo($body)            .addClass('map-img')            .css('background-image', 'url(' + $mapLink.data('map') + ')')            .append( $(' ')             .addClass('map-img-blip') .css({               left: $mapLink.data('left') + '%',                top: $mapLink.data('top') + '%',              }) );       $mapLink          .click(function (e) { e.preventDefault; e.stopPropagation; })         .mouseenter(function  { var width = $window.width, height = $window.height, scrollLeft = $window.scrollLeft, scrollTop = $window.scrollTop; $mapLink .on('mousemove', function (e) {               $magImg                  .css({ left: scrollLeft + e.clientX, top: scrollTop + e.clientY })                 .removeClass('map-img-left map-img-right map-img-top map-img-bottom')                  .addClass( width - e.clientX > mapWidth + distance ? 'map-img-left' : 'map-img-right' )                 .addClass( height - e.clientY > mapHeight + distance ? 'map-img-bottom' : 'map-img-top' );             });            $magImg .addClass('map-img-show') })         .mouseleave(function  { $mapLink .off('mousemove'); $magImg .removeClass('map-img-show map-img-left map-img-right map-img-top map-img-bottom') });     });  }); }(mediaWiki, jQuery));

//**************************************** //****   Starup from Wikia.js        **** //**************************************** // Needs to be interated

$(function {  if ($("#mw-data-after-content").length > 0) { smwInitPage; }  ttMouseOver(1);  addAjaxDisplayLink;  wwScribbleMaps; });

/*******************************************************************************************

SECTION New Fixes



/* Make Wowhead 3D model viewer button links open a new tab when clicked. */ $('a[href*="modelviewer"]').attr({ target: '_blank' });

/*******************************************************************************************

SECTION Loaders



/* Load Loaders that were registered and just waiting for mw and jq to run their own boot-strap functionality. There's a very long detailed reason for yet another loader. (function { var loaders = window.wwLoaders;  if (!loaders) return;

for (var i=0, l=loaders.length; i < l; i++) {   var loader = loaders[i]; if (typeof loader == 'function') { loader; } } });