MediaWiki:Common.js: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
m (return wantedPages)
(Collapsible prototype tree with indentation guides)
 
(54 intermediate revisions by 2 users not shown)
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. */
var apiUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + "/api.php"


/* Script in here will be executed when the page is "ready" */
/* Script in here will be executed when the page is "ready" */
Line 9: Line 11:
if (document.getElementById("active-users")) {
if (document.getElementById("active-users")) {
$.ajax({
$.ajax({
url: 'https://wiki.factorio.com/api.php',
url: apiUrl,
data: {
data: {
format: 'json',
format: 'json',
Line 28: Line 30:
}
}
};
};


/* User is bot if userGroup.some(isBot) == true */
/* Collapsible list on [[Prototype definitions]] */
 
$(".prototype-tree li").each(function (index, element) {
  if ( $( element ).children("ul").length > 0 ) {
    $( element ).addClass("prototype-tree-parent");
  };
});
 
$(".prototype-tree li.prototype-tree-parent").on("click", function(event) {
// only collapse if I clicked a li or the direct child of a li that is not another list or a link
  if ( $( event.currentTarget ).children("ul").length > 0 && $( event.target ).get(0).tagName != "UL" && $( event.target ).get(0).tagName != "A" && ($( event.target ).hasClass("prototype-tree-parent") || $( event.target ).parent().hasClass("prototype-tree-parent")) ) {
    $( event.currentTarget ).children("ul")[0].classList.toggle("hidden");
    $( event.currentTarget ).toggleClass("prototype-tree-parent-collapsed");
    return false; // prevents further event bubbling
  }
});
 
/* Evolution calc */
 
//values are in the form [evolution, weight]
const biterSpawner = [
["Small Biter",    [[0.0, 0.3], [0.6, 0.0]]],
["Medium Biter",  [[0.2, 0.0], [0.6, 0.3], [0.7, 0.1]]],
["Big Biter",      [[0.5, 0.0], [1.0, 0.4]]],
["Behemoth Biter", [[0.9, 0.0], [1.0, 0.3]]]
];
const spitterSpawner = [
["Small Biter",      [[0.0, 0.3], [0.35, 0.0]]],
["Small Spitter",    [[0.25, 0.0], [0.5, 0.3], [0.7, 0.0]]],
["Medium Spitter",  [[0.4, 0.0], [0.7, 0.3], [0.9, 0.1]]],
["Big Spitter",      [[0.5, 0.0], [1.0, 0.4]]],
["Behemoth Spitter", [[0.9, 0.0], [1.0, 0.3]]]
];


var userGroup = "";
//calculates the interpolated value
function lerp(low, high, pos) {
const s = high[0] - low[0];
const l = (pos - low[0]) / s;
return (low[1] * (1-l)) + (high[1] * l);
};


function getUserGroup() {
//gets the weight list
$.ajax({
function getValues(map, evo) {
url: 'https://wiki.factorio.com/api.php',
var result = {};
data: {
var sum = 0;
format: 'json',
map.forEach(function(data) {
action: 'query',
const list = data[1];
meta: 'userinfo',
var low = list[0];
uiprop: 'groups',
var high = list[list.length-1];
},
list.forEach(function(val) {
async: false,
if(val[0] <= evo && val[0] >  low[0])  low = val;
dataType: 'json',
if(val[0] >= evo && val[0] < high[0]) high = val;
type: 'GET',
});
success: function(data) {
var val = null;
userGroup = data.query.userinfo.groups
if(evo <= low[0]) val = low[1];
},
else if(evo >= high[0]) val = high[1];
else val = lerp(low, high, evo);
sum += val;
result[data[0]] = val;
});
Object.keys(result).forEach(function(data, index) {
result[data] = result[data] / sum;
});
});
return result;
};
function calcEvo() {
const evo = document.getElementById("evoInput").value;
genTable(getValues(biterSpawner, evo), document.getElementById("evoOutputBiter"), "Biter's Nest");
genTable(getValues(spitterSpawner, evo), document.getElementById("evoOutputSpitter"), "Spitter's Nest");
};
function percentile(value) {
return (value*100).toFixed(2) + "%";
};
};


function isBot(group) {
function genTable(data, tableElem, title) {
return group == "bot";
var html = '<tr><th>'+title+'</th><th>Chance</th>';
}
Object.keys(data).forEach(function(value) {
html += '<tr><td>'+value+'</td><td>'+percentile(data[value])+'</td>';
});
tableElem.innerHTML = html;
};


window.onload = function() {
var elem = document.getElementById("evoChecker");
if(elem != null) {
elem.innerHTML =
'Alternatively, enter an evolution factor below to see the chances.<br>' +
'<input style="margin-bottom:10px" type="number" id="evoInput" min=0 max=1 step=0.01 placeholder="Evolution" onchange="calcEvo()"></input><br>' +
'<table style="float:left;margin-right:10px" class="wikitable" id="evoOutputBiter"></table>' +
'<table class="wikitable" id="evoOutputSpitter"></table>';
calcEvo();
}
};


var globalToken;
/* Template:Inventory tooltips */


function getToken() {
var lastTouchTime = 0;
    $.ajax({
document.addEventListener('touchstart', updateLastTouchTime, true);
        url: 'https://wiki.factorio.com/api.php',
function updateLastTouchTime() {
        data: {
  lastTouchTime = new Date();
            format: 'json',
            action: 'query',
            meta: 'tokens',
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
          globalToken = data.query.tokens.csrftoken;
        },
        error: function( xhr ) {
            console.log("Failed to get token.");
        }
    });
}
}


/* Infobox more info in header */
$(".tab-head").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  var newRule = '.tab-head:hover:after{display: block; left: ' + (e.offsetX + 20) + 'px; top: ' + (e.offsetY + 20) + 'px;}';
  document.styleSheets[0].insertRule(newRule, countCssRules);
});


$(".more-button").click(function() {
$(".tab .factorio-icon").mousemove(function(e) {
   $(".more-content").toggle("fast");
   if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  $(e.currentTarget).children("a").attr("title", "");
  var text = $(e.currentTarget).children("a").children("img").attr("alt");
  var newRule = '.tab .factorio-icon:hover:after{display: block; ' + "content: '" + text + "'}";
  document.styleSheets[0].insertRule(newRule, countCssRules);
});
 
/* Template:BlueprintString */
 
$(".bps-box").click(function(event) {
var copyTarget = document.createElement("input");
copyTarget.setAttribute("value", $( event.target ).children("p").html());
document.body.appendChild(copyTarget);
copyTarget.select();
document.execCommand("copy");
document.body.removeChild(copyTarget);
});
});


Line 91: Line 169:
$(".tab-head").removeClass("tab-head-active");
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(this).addClass("tab-head-active");
  $(".tab").hide();
$(".tab").hide();
$(".tab-1").show();
$(".tab-1").show();
});
});
Line 118: Line 196:
//*** Language template ***//
//*** Language template ***//
if($(".languages-flags .flag").length == 0) {
if($(".languages-flags .flag").length == 0) {
console.log("Not showing languages bar because there's no other language's version of this page.");
console.log("Not showing languages bar because there's no other language's version of this page.");
$(".languages-container").hide();
$(".languages-container").hide();
}
}


