Index: lib/compat.js |
=================================================================== |
--- a/lib/compat.js |
+++ b/lib/compat.js |
@@ -12,17 +12,16 @@ |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
// TODO: These need to be defined properly |
var window = this; |
-function XMLHttpRequest() {}; |
// |
// Module framework stuff |
// |
function require(module) |
{ |
return require.scopes[module]; |
@@ -272,23 +271,138 @@ FakeTimer.prototype = |
Cu.reportError(e); |
} |
me.scheduleTimeout(); |
}, this.delay); |
} |
}; |
// |
-// Add a channel property to XMLHttpRequest, Synchronizer needs it |
+// Fake XMLHttpRequest implementation |
// |
-XMLHttpRequest.prototype.channel = |
+function XMLHttpRequest() |
{ |
- status: -1, |
- notificationCallbacks: {}, |
- loadFlags: 0, |
- INHIBIT_CACHING: 0, |
- VALIDATE_ALWAYS: 0, |
- QueryInterface: function() |
+ this._requestHeaders = {}; |
+ this._loadHandlers = []; |
+ this._errorHandlers = []; |
+}; |
+XMLHttpRequest.prototype = |
+{ |
+ _url: null, |
+ _requestHeaders: null, |
+ _responseHeaders: null, |
+ _loadHandlers: null, |
+ _errorHandlers: null, |
+ onload: null, |
+ onerror: null, |
+ status: 0, |
+ readyState: 0, |
+ responseText: null, |
+ |
+ addEventListener: function(eventName, handler, capture) |
{ |
- return this; |
+ var list; |
+ if (eventName == "load") |
+ list = this._loadHandlers; |
+ else if (eventName == "error") |
+ list = this._errorHandlers; |
+ else |
+ throw new Error("Event type " + eventName + " not supported"); |
+ |
+ if (list.indexOf(handler) < 0) |
+ list.push(handler); |
+ }, |
+ |
+ removeEventListener: function(eventName, handler, capture) |
+ { |
+ var list; |
+ if (eventName == "load") |
+ list = this._loadHandlers; |
+ else if (eventName == "error") |
+ list = this._errorHandlers; |
+ else |
+ throw new Error("Event type " + eventName + " not supported"); |
+ |
+ var index = list.indexOf(handler); |
+ if (index >= 0) |
+ list.splice(index, 1); |
+ }, |
+ |
+ open: function(method, url, async, user, password) |
+ { |
+ if (method != "GET") |
+ throw new Error("Only GET requests are currently supported"); |
+ if (typeof async != "undefined" && !async) |
+ throw new Error("Sync requests are not supported"); |
+ if (typeof user != "undefined" || typeof password != "undefined") |
+ throw new Error("User authentification is not supported"); |
+ if (this.readyState != 0) |
+ throw new Error("Already opened"); |
+ |
+ this.readyState = 1; |
+ this._url = url; |
+ }, |
+ |
+ send: function(data) |
+ { |
+ if (this.readyState != 1) |
+ throw new Error("XMLHttpRequest.send() is being called before XMLHttpRequest.open()"); |
+ if (typeof data != "undefined" && data) |
+ throw new Error("Sending data to server is not supported"); |
+ |
+ this.readyState = 3; |
+ window._webRequest.GET(this._url, this._requestHeaders, function(result) |
+ { |
+ this.channel.status = result.status; |
+ this.status = result.responseStatus; |
+ this.responseText = result.responseText; |
+ this._responseHeaders = result.responseHeaders; |
+ this.readyState = 4; |
+ |
+ // Notify event listeners |
+ const NS_OK = 0; |
+ var eventName = (this.channel.status == NS_OK ? "load" : "error"); |
+ var event = {type: eventName}; |
+ |
+ if (this["on" + eventName]) |
+ this.onload.call(this, event); |
+ |
+ var list = this["_" + eventName + "Handlers"]; |
+ for (var i = 0; i < list.length; i++) |
+ list[i].call(this, event); |
+ }.bind(this)); |
+ }, |
+ |
+ overrideMimeType: function(mime) |
+ { |
+ }, |
+ |
+ setRequestHeader: function(name, value) |
+ { |
+ if (this.readyState > 1) |
+ throw new Error("Cannot set request header after sending"); |
+ |
+ this._requestHeaders[name] = value; |
+ }, |
+ |
+ getResponseHeader: function(name) |
+ { |
+ name = name.toLowerCase(); |
+ if (!this._responseHeaders || !this._responseHeaders.hasOwnProperty(name)) |
+ return null; |
+ else |
+ return this._responseHeaders[name]; |
+ }, |
+ |
+ channel: |
+ { |
+ status: -1, |
+ notificationCallbacks: {}, |
+ loadFlags: 0, |
+ INHIBIT_CACHING: 0, |
+ VALIDATE_ALWAYS: 0, |
+ QueryInterface: function() |
+ { |
+ return this; |
+ } |
} |
}; |