This is a javascript code that will be injected into every page a .NET WebBrowser component navigates to. This means the code needs to be compatible with IE 7+ only. The code will be injected and run when the OnNavigateComplete
event happens, which means it will run before any other script in the page runs.
ajaxHandler
is an object defined in another section with only two methods: OnAjaxStart
and OnAjaxEnd
.
The requirements are that ajaxHandler.OnAjaxStart
should be called before one or more ajax requests start and ajaxHandler.OnAjaxEnd
must be called after these ajax calls end. Also, there must be a call to ajaxHandler.OnAjaxEnd
for every call to ajaxHandler.OnAjaxStart
so the application doesn't wait for the ajax call to end forever (unless the page itself waits forever; this could safely be considered as a page that doesn't complete loading). Finally, the code shouldn't mess with the webpage's functionality.
This is all part of a web scrapping application and the goal is to have the web scraper wait until AJAX completes before it starts getting data from the page (any page).
(function () {
if (!(window.____hsXMLHttpRequestHooked === true)) {
window.____hsXMLHttpRequestHooked = true;
function arrayRemove(array, from, to) {
var rest = array.slice((to || from) + 1 || array.length);
array.length = from < 0 ? array.length + from : from;
return array.push.apply(array, rest);
}
function addRequest(request) {
if (requests.length == 0) ajaxHandler.OnAjaxStart(window);
for (var i = 0; i < requests.length; i++) {
if (requests[i] == request) return;
}
requests.push(request);
}
function removeRequest(request) {
for (var i = 0; i < requests.length; i++) {
if (requests[i] == request) {
arrayRemove(requests, i);
break;
}
}
if (requests.length == 0) ajaxHandler.OnAjaxEnd(window);
}
var oldSend = XMLHttpRequest.prototype.send;
var requests = [];
XMLHttpRequest.prototype.send = function () {
var originalCallback = this.onreadystatechange;
this.onreadystatechange = function () {
if (originalCallback) originalCallback.apply(this, [].slice.call(arguments));
if (this.readyState == 4) removeRequest(this);
}
addRequest(this);
oldSend.apply(this, [].slice.call(arguments));
}
}
})();