//Spoiler template JavaScript
//Spoiler template
$(".spoiler-container .button").click(function() {
$(".spoiler-container .button").click(function() {
  $(this).siblings(".text").toggle("slow");
$(this).siblings(".text").toggle("slow");
});
});


var wantedPagesListsLocation = "Factorio:Wanted pages";
//* General/generic functions *//
var enPageLength = {};
 
var stubs = {};
/* User is bot if userGroup.some(isBot) == true */
var disambigs = {};
 
var userGroup = "";


function getStubs() {
function getUserGroup() {
  $.ajax({
$.ajax({
url: 'https://wiki.factorio.com/api.php',
url: apiUrl,
data: {
data: {
format: 'json',
format: 'json',
action: 'query',
action: 'query',
list: 'categorymembers',
meta: 'userinfo',
cmtitle: 'Category:Stubs',
uiprop: 'groups',
cmlimit: 400,
cmprop: 'title'
},
},
async: false,
async: false,
dataType: 'json',
dataType: 'json',
type: 'GET',
type: 'GET',
success: function( data ) {
success: function(data) {
var categorymembers = data.query.categorymembers;
userGroup = data.query.userinfo.groups
console.log('Found ' + categorymembers.length + ' stubs.');
      for (var i = 0; i < categorymembers.length; i++) {
        stubs[categorymembers[i].title] = true;
      }
},
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
}
});
});
};
};


function getDisambigs() {
function isBot(group) {
  $.ajax({
return group == "bot";
url: 'https://wiki.factorio.com/api.php',
}
 
/* Get token of this session */
 
var globalToken;
 
function getToken() {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'query',
            meta: 'tokens',
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
          globalToken = data.query.tokens.csrftoken;
        },
        error: function( xhr ) {
            console.log("Failed to get token.");
        }
    });
}
 
 
function genericEditPage(title, content, summary) {
$.ajax({
url: apiUrl,
data: {
data: {
format: 'json',
format: 'json',
action: 'query',
action: 'edit',
list: 'categorymembers',
title: title,
cmtitle: 'Category:Disambiguations',
text: content,
cmlimit: 400,
token: globalToken,
cmprop: 'title'
summary: summary,
bot: true,
nocreate: true
},
},
async: false,
dataType: 'json',
dataType: 'json',
type: 'GET',
type: 'POST',
success: function( data ) {
success: function( data ) {
var categorymembers = data.query.categorymembers;
console.log("Edited " + title);
console.log('Found ' + categorymembers.length + ' disambigs.');
      for (var i = 0; i < categorymembers.length; i++) {
        disambigs[categorymembers[i].title] = true;
      }
},
},
error: function( xhr ) {
error: function( xhr ) {
alert( 'Error: Request failed.' );
alert("Failed to edit " + title);
}
}
});
});
};
};


