The userscript in question: http://userscripts.org/scripts/show/130532
After the site it’s been made for has been updated to HTML5, I had to update the script. However, it’s got a really big problem now. When I launch the script’s main function that contains the XMLHttpRequest, it simply spams the console with these requests until the browser simply crashes.
Now, I looked around in both StackOverflow and in Google for anything that could help me, but there’s nothing.
If you proceed to try the script, be careful, because it crashes the browser. Or at least, it does for me in FF 11.00
Code:
// ==UserScript==
// @name Where my thread at
// @include *//boards.4chan.org/*/res/*
// ==/UserScript==
(function () {
"use strict";
var board = document.location.href.match(/https?:\/\/boards\.4chan\.org\/[\w]+/i), threadNo = location.pathname.match(/\/res\/([\d]+)/i), main = document.getElementsByName("delform")[0], is404 = 0, ttt = null, b, c, num, timer, html, i, l, no, found, xhr1, xhr2, cstatus, ui, pg;
function lookup(resp) {
html = resp.match(/<div class="postContainer opContainer".*?<\/div>[^<]*?<\/div>/gi);
if (html) {
l = html.length;
for (i = 0; i < l; i += i) {
no = html[i].match(/<a href="res\/([\d]+)"/i)[1];
if (threadNo[1] === no) {
document.getElementById('page').innerHTML = pg;
cstatus.innerHTML = "Status: Done";
found = 1;
break;
}
}
}
}
function doIndex(pg) {
b = document.getElementById('shouldi');
if (!is404 && b.checked === true) {
cstatus.innerHTML = "Status: Searching";
c = document.getElementById('timerbox');
num = parseInt(c.value, 10);
if (num > 600) { timer = 600; }
if (num < 30) { timer = 30; }
if (isNaN(num)) {
timer = 60;
alert("Value entered is not a valid number! Defaulting to 60");
c.value = "60";
}
if (!timer) { timer = num; }
xhr1 = new XMLHttpRequest();
xhr1.open("GET", board[0] + (0 === pg ? "" : "/" + pg), true);
xhr1.setRequestHeader("Cache-Control", "no-cache");
xhr1.onreadystatechange = function () {
if (xhr1.readyState === 4) {
if (xhr1.status === 200) {
lookup(xhr1.responseText);
}
}
if (found) {
ttt = setTimeout(function () {
doIndex(0);
}, timer * 1000);
} else {
if (pg < 15) {
doIndex(pg + 1);
} else {
cstatus.innerHTML = "Status: Really 404?";
xhr2 = new XMLHttpRequest();
xhr2.open("GET", board[0] + threadNo[0], true);
xhr2.setRequestHeader("Cache-Control", "no-cache");
xhr2.onreadystatechange = function () {
if (xhr2.readyState === 4) {
if (xhr2.status === 404) {
cstatus.parentNode.removeChild(cstatus);
document.getElementById('page').innerHTML = "404'd";
is404 = 1;
} else {
cstatus.innerHTML = "Status: Still alive";
setTimeout(function () {
doIndex(0);
}, 1000);
}
}
};
xhr2.send(null);
}
}
};
xhr1.send(null);
}
}
ui = document.createElement('center');
ui.innerHTML = '<table border="0" style="width: 100%"><tbody><tr><td style="width: 33%;text-align: right;">Timer(600-30s): <input type="text" value="30" maxlength="3" size="3" id="timerbox"> </td><td style="width: 33%"> <center><font size="20" color="red" id="page"> </font></center> </td><td style="width: 33%;text-align:left;"> <span id="checkcheck"><label for="shouldi">Checking</label><input type="checkbox" id="shouldi" /></span> <span id="checkstatus">Status: </span></td></tr></tbody></table>';
main.parentNode.insertBefore(ui, main);
cstatus = document.getElementById('checkstatus');
cstatus.innerHTML = "Status: Ready";
document.getElementById('checkcheck').addEventListener("click", function () {
if (ttt !== null) {
clearTimeout(ttt);
ttt = null;
}
setTimeout(function () {
doIndex(0);
}, 500);
}, false);
}());
You’re using several variables without declaring these locally:
First, you assign a new XHR instance to a non-local
xhr1variable.Then, you add a
readystatechangeevent handler, in which the following happens:readyStateis not four, sofoundis false. Sincepgstarts at 0,doIndex(pg + 1)is called. Now,xhr1gets overwritten by a new XHR instance.pgreaches 15. Then,pg < 15is false, and the horror starts:xhr1.onreadystatechangefires multiple time during the request.pg < 15is false, so theelseblock is evaluated, in which you launch several new XHR (xhr2) requests…xhr1.readyState, which refers to the state of the last createdxhr1request.So, you’re calling
doIndex(pg+1)over and over again, which, oncepghas reached 15, creates new XHR (xhr2) instances.To fix the problem, declare the variables in the function, and wrap the whole
onreadystatechangeblock inif (xhr1.readyState == 4)(or useonloadinstead ofonreadystatechange).