Index: lib/compat.js |
=================================================================== |
--- a/lib/compat.js |
+++ b/lib/compat.js |
@@ -10,211 +10,212 @@ |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* 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/>. |
*/ |
-var window = this; |
+"use strict"; |
+ |
+let window = this; |
// |
// Module framework stuff |
// |
function require(module) |
{ |
return require.scopes[module]; |
} |
require.scopes = {__proto__: null}; |
-function importAll(module, globalObj) |
-{ |
- var exports = require(module); |
- for (var key in exports) |
- globalObj[key] = exports[key]; |
-} |
- |
const onShutdown = { |
done: false, |
- add: function() {}, |
- remove: function() {} |
+ add() {}, |
+ remove() {} |
}; |
// |
// XPCOM emulation |
// |
-const Components = |
+// nsIHttpChannel is checked against instanceof. |
+class nsIHttpChannel |
{ |
- interfaces: |
+} |
+ |
+const Components = |
{ |
- nsIHttpChannel: function() {}, |
- nsITimer: {TYPE_REPEATING_SLACK: 0}, |
- }, |
- classes: |
- { |
- "@mozilla.org/timer;1": |
+ interfaces: |
+ { |
+ nsIHttpChannel, |
+ nsITimer: {TYPE_REPEATING_SLACK: 0} |
+ }, |
+ classes: |
{ |
- createInstance: function() |
+ "@mozilla.org/timer;1": |
{ |
- return new FakeTimer(); |
+ createInstance() |
+ { |
+ return new FakeTimer(); |
+ } |
} |
}, |
- }, |
- utils: { |
- reportError: function(e) |
- { |
- console.error(e); |
- console.trace(); |
- }, |
- import: function(resource) |
+ utils: |
{ |
- let match = /^resource:\/\/gre\/modules\/(.+)\.jsm$/.exec(resource); |
- let resourceName = match && match[1]; |
- if (resourceName && Cu.import.resources.has(resourceName)) |
- return {[resourceName]: Cu.import.resources.get(resourceName)}; |
- throw new Error("Attempt to import unknown JavaScript module " + resource); |
+ reportError(e) |
+ { |
+ console.error(e); |
+ console.trace(); |
+ }, |
+ import(resource) |
+ { |
+ let match = /^resource:\/\/gre\/modules\/(.+)\.jsm$/.exec(resource); |
+ let resourceName = match && match[1]; |
+ if (resourceName && Cu.import.resources.has(resourceName)) |
+ return {[resourceName]: Cu.import.resources.get(resourceName)}; |
+ throw new Error( |
+ "Attempt to import unknown JavaScript module " + resource); |
+ } |
} |
- }, |
-}; |
+ }; |
const Cc = Components.classes; |
const Ci = Components.interfaces; |
const Cu = Components.utils; |
Cu.import.resources = new Map(); |
Cu.import.resources.set("XPCOMUtils", |
-{ |
- generateQI: function() {} |
-}); |
+ { |
+ generateQI() {} |
+ }); |
// |
// Services.jsm module emulation |
// |
Cu.import.resources.set("Services", |
-{ |
- obs: { |
- addObserver: function() {}, |
- removeObserver: function() {} |
- }, |
- vc: { |
- compare: function(v1, v2) |
- { |
- function parsePart(s) |
+ { |
+ obs: { |
+ addObserver() {}, |
+ removeObserver() {} |
+ }, |
+ vc: { |
+ compare(v1, v2) |
{ |
- if (!s) |
- return parsePart("0"); |
+ function parsePart(s) |
+ { |
+ if (!s) |
+ return parsePart("0"); |
+ |
+ let part = { |
+ numA: 0, |
+ strB: "", |
+ numC: 0, |
+ extraD: "" |
+ }; |
- var part = { |
- numA: 0, |
- strB: "", |
- numC: 0, |
- extraD: "" |
- }; |
+ if (s === "*") |
+ { |
+ part.numA = Number.MAX_VALUE; |
+ return part; |
+ } |
- if (s === "*") |
- { |
- part.numA = Number.MAX_VALUE; |
+ let matches = s.match(/(\d*)(\D*)(\d*)(.*)/); |
+ part.numA = parseInt(matches[1], 10) || part.numA; |
+ part.strB = matches[2] || part.strB; |
+ part.numC = parseInt(matches[3], 10) || part.numC; |
+ part.extraD = matches[4] || part.extraD; |
+ |
+ if (part.strB == "+") |
+ { |
+ part.numA++; |
+ part.strB = "pre"; |
+ } |
+ |
return part; |
} |
- var matches = s.match(/(\d*)(\D*)(\d*)(.*)/); |
- part.numA = parseInt(matches[1], 10) || part.numA; |
- part.strB = matches[2] || part.strB; |
- part.numC = parseInt(matches[3], 10) || part.numC; |
- part.extraD = matches[4] || part.extraD; |
- |
- if (part.strB == "+") |
+ function comparePartElement(s1, s2) |
{ |
- part.numA++; |
- part.strB = "pre"; |
+ if (s1 === "" && s2 !== "") |
+ return 1; |
+ if (s1 !== "" && s2 === "") |
+ return -1; |
+ return s1 === s2 ? 0 : (s1 > s2 ? 1 : -1); |
} |
- return part; |
- } |
- |
- function comparePartElement(s1, s2) |
- { |
- if (s1 === "" && s2 !== "") |
- return 1; |
- if (s1 !== "" && s2 === "") |
- return -1; |
- return s1 === s2 ? 0 : (s1 > s2 ? 1 : -1); |
- } |
- |
- function compareParts(p1, p2) |
- { |
- var result = 0; |
- var elements = ["numA", "strB", "numC", "extraD"]; |
- elements.some(function(element) |
+ function compareParts(p1, p2) |
{ |
- result = comparePartElement(p1[element], p2[element]); |
+ let result = 0; |
+ let elements = ["numA", "strB", "numC", "extraD"]; |
+ elements.some(element => |
+ { |
+ result = comparePartElement(p1[element], p2[element]); |
+ return result; |
+ }); |
return result; |
- }); |
- return result; |
- } |
+ } |
- var parts1 = v1.split("."); |
- var parts2 = v2.split("."); |
- for (var i = 0; i < Math.max(parts1.length, parts2.length); i++) |
- { |
- var result = compareParts(parsePart(parts1[i]), parsePart(parts2[i])); |
- if (result) |
- return result; |
+ let parts1 = v1.split("."); |
+ let parts2 = v2.split("."); |
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) |
+ { |
+ let result = compareParts(parsePart(parts1[i]), parsePart(parts2[i])); |
+ if (result) |
+ return result; |
+ } |
+ return 0; |
} |
- return 0; |
} |
- } |
-}); |
+ }); |
function FakeTimer() |
{ |
} |
FakeTimer.prototype = |
{ |
delay: 0, |
callback: null, |
- initWithCallback: function(callback, delay) |
+ initWithCallback(callback, delay) |
{ |
this.callback = callback; |
this.delay = delay; |
this.scheduleTimeout(); |
}, |
- scheduleTimeout: function() |
+ scheduleTimeout() |
{ |
- var me = this; |
- setTimeout(function() |
+ setTimeout(() => |
{ |
try |
{ |
- me.callback(); |
+ this.callback(); |
} |
- catch(e) |
+ catch (e) |
{ |
Cu.reportError(e); |
} |
- me.scheduleTimeout(); |
+ this.scheduleTimeout(); |
}, this.delay); |
} |
}; |
// |
// Fake XMLHttpRequest implementation |
// |
function XMLHttpRequest() |
{ |
this._requestHeaders = {}; |
this._loadHandlers = []; |
this._errorHandlers = []; |
-}; |
+} |
XMLHttpRequest.prototype = |
{ |
_url: null, |
_requestHeaders: null, |
_responseHeaders: null, |
_loadHandlers: null, |
_errorHandlers: null, |
onload: null, |
@@ -239,205 +240,164 @@ |
"host": true, |
"keep-alive": true, |
"origin": true, |
"referer": true, |
"te": true, |
"trailer": true, |
"transfer-encoding": true, |
"upgrade": true, |
- "via": true, |
+ "via": true |
}, |
_forbiddenRequestHeadersRe: new RegExp("^(Proxy|Sec)-", "i"), |
- _isRequestHeaderAllowed: function(header) |
+ _isRequestHeaderAllowed(header) |
{ |
if (this._forbiddenRequestHeaders.hasOwnProperty(header.toLowerCase())) |
return false; |
if (header.match(this._forbiddenRequestHeadersRe)) |
return false; |
return true; |
}, |
- addEventListener: function(eventName, handler, capture) |
+ addEventListener(eventName, handler, capture) |
{ |
- var list; |
+ let 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) |
+ removeEventListener(eventName, handler, capture) |
{ |
- var list; |
+ let 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); |
+ let index = list.indexOf(handler); |
if (index >= 0) |
list.splice(index, 1); |
}, |
- open: function(method, url, async, user, password) |
+ open(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) |
+ send(data) |
{ |
if (this.readyState != 1) |
- throw new Error("XMLHttpRequest.send() is being called before XMLHttpRequest.open()"); |
+ 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; |
- var onGetDone = function(result) |
+ let onGetDone = 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}; |
+ let eventName = (this.channel.status == NS_OK ? "load" : "error"); |
+ let event = {type: eventName}; |
if (this["on" + eventName]) |
this["on" + eventName].call(this, event); |
- var list = this["_" + eventName + "Handlers"]; |
- for (var i = 0; i < list.length; i++) |
+ let list = this["_" + eventName + "Handlers"]; |
+ for (let i = 0; i < list.length; i++) |
list[i].call(this, event); |
- }.bind(this); |
- // HACK (#5066): the code checking whether the connection is allowed is temporary, |
- // the actual check should be in the core when we make a decision whether |
- // to update a subscription with current connection or not, thus whether to |
- // even construct XMLHttpRequest object or not. |
- _isSubscriptionDownloadAllowed(function(isAllowed) |
+ }; |
+ // HACK (#5066): the code checking whether the connection is |
+ // allowed is temporary, the actual check should be in the core |
+ // when we make a decision whether to update a subscription with |
+ // current connection or not, thus whether to even construct |
+ // XMLHttpRequest object or not. |
+ _isSubscriptionDownloadAllowed(isAllowed => |
{ |
if (!isAllowed) |
{ |
onGetDone({ |
- status: 0x804b000d, //NS_ERROR_CONNECTION_REFUSED; |
+ status: 0x804b000d, // NS_ERROR_CONNECTION_REFUSED; |
responseStatus: 0 |
}); |
return; |
} |
window._webRequest.GET(this._url, this._requestHeaders, onGetDone); |
- }.bind(this)); |
+ }); |
}, |
- overrideMimeType: function(mime) |
+ overrideMimeType(mime) |
{ |
}, |
- setRequestHeader: function(name, value) |
+ setRequestHeader(name, value) |
{ |
if (this.readyState > 1) |
throw new Error("Cannot set request header after sending"); |
if (this._isRequestHeaderAllowed(name)) |
this._requestHeaders[name] = value; |
else |
console.warn("Attempt to set a forbidden header was denied: " + name); |
}, |
- getResponseHeader: function(name) |
+ getResponseHeader(name) |
{ |
name = name.toLowerCase(); |
if (!this._responseHeaders || !this._responseHeaders.hasOwnProperty(name)) |
return null; |
- else |
- return this._responseHeaders[name]; |
+ return this._responseHeaders[name]; |
}, |
channel: |
{ |
status: -1, |
notificationCallbacks: {}, |
loadFlags: 0, |
INHIBIT_CACHING: 0, |
VALIDATE_ALWAYS: 0, |
- QueryInterface: function() |
+ QueryInterface() |
{ |
return this; |
} |
} |
}; |
-function _isSubscriptionDownloadAllowed(callback) { |
+function _isSubscriptionDownloadAllowed(callback) |
+{ |
// It's a bit hacky, JsEngine interface which is used by FilterEngine does |
// not allow to inject an arbitrary callback, so we use triggerEvent |
// mechanism. |
// Yet one hack (#5039). |
- var allowed_connection_type = require("prefs").Prefs.allowed_connection_type; |
- if (allowed_connection_type == "") |
- allowed_connection_type = null; |
- _triggerEvent("_isSubscriptionDownloadAllowed", allowed_connection_type, callback); |
+ let allowedConnectionType = require("prefs").Prefs.allowed_connection_type; |
+ if (allowedConnectionType == "") |
+ allowedConnectionType = null; |
+ _triggerEvent("_isSubscriptionDownloadAllowed", allowedConnectionType, |
+ callback); |
} |
- |
-// Polyfill Array.prototype.find |
-// from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find |
-// https://tc39.github.io/ecma262/#sec-array.prototype.find |
-if (!Array.prototype.find) { |
- Object.defineProperty(Array.prototype, 'find', { |
- value: function (predicate) { |
- // 1. Let O be ? ToObject(this value). |
- if (this == null) { |
- throw new TypeError('"this" is null or not defined'); |
- } |
- |
- var o = Object(this); |
- |
- // 2. Let len be ? ToLength(? Get(O, "length")). |
- var len = o.length >>> 0; |
- |
- // 3. If IsCallable(predicate) is false, throw a TypeError exception. |
- if (typeof predicate !== 'function') { |
- throw new TypeError('predicate must be a function'); |
- } |
- |
- // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. |
- var thisArg = arguments[1]; |
- |
- // 5. Let k be 0. |
- var k = 0; |
- |
- // 6. Repeat, while k < len |
- while (k < len) { |
- // a. Let Pk be ! ToString(k). |
- // b. Let kValue be ? Get(O, Pk). |
- // c. Let testResult be ToBoolean(? Call(predicate, T, "kValue, k, O")). |
- // d. If testResult is true, return kValue. |
- var kValue = o[k]; |
- if (predicate.call(thisArg, kValue, k, o)) { |
- return kValue; |
- } |
- // e. Increase k by 1. |
- k++; |
- } |
- } |
- }); |
-} |