$("#create-wanted-pages-list").click(function(){
    getToken();
    createWantedPagesLists();
});


function createWantedPagesLists() {
function createPage(pageTitle, content, summary) {
     getUserGroup();
     $.ajax({
    if (userGroup.some(isBot) == false) return;
         url: apiUrl,
    enPageLength = {};
    var wantedPages = getWantedPages();
    wantedPages = filterWantedPages(wantedPages);
    wantedPages = wantedPages.sort(compare);
    splitWantedPagesIntoDifferentLanguages(wantedPages);
};
 
function filterWantedPages(wantedPages) {
  for (var i = 0; i < wantedPages.length; i++) {
    if ((wantedPages[i].title.indexOf("File:") == -1) && (wantedPages[i].title.indexOf("Template:") == -1)) { //not doing this for file or template pages
      $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         data: {
         data: {
            format: "json",
format: 'json',
            action: 'query',
action: 'edit',
            list: "backlinks",
title: pageTitle,
            bltitle: wantedPages[i].title,
text: content,
            bllimit: 500,
token: globalToken,
            blnamespace: 0|4|6|8|10|12|14|3000|3002 //Main, Project (Factorio), File, MediaWiki, Template, Help, Category, Tutorial, Infobox
summary: summary,
bot: true
         },
         },
         async: false,
         async: false,
         type: 'GET',
        dataType: 'json',
         type: 'POST',
         success: function( data ) {
         success: function( data ) {
          if (data.query.backlinks.length == 0) {
console.log("Created page: " + pageTitle);
            wantedPages.splice(i, 1);
          }
         },
         },
         error: function( xhr ) {
         error: function( xhr ) {
          alert( 'Error: Backlinks request failed.' );
console.log("Failed to create page");
         }
         }
      });
     });
    }
  }
  return wantedPages;
};
 
function splitWantedPagesIntoDifferentLanguages(wantedPages) {
  var czechWantedPages = [];
  var germanWantedPages = [];
  var spanishWantedPages = [];
  var frenchWantedPages = [];
  var italianWantedPages = [];
  var japaneseWantedPages = [];
  var dutchWantedPages = [];
  var polishWantedPages = [];
  var portugueseWantedPages = [];
  var russianWantedPages = [];
  var swedishWantedPages = [];
  var ukrainianWantedPages = [];
  var chineseWantedPages = [];
  var turkishWantedPages = [];
  var koreanWantedPages = [];
  var wantedFiles = [];
  var wantedFileTalk = [];
  var wantedTemplates = [];
  var otherWantedPages = [];
 
  for (var i = 0; i < wantedPages.length; i++) {
     switch (wantedPages[i].title.slice(-3)) {//"/cs", "/de", "/es", "/fr", "/it", "/ja", "/nl", "/pl", "/-br", "/ru", "/sv", "/uk", "/zh", "/tr", "/kr"
      case "/cs": czechWantedPages.push(wantedPages[i]); break;
      case "/de": germanWantedPages.push(wantedPages[i]); break;
      case "/es": spanishWantedPages.push(wantedPages[i]); break;
      case "/fr": frenchWantedPages.push(wantedPages[i]); break;
      case "/it": italianWantedPages.push(wantedPages[i]); break;
      case "/ja": japaneseWantedPages.push(wantedPages[i]); break;
      case "/nl": dutchWantedPages.push(wantedPages[i]); break;
      case "/pl": polishWantedPages.push(wantedPages[i]); break;
      case "-br": portugueseWantedPages.push(wantedPages[i]); break;
      case "/ru": russianWantedPages.push(wantedPages[i]); break;
      case "/sv": swedishWantedPages.push(wantedPages[i]); break;
      case "/uk": ukrainianWantedPages.push(wantedPages[i]); break;
      case "/zh": chineseWantedPages.push(wantedPages[i]); break;
      case "/tr": turkishWantedPages.push(wantedPages[i]); break;
      case "/kr": koreanWantedPages.push(wantedPages[i]); break;
      default: if (wantedPages[i].title.slice(0, 5) == "File:") {wantedFiles.push(wantedPages[i])} else if (wantedPages[i].title.slice(0, 9) == "Template:") {wantedTemplates.push(wantedPages[i])} else if (wantedPages[i].title.slice(0, 10) == "File talk:") {wantedFileTalk.push(wantedPages[i])} else {otherWantedPages.push(wantedPages[i])}; break;
    }
  }
 
  getStubs();
  getDisambigs();
  createWantedPagesPage("cs", czechWantedPages, "Czech");
  createWantedPagesPage("de", germanWantedPages, "German");
  createWantedPagesPage("es", spanishWantedPages, "Spanish");
  createWantedPagesPage("fr", frenchWantedPages, "French");
  createWantedPagesPage("it", italianWantedPages, "Italian");
  createWantedPagesPage("ja", japaneseWantedPages, "Japanese");
  createWantedPagesPage("nl", dutchWantedPages, "Dutch");
  createWantedPagesPage("pl", polishWantedPages, "Polish");
  createWantedPagesPage("pt-br", portugueseWantedPages, "Portuguese");
  createWantedPagesPage("ru", russianWantedPages, "Russian");
  createWantedPagesPage("sv", swedishWantedPages, "Swedish");
  createWantedPagesPage("uk", ukrainianWantedPages, "Ukrainian");
  createWantedPagesPage("zh", chineseWantedPages, "Chinese");
  createWantedPagesPage("tr", turkishWantedPages, "Turkish");
  createWantedPagesPage("kr", koreanWantedPages, "Korean");
 
  createWantedPagesPage("file", wantedFiles, "Files");
  createWantedPagesPage("file_talk", wantedFileTalk, "File talk");
  createWantedPagesPage("template", wantedTemplates, "Templates");
  createWantedPagesPage("other", otherWantedPages, "Other");
}
}


function createWantedPagesPage(location, wantedPages, language) {
function getBacklinks(page) {
  var languageSuffixes = ["cs", "de", "es", "fr", "it", "ja", "nl", "pl", "pt-br", "ru", "sv", "uk", "zh", "tr", "kr"]
var backlinks = [];
  if (languageSuffixes.indexOf(location) > -1) {
$.ajax({
    var formattedWantedPages = "Number of wanted pages in " + language + ": " + wantedPages.length + "\n{|class=wikitable\n!#\n!Page\n!Links to this page\n!Length of the corresponding English page in bytes";
url: apiUrl,
    for (var i = 0; i < wantedPages.length; i++) {
data: {
      //I don't dare to make this into a function because I don't want this to be async so lets put a whole api request in here lul
format: 'json',
      var enPageTitle = wantedPages[i].title.slice(0, - location.length - 1)
action: 'query',
      var length = 0;
list: 'backlinks',
      if (enPageLength[enPageTitle]) {
bltitle: page,
        length = enPageLength[enPageTitle]
bllimit: 1000,
      } else {
},
        $.ajax({
async: false,
          url: 'https://wiki.factorio.com/api.php',
type: 'GET',
          data: {
success: function( data ) {
              format: 'json',
backlinks = data.query.backlinks;
              action: 'query',
},
              titles: enPageTitle,
error: function( xhr ) {
              prop: 'info',
alert( 'Error: Backlinks request failed.' );
          },
}
          async: false,
});
          dataType: 'json',
return backlinks;
          type: 'POST',
};
          success: function( data ) {
            var pages = data.query.pages;
            var pageInfo = pages[Object.keys(pages)[0]];
            length = pageInfo['length'];
            if (!length) length = '---';
            var redirect = pageInfo['redirect'];
            if (redirect == "") {
              length = length + " (Redirect)";
            } else if (disambigs[enPageTitle]) {
              length = length + " (Disambiguation)";
            }
            if (stubs[enPageTitle]) {
              length = length + " (Stub)";
            }
            enPageLength[enPageTitle] = length
          },
          error: function( xhr ) {
            alert("Failed to get page length: " + pageTitle);
          }
        });
      }
      formattedWantedPages = formattedWantedPages.concat("\n|-\n|" + (i + 1) + "\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].title + "]\n|[https://wiki.factorio.com/index.php?title=Special:WhatLinksHere/" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].value + "]\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(enPageTitle) + " " + length + "]");
    }
  } else {
    var formattedWantedPages = "Number of wanted pages in " + language + ": " + wantedPages.length + "\n{|class=wikitable\n!#\n!Page\n!Links to this page";
    for (var i = 0; i < wantedPages.length; i++) {   
      formattedWantedPages = formattedWantedPages.concat("\n|-\n|" + (i + 1) + "\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].title + "]\n|[https://wiki.factorio.com/index.php?title=Special:WhatLinksHere/" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].value + "]");
    }
  }
  formattedWantedPages = formattedWantedPages.concat("\n|}");


  createPage(wantedPagesListsLocation + "/" + location, formattedWantedPages, "Updated the list of wanted pages for " + language + ".");
function getFileUsage(file) {
}
var imageusage = [];
$.ajax({
url: apiUrl,
data: {
format: 'json',
action: 'query',
list: 'imageusage',
iutitle: file,
iulimit: 1000
},
async: false,
type: 'GET',
success: function( data ) {
imageusage = data.query.imageusage;
},
error: function( xhr ) {
alert( 'Error: Imageusage request failed.' );
}
});
return imageusage;
};


function performNullEdit(pageTitle, summary) {
function performNullEdit(pageTitle, summary) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: 'json',
             format: 'json',
Line 379: Line 381:
function purgeWhatLinksHere(pageTitle) {
function purgeWhatLinksHere(pageTitle) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: "json",
             format: "json",
Line 404: Line 406:
function purgePage(pageTitle) {
function purgePage(pageTitle) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             action: 'purge',
             action: 'purge',
Line 422: Line 424:
     });
     });
}
}
function compare(a,b) {
  if (parseInt(a.value) > parseInt(b.value))
    return -1;
  if (parseInt(a.value) < parseInt(b.value))
    return 1;
  if (a.title < b.title)
    return -1;
  if (a.title > b.title)
    return 1;
  return 0;
}
function createPage(pageTitle, content, summary) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            token: globalToken,
            summary: summary,
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
          console.log("created page: " + pageTitle);
        },
        error: function( xhr ) {
            console.log("failed to create page");
        }
    });
}
function getWantedPages() {
  var wantedPages = [];
  $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'querypage',
            qppage: 'Wantedpages',
            qplimit: '5000',
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var results = data.query.querypage.results;
            for (var i = 0; i < results.length; i++) {
              var pageObject = new WantedPage(results[i].title, results[i].value);
              var alreadyInArray = false;
              for (var j = 0; j < wantedPages.length; j++) {
                if (wantedPages[j].title == pageObject.title) {
                    alreadyInArray = true;
                }
              }
              if (!alreadyInArray) {
                wantedPages.push(pageObject);
              }
              if (pageObject.title == "Rocket defense/it") {
              }
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
  });
$.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'querypage',
            qppage: 'Wantedpages',
            qplimit: '5000',
            qpoffset: '3000',
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var results = data.query.querypage.results;
            for (var i = 0; i < results.length; i++) {
              var pageObject = new WantedPage(results[i].title, results[i].value);
              var alreadyInArray = false;
              for (var j = 0; j < wantedPages.length; j++) {
                if (wantedPages[j].title == pageObject.title) {
                    alreadyInArray = true;
                }
              }
              if (!alreadyInArray) {
                wantedPages.push(pageObject);
              }
              if (pageObject.title == "Rocket defense/it") {
              }
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
  });
  return wantedPages;
};
function WantedPage(pageTitle, pageValue) {
  this.title = pageTitle;
  this.value = pageValue;
}
$("#create-redirect-list").click(function(){
  getToken();
  createRedirectList();
});
function createRedirectList() {
    getUserGroup();
    if (userGroup.some(isBot) == false) return;
    getRedirects();
};
function getRedirects() {
  var redirects = [];
  $.ajax({
    url: 'https://wiki.factorio.com/api.php',
    data: {
      format: 'json',
      action: 'query',
      list: 'allpages',
      aplimit: '5000',
      apfilterredir: 'redirects',
    },
    async: false,
    dataType: 'json',
    type: 'GET',
    success: function( data ) {
      redirects = data.query.allpages;
    },
    error: function( xhr ) {
      alert( 'Error: Allpages request failed.' );
    }
  });
 
  $.ajax({
    url: 'https://wiki.factorio.com/api.php',
    data: {
      format: 'json',
      action: 'query',
      list: 'allpages',
      aplimit: '5000',
      apfilterredir: 'redirects',
      apnamespace: '6'
    },
    async: false,
    dataType: 'json',
    type: 'GET',
    success: function( data ) {
      for (var i = 0; i < data.query.allpages.length; i++) {
        redirects.push(data.query.allpages[i])
      }
    },
    error: function( xhr ) {
      alert( 'Error: Allpages request failed.' );
    }
  });
 
  for (var i = 0; i < redirects.length; i++) {
    $.ajax({
      url: 'https://wiki.factorio.com/api.php',
      data: {
          format: "json",
          action: 'query',
          list: "backlinks",
          bltitle: redirects[i].title,
          bllimit: 500
      },
      async: false,
      type: 'GET',
      success: function( data ) {
        redirects[i].value = data.query.backlinks.length;
      },
      error: function( xhr ) {
        alert( 'Error: Backlinks request failed.' );
      }
    });
 
  }
  redirects = redirects.sort(compare);
  createRedirectsPage("Factorio:Redirects", redirects);
};
function createRedirectsPage(location, redirects) {
  var formattedRedirects = "{|class=wikitable\n!#\n!Redirect\n!Links to this redirect";
  for (var i = 0; i < redirects.length; i++) {   
    formattedRedirects = formattedRedirects.concat("\n|-\n|" + (i + 1) + "\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(redirects[i].title) + "&redirect=no " + redirects[i].title + "]\n|[https://wiki.factorio.com/index.php?title=Special:WhatLinksHere/" + encodeURI(redirects[i].title) + " " + redirects[i].value + "]");
  }
  formattedRedirects = formattedRedirects.concat("\n|}");
  createPage(location, formattedRedirects, "Updated the list of redirects.");
}
/* OLD INFOBOX CONVERSION TOOLS */
/*function targetAllPagesInCategory(category) {
    var languageSuffixes = ["/fr", "/ru", "/de"]; //, "/cs", "/de", "/es", "/fr", "/it", "/nl", "/pl", "/pt-br", "/ru", "/sv", "/uk", "/zh", ""];
    for (var j = 0; j < languageSuffixes.length; j++) {
      $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'categorymembers',
            cmtitle: (category + languageSuffixes[j]),
            cmlimit: 500
        },
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var pages = data.query.categorymembers;
            for (var i = 0; i < pages.length; i++) {
                    //purgePage(pages[i].title);
                    extractPageInfo(pages[i].title, "9c28a1344a20bf189fda7d58339e518257f2dd9b+\\");
               
            }
            if ( data && data.query && data.query.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info + 'Category' );
            } else {
                //alert( 'Error: Unknown result from API. Category' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
    });
  }
}
function extractPageInfo(pageTitle, token) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            titles: pageTitle,
            prop: 'revisions',
            rvprop: 'content'
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var pages = data.query.pages;
            var revisions = pages[Object.keys(pages)[0]].revisions[0];
            var content = revisions[Object.keys(revisions)[2]]
            var title = pages[Object.keys(pages)[0]].title;
            createNewInfoboxPage(title, content, token);
            if ( data && data.query && data.query.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    });
}
function createNewInfoboxPage(page, contentOfMainPage, token) {
    var infoboxText = getInfoboxFromFullPageContent(contentOfMainPage);
    var infoboxPageTitle = page.replace(/\/(de|fr|nl|it|es|ru|pt\-br|cs|pl|sv|uk|zh)/g, function(piece) {return "";}).concat("/infobox");
    var oldPageRevisedText = getOldPageRevisedText(page, contentOfMainPage, infoboxPageTitle);
    removeInfoboxFromMain(page, oldPageRevisedText, token);
    if (infoboxText != null) {
      if (/\/(de|fr|nl|it|es|ru|pt\-br|cs|pl|sv|uk|zh)/g.test(page)) {
        return;
      }
      var newPageTitle = page.concat("/infobox");
      var convertedInfoboxText = convertInfobox(infoboxText, token);
      createPage(newPageTitle, convertedInfoboxText, token, page, contentOfMainPage);
    }
}
function getOldPageRevisedText(pageTitle, content, infoboxPageTitle) {
    content = content.replace(/{{\bCombat\b(\s+(\||{).+)+\s}}/gi, function (piece) {
        return "{{:" + infoboxPageTitle + "}}";
    });
    return content;
}
function removeInfoboxFromMain(pageTitle, content, token) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            bot: true,
            token: token,
            summary: "(BOT) - Replaced old infobox with a link to the /infobox subpage"
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    })
};
function getInfoboxFromFullPageContent(contentOfPage) {
    var matches = contentOfPage.match(/{{\bCombat\b(\s+\|.+)+\s}}/gi);
if (matches != null && matches.length > 0) {
infoboxText = matches[0];
} else {
infoboxText = null;
}
    return infoboxText;
}
function convertInfobox(text) {
    text = text.replace(/{{(\w+)/g, function (piece, $1) {
        var returnText = "{{Infobox\n| category = ";
        $1 = $1.toLowerCase();
        switch ($1) {
            case "item":
                returnText = returnText.concat("Items");
                break;
            case "machinery":
                returnText = returnText.concat("Machinery");
                break;
            case "combat":
                returnText = returnText.concat("Combat");
                break;
            case "technology":
                returnText = returnText.concat("Technology");
        }
        switch ($1) {
            case "machinery":
                returnText = returnText.concat("\n| category-name = Machine");
                break;
            case "item":
                returnText = returnText.concat("\n| category-name = Item");
                break;
        }
        return returnText;
    });
    text = text.replace("stack_size", "stack-size");
    text = text.replace("poweroutput", "power-output");
    text = text.replace("input", "recipe");
    text = text.replace("raw", "total-raw");
    text = text.replace("technologies", "required-technologies");
    text = text.replace("costmultiplier", "cost-multiplier");
    text = text.replace("requirements", "required-technologies");
    text = text.replace("walkingspeed", "walking-speed");
    text = text.replace("storagesize", "storage-size");
    text = text.replace("gridsize", "grid-size");
    text = text.replace("shootingspeed", "shooting-speed");
    text = text.replace("damagebonus", "damage-bonus");
    text = text.replace("clustersize", "cluster-size");
    text = text.replace("aoesize", "area-of-effect-size");
    text = text.replace("magazinesize", "magazine-size");
    text = text.replace("recharge", "robot-recharge-rate");
    text = text.replace("rechargebuffer", "internal-buffer-recharge-rate");
    text = text.replace("wirereach", "wire-reach");
    text = text.replace("craftingspeed", "crafting-speed");
    text = text.replace("smeltingspeed", "smelting-speed");
    text = text.replace("miningpower", "mining-power");
    text = text.replace("miningspeed", "mining-speed");
    text = text.replace("miningarea", "mining-area");
    text = text.replace("supplyarea", "supply-area");
    text = text.replace("constructionarea", "construction-area");
    text = text.replace("lifetime", "lifespan");
    text = text.replace("inventorysizebonus", "inventory-size-bonus");
    text = text.replace("gridsize", "grid-size");
    text = text.replace("boosttechs", "boosting-technologies");
    text = text.replace("allowstech", "allows");
    text = text.replace("storage", "storage-size");
    text = text.replace(/\|\s*\brecipe\b\s*=\s*(.+)\n\|\s*\boutput\b\s*=\s*(.+)/g, function (piece, $1, $2) {
        return "| recipe = " + $1 + " = " + $2;
    });
    text = text.concat("<noinclude>[[Category:Infobox page]]</noinclude>");
    return text;
}
function createPage(pageTitle, content, token, page, contentOfMainPage) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            bot: true,
            createonly: true,
            token: token,
            summary: "(BOT) - Created infobox sub page for " + page
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
         
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    });
}*/
/* END OF OLD INFOBOX CONVERSION TOOL */

Latest revision as of 12:24, 20 February 2020

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

var apiUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + "/api.php"

/* Script in here will be executed when the page is "ready" */
$(document).ready(getNumberOfActiveUsers);

/* show correct number of active users on the main page */

function getNumberOfActiveUsers() {
	if (document.getElementById("active-users")) {
		$.ajax({
			url: apiUrl,
			data: {
				format: 'json',
				action: 'query',
				list: 'allusers',
				aulimit: 500,
				auactiveusers: true
			},
			dataType: 'json',
			type: 'GET',
			success: function(data) {
				document.getElementById("active-users").innerHTML = data.query.allusers.length.toString();
			},
			error: function(xhr) {
				console.log( 'Error: Request failed.' );
			}
		});
	}
};

/* Collapsible list on [[Prototype definitions]] */

$(".prototype-tree li").each(function (index, element) {
  if ( $( element ).children("ul").length > 0 ) {
    $( element ).addClass("prototype-tree-parent");
  };
});

$(".prototype-tree li.prototype-tree-parent").on("click", function(event) {
 // only collapse if I clicked a li or the direct child of a li that is not another list or a link
  if ( $( event.currentTarget ).children("ul").length > 0 && $( event.target ).get(0).tagName != "UL" && $( event.target ).get(0).tagName != "A" && ($( event.target ).hasClass("prototype-tree-parent") || $( event.target ).parent().hasClass("prototype-tree-parent")) ) {
    $( event.currentTarget ).children("ul")[0].classList.toggle("hidden");
    $( event.currentTarget ).toggleClass("prototype-tree-parent-collapsed");
    return false; // prevents further event bubbling
  }
});

/* Evolution calc */

//values are in the form [evolution, weight]
const biterSpawner = [
	["Small Biter",    [[0.0, 0.3], [0.6, 0.0]]],
	["Medium Biter",   [[0.2, 0.0], [0.6, 0.3], [0.7, 0.1]]],
	["Big Biter",      [[0.5, 0.0], [1.0, 0.4]]],
	["Behemoth Biter", [[0.9, 0.0], [1.0, 0.3]]]
];
const spitterSpawner = [
	["Small Biter",      [[0.0, 0.3], [0.35, 0.0]]],
	["Small Spitter",    [[0.25, 0.0], [0.5, 0.3], [0.7, 0.0]]],
	["Medium Spitter",   [[0.4, 0.0], [0.7, 0.3], [0.9, 0.1]]],
	["Big Spitter",      [[0.5, 0.0], [1.0, 0.4]]],
	["Behemoth Spitter", [[0.9, 0.0], [1.0, 0.3]]]
];

//calculates the interpolated value
function lerp(low, high, pos) {
	const s = high[0] - low[0];
	const l = (pos - low[0]) / s;
	return (low[1] * (1-l)) + (high[1] * l);
};

//gets the weight list
function getValues(map, evo) {
	var result = {};
	var sum = 0;
	map.forEach(function(data) {
		const list = data[1];
		var low = list[0];
		var high = list[list.length-1];
		list.forEach(function(val) {
			if(val[0] <= evo && val[0] >  low[0])  low = val;
			if(val[0] >= evo && val[0] < high[0]) high = val;
		});
		var val = null;
		if(evo <= low[0]) val = low[1];
		else if(evo >= high[0]) val = high[1];
		else val = lerp(low, high, evo);
		sum += val;
		result[data[0]] = val;
	});
	Object.keys(result).forEach(function(data, index) {
		result[data] = result[data] / sum;
	});
	return result;
};

function calcEvo() {
	const evo = document.getElementById("evoInput").value;
	genTable(getValues(biterSpawner, evo), document.getElementById("evoOutputBiter"), "Biter's Nest");
	genTable(getValues(spitterSpawner, evo), document.getElementById("evoOutputSpitter"), "Spitter's Nest");
};

function percentile(value) {
	return (value*100).toFixed(2) + "%";
};

function genTable(data, tableElem, title) {
	var html = '<tr><th>'+title+'</th><th>Chance</th>';
	Object.keys(data).forEach(function(value) {
		html += '<tr><td>'+value+'</td><td>'+percentile(data[value])+'</td>';
	});
	tableElem.innerHTML = html;
};

window.onload = function() {
	var elem = document.getElementById("evoChecker");
	if(elem != null) {
		elem.innerHTML =
		'Alternatively, enter an evolution factor below to see the chances.<br>' +
		'<input style="margin-bottom:10px" type="number" id="evoInput" min=0 max=1 step=0.01 placeholder="Evolution" onchange="calcEvo()"></input><br>' +
		'<table style="float:left;margin-right:10px" class="wikitable" id="evoOutputBiter"></table>' +
		'<table class="wikitable" id="evoOutputSpitter"></table>';
		calcEvo();
	}
};

/* Template:Inventory tooltips */

var lastTouchTime = 0;
document.addEventListener('touchstart', updateLastTouchTime, true);
function updateLastTouchTime() {
  lastTouchTime = new Date();
}

$(".tab-head").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  var newRule = '.tab-head:hover:after{display: block; left: ' + (e.offsetX + 20) + 'px; top: ' + (e.offsetY + 20) + 'px;}';
  document.styleSheets[0].insertRule(newRule, countCssRules);
});

$(".tab .factorio-icon").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  $(e.currentTarget).children("a").attr("title", "");
  var text = $(e.currentTarget).children("a").children("img").attr("alt");
  var newRule = '.tab .factorio-icon:hover:after{display: block; ' + "content: '" + text + "'}";
  document.styleSheets[0].insertRule(newRule, countCssRules);
});

/* Template:BlueprintString */

$(".bps-box").click(function(event) {
	var copyTarget = document.createElement("input");
	copyTarget.setAttribute("value", $( event.target ).children("p").html());
	document.body.appendChild(copyTarget);
	copyTarget.select();
	document.execCommand("copy");
	document.body.removeChild(copyTarget);
});

/* Template:Inventory */

$(".tab-head-1").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-1").show();
});

$(".tab-head-2").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-2").show();
});

$(".tab-head-3").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-3").show();
});

$(".tab-head-4").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-4").show();
});

//*** Language template ***//
if($(".languages-flags .flag").length == 0) {
	console.log("Not showing languages bar because there's no other language's version of this page.");
	$(".languages-container").hide();
}

//Spoiler template
$(".spoiler-container .button").click(function() {
	$(this).siblings(".text").toggle("slow");
});

//* General/generic functions *//

/* User is bot if userGroup.some(isBot) == true */

var userGroup = "";

function getUserGroup() {
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			meta: 'userinfo',
			uiprop: 'groups',
		},
		async: false,
		dataType: 'json',
		type: 'GET',
		success: function(data) {
			userGroup = data.query.userinfo.groups
		},
	});
};

function isBot(group) {
	return group == "bot";
}

/* Get token of this session */

var globalToken;

function getToken() {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'query',
            meta: 'tokens',
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
           globalToken = data.query.tokens.csrftoken;
        },
        error: function( xhr ) {
            console.log("Failed to get token.");
        }
    });
}


function genericEditPage(title, content, summary) {
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'edit',
			title: title,
			text: content,
			token: globalToken,
			summary: summary,
			bot: true,
			nocreate: true
		},
		dataType: 'json',
		type: 'POST',
		success: function( data ) {
			console.log("Edited " + title);
		},
		error: function( xhr ) {
			alert("Failed to edit " + title);
		}
	});
};


function createPage(pageTitle, content, summary) {
    $.ajax({
        url: apiUrl,
        data: {
			format: 'json',
			action: 'edit',
			title: pageTitle,
			text: content,
			token: globalToken,
			summary: summary,
			bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
			console.log("Created page: " + pageTitle);
        },
        error: function( xhr ) {
			console.log("Failed to create page");
        }
    });
}

function getBacklinks(page) {
	var backlinks = [];
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			list: 'backlinks',
			bltitle: page,
			bllimit: 1000,
		},
		async: false,
		type: 'GET',
		success: function( data ) {
			backlinks = data.query.backlinks;
		},
		error: function( xhr ) {
			alert( 'Error: Backlinks request failed.' );
		}
	});
	return backlinks;
};

function getFileUsage(file) {
	var imageusage = [];
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			list: 'imageusage',
			iutitle: file,
			iulimit: 1000
		},
		async: false,
		type: 'GET',
		success: function( data ) {
			imageusage = data.query.imageusage;
		},
		error: function( xhr ) {
			alert( 'Error: Imageusage request failed.' );
		}
	});
	return imageusage;
};

function performNullEdit(pageTitle, summary) {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            section: 0,
            text: "",
            token: globalToken,
            summary: summary,
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
           console.log("Performed null edit");
        },
        error: function( xhr ) {
            console.log("Failed to perform null edit");
        }
    });
}

function purgeWhatLinksHere(pageTitle) {
    $.ajax({
        url: apiUrl,
        data: {
            format: "json",
            action: 'query',
            list: "backlinks",
            bltitle: pageTitle,
            bllimit: 500
        },
        async: true,
        type: 'GET',
        success: function( data ) {
            console.log(data);
            for (var i = 0; i < data.query.backlinks.length; i++) {
                purgePage(data.query.backlinks[i].title);
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
            console.log("Failed purging");
        }
    });
}

function purgePage(pageTitle) {
    $.ajax({
        url: apiUrl,
        data: {
            action: 'purge',
            forcelinkupdate: true,
            titles: pageTitle,
            prop: "info"
        },
        async: true,
        type: 'GET',
        success: function( data ) {
            console.log("purging " + pageTitle);
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
            console.log("Failed purging");
        }
    });
}