Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/compat.js

Issue 29545700: Issue 5685 - Pass ESLint (Closed) Base URL: https://hg.adblockplus.org/libadblockplus/
Patch Set: Address review comments Created Sept. 18, 2017, 12:42 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/api.js ('k') | lib/elemHideHitRegistration.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 var window = this; 18 "use strict";
19
20 let window = this;
19 21
20 // 22 //
21 // Module framework stuff 23 // Module framework stuff
22 // 24 //
23 25
24 function require(module) 26 function require(module)
25 { 27 {
26 return require.scopes[module]; 28 return require.scopes[module];
27 } 29 }
28 require.scopes = {__proto__: null}; 30 require.scopes = {__proto__: null};
29 31
30 function importAll(module, globalObj)
31 {
32 var exports = require(module);
33 for (var key in exports)
34 globalObj[key] = exports[key];
35 }
36
37 const onShutdown = { 32 const onShutdown = {
38 done: false, 33 done: false,
39 add: function() {}, 34 add() {},
40 remove: function() {} 35 remove() {}
41 }; 36 };
42 37
43 // 38 //
44 // XPCOM emulation 39 // XPCOM emulation
45 // 40 //
46 41
42 // nsIHttpChannel is checked against instanceof.
43 class nsIHttpChannel
44 {
45 }
46
47 const Components = 47 const Components =
48 { 48 {
49 interfaces: 49 interfaces:
50 { 50 {
51 nsIHttpChannel: function() {}, 51 nsIHttpChannel,
52 nsITimer: {TYPE_REPEATING_SLACK: 0}, 52 nsITimer: {TYPE_REPEATING_SLACK: 0}
53 },
54 classes:
55 {
56 "@mozilla.org/timer;1":
57 {
58 createInstance: function()
59 {
60 return new FakeTimer();
61 }
62 }, 53 },
63 }, 54 classes:
64 utils: { 55 {
65 reportError: function(e) 56 "@mozilla.org/timer;1":
66 { 57 {
67 console.error(e); 58 createInstance()
68 console.trace(); 59 {
60 return new FakeTimer();
61 }
62 }
69 }, 63 },
70 import: function(resource) 64 utils:
71 { 65 {
72 let match = /^resource:\/\/gre\/modules\/(.+)\.jsm$/.exec(resource); 66 reportError(e)
73 let resourceName = match && match[1]; 67 {
74 if (resourceName && Cu.import.resources.has(resourceName)) 68 console.error(e);
75 return {[resourceName]: Cu.import.resources.get(resourceName)}; 69 console.trace();
76 throw new Error("Attempt to import unknown JavaScript module " + resource) ; 70 },
71 import(resource)
72 {
73 let match = /^resource:\/\/gre\/modules\/(.+)\.jsm$/.exec(resource);
74 let resourceName = match && match[1];
75 if (resourceName && Cu.import.resources.has(resourceName))
76 return {[resourceName]: Cu.import.resources.get(resourceName)};
77 throw new Error(
78 "Attempt to import unknown JavaScript module " + resource);
79 }
77 } 80 }
78 }, 81 };
79 };
80 82
81 const Cc = Components.classes; 83 const Cc = Components.classes;
82 const Ci = Components.interfaces; 84 const Ci = Components.interfaces;
83 const Cu = Components.utils; 85 const Cu = Components.utils;
84 86
85 Cu.import.resources = new Map(); 87 Cu.import.resources = new Map();
86 88
87 Cu.import.resources.set("XPCOMUtils", 89 Cu.import.resources.set("XPCOMUtils",
88 { 90 {
89 generateQI: function() {} 91 generateQI() {}
90 }); 92 });
91 93
92 // 94 //
93 // Services.jsm module emulation 95 // Services.jsm module emulation
94 // 96 //
95 97
96 Cu.import.resources.set("Services", 98 Cu.import.resources.set("Services",
97 { 99 {
98 obs: { 100 obs: {
99 addObserver: function() {}, 101 addObserver() {},
100 removeObserver: function() {} 102 removeObserver() {}
101 }, 103 },
102 vc: { 104 vc: {
103 compare: function(v1, v2) 105 compare(v1, v2)
104 { 106 {
105 function parsePart(s) 107 function parsePart(s)
106 { 108 {
107 if (!s) 109 if (!s)
108 return parsePart("0"); 110 return parsePart("0");
109 111
110 var part = { 112 let part = {
111 numA: 0, 113 numA: 0,
112 strB: "", 114 strB: "",
113 numC: 0, 115 numC: 0,
114 extraD: "" 116 extraD: ""
115 }; 117 };
116 118
117 if (s === "*") 119 if (s === "*")
118 { 120 {
119 part.numA = Number.MAX_VALUE; 121 part.numA = Number.MAX_VALUE;
122 return part;
123 }
124
125 let matches = s.match(/(\d*)(\D*)(\d*)(.*)/);
126 part.numA = parseInt(matches[1], 10) || part.numA;
127 part.strB = matches[2] || part.strB;
128 part.numC = parseInt(matches[3], 10) || part.numC;
129 part.extraD = matches[4] || part.extraD;
130
131 if (part.strB == "+")
132 {
133 part.numA++;
134 part.strB = "pre";
135 }
136
120 return part; 137 return part;
121 } 138 }
122 139
123 var matches = s.match(/(\d*)(\D*)(\d*)(.*)/); 140 function comparePartElement(s1, s2)
124 part.numA = parseInt(matches[1], 10) || part.numA; 141 {
125 part.strB = matches[2] || part.strB; 142 if (s1 === "" && s2 !== "")
126 part.numC = parseInt(matches[3], 10) || part.numC; 143 return 1;
127 part.extraD = matches[4] || part.extraD; 144 if (s1 !== "" && s2 === "")
128 145 return -1;
129 if (part.strB == "+") 146 return s1 === s2 ? 0 : (s1 > s2 ? 1 : -1);
130 { 147 }
131 part.numA++; 148
132 part.strB = "pre"; 149 function compareParts(p1, p2)
133 } 150 {
134 151 let result = 0;
135 return part; 152 let elements = ["numA", "strB", "numC", "extraD"];
136 } 153 elements.some(element =>
137 154 {
138 function comparePartElement(s1, s2) 155 result = comparePartElement(p1[element], p2[element]);
139 { 156 return result;
140 if (s1 === "" && s2 !== "") 157 });
141 return 1;
142 if (s1 !== "" && s2 === "")
143 return -1;
144 return s1 === s2 ? 0 : (s1 > s2 ? 1 : -1);
145 }
146
147 function compareParts(p1, p2)
148 {
149 var result = 0;
150 var elements = ["numA", "strB", "numC", "extraD"];
151 elements.some(function(element)
152 {
153 result = comparePartElement(p1[element], p2[element]);
154 return result; 158 return result;
155 }); 159 }
156 return result; 160
157 } 161 let parts1 = v1.split(".");
158 162 let parts2 = v2.split(".");
159 var parts1 = v1.split("."); 163 for (let i = 0; i < Math.max(parts1.length, parts2.length); i++)
160 var parts2 = v2.split("."); 164 {
161 for (var i = 0; i < Math.max(parts1.length, parts2.length); i++) 165 let result = compareParts(parsePart(parts1[i]), parsePart(parts2[i]));
162 { 166 if (result)
163 var result = compareParts(parsePart(parts1[i]), parsePart(parts2[i])); 167 return result;
164 if (result) 168 }
165 return result; 169 return 0;
166 } 170 }
167 return 0;
168 } 171 }
169 } 172 });
170 });
171 173
172 function FakeTimer() 174 function FakeTimer()
173 { 175 {
174 } 176 }
175 FakeTimer.prototype = 177 FakeTimer.prototype =
176 { 178 {
177 delay: 0, 179 delay: 0,
178 callback: null, 180 callback: null,
179 initWithCallback: function(callback, delay) 181 initWithCallback(callback, delay)
180 { 182 {
181 this.callback = callback; 183 this.callback = callback;
182 this.delay = delay; 184 this.delay = delay;
183 this.scheduleTimeout(); 185 this.scheduleTimeout();
184 }, 186 },
185 scheduleTimeout: function() 187 scheduleTimeout()
186 { 188 {
187 var me = this; 189 setTimeout(() =>
188 setTimeout(function()
189 { 190 {
190 try 191 try
191 { 192 {
192 me.callback(); 193 this.callback();
193 } 194 }
194 catch(e) 195 catch (e)
195 { 196 {
196 Cu.reportError(e); 197 Cu.reportError(e);
197 } 198 }
198 me.scheduleTimeout(); 199 this.scheduleTimeout();
199 }, this.delay); 200 }, this.delay);
200 } 201 }
201 }; 202 };
202 203
203 // 204 //
204 // Fake XMLHttpRequest implementation 205 // Fake XMLHttpRequest implementation
205 // 206 //
206 207
207 function XMLHttpRequest() 208 function XMLHttpRequest()
208 { 209 {
209 this._requestHeaders = {}; 210 this._requestHeaders = {};
210 this._loadHandlers = []; 211 this._loadHandlers = [];
211 this._errorHandlers = []; 212 this._errorHandlers = [];
212 }; 213 }
213 XMLHttpRequest.prototype = 214 XMLHttpRequest.prototype =
214 { 215 {
215 _url: null, 216 _url: null,
216 _requestHeaders: null, 217 _requestHeaders: null,
217 _responseHeaders: null, 218 _responseHeaders: null,
218 _loadHandlers: null, 219 _loadHandlers: null,
219 _errorHandlers: null, 220 _errorHandlers: null,
220 onload: null, 221 onload: null,
221 onerror: null, 222 onerror: null,
222 status: 0, 223 status: 0,
(...skipping 14 matching lines...) Expand all
237 "dnt": true, 238 "dnt": true,
238 "expect": true, 239 "expect": true,
239 "host": true, 240 "host": true,
240 "keep-alive": true, 241 "keep-alive": true,
241 "origin": true, 242 "origin": true,
242 "referer": true, 243 "referer": true,
243 "te": true, 244 "te": true,
244 "trailer": true, 245 "trailer": true,
245 "transfer-encoding": true, 246 "transfer-encoding": true,
246 "upgrade": true, 247 "upgrade": true,
247 "via": true, 248 "via": true
248 }, 249 },
249 _forbiddenRequestHeadersRe: new RegExp("^(Proxy|Sec)-", "i"), 250 _forbiddenRequestHeadersRe: new RegExp("^(Proxy|Sec)-", "i"),
250 251
251 _isRequestHeaderAllowed: function(header) 252 _isRequestHeaderAllowed(header)
252 { 253 {
253 if (this._forbiddenRequestHeaders.hasOwnProperty(header.toLowerCase())) 254 if (this._forbiddenRequestHeaders.hasOwnProperty(header.toLowerCase()))
254 return false; 255 return false;
255 if (header.match(this._forbiddenRequestHeadersRe)) 256 if (header.match(this._forbiddenRequestHeadersRe))
256 return false; 257 return false;
257 258
258 return true; 259 return true;
259 }, 260 },
260 261
261 addEventListener: function(eventName, handler, capture) 262 addEventListener(eventName, handler, capture)
262 { 263 {
263 var list; 264 let list;
264 if (eventName == "load") 265 if (eventName == "load")
265 list = this._loadHandlers; 266 list = this._loadHandlers;
266 else if (eventName == "error") 267 else if (eventName == "error")
267 list = this._errorHandlers; 268 list = this._errorHandlers;
268 else 269 else
269 throw new Error("Event type " + eventName + " not supported"); 270 throw new Error("Event type " + eventName + " not supported");
270 271
271 if (list.indexOf(handler) < 0) 272 if (list.indexOf(handler) < 0)
272 list.push(handler); 273 list.push(handler);
273 }, 274 },
274 275
275 removeEventListener: function(eventName, handler, capture) 276 removeEventListener(eventName, handler, capture)
276 { 277 {
277 var list; 278 let list;
278 if (eventName == "load") 279 if (eventName == "load")
279 list = this._loadHandlers; 280 list = this._loadHandlers;
280 else if (eventName == "error") 281 else if (eventName == "error")
281 list = this._errorHandlers; 282 list = this._errorHandlers;
282 else 283 else
283 throw new Error("Event type " + eventName + " not supported"); 284 throw new Error("Event type " + eventName + " not supported");
284 285
285 var index = list.indexOf(handler); 286 let index = list.indexOf(handler);
286 if (index >= 0) 287 if (index >= 0)
287 list.splice(index, 1); 288 list.splice(index, 1);
288 }, 289 },
289 290
290 open: function(method, url, async, user, password) 291 open(method, url, async, user, password)
291 { 292 {
292 if (method != "GET") 293 if (method != "GET")
293 throw new Error("Only GET requests are currently supported"); 294 throw new Error("Only GET requests are currently supported");
294 if (typeof async != "undefined" && !async) 295 if (typeof async != "undefined" && !async)
295 throw new Error("Sync requests are not supported"); 296 throw new Error("Sync requests are not supported");
296 if (typeof user != "undefined" || typeof password != "undefined") 297 if (typeof user != "undefined" || typeof password != "undefined")
297 throw new Error("User authentification is not supported"); 298 throw new Error("User authentification is not supported");
298 if (this.readyState != 0) 299 if (this.readyState != 0)
299 throw new Error("Already opened"); 300 throw new Error("Already opened");
300 301
301 this.readyState = 1; 302 this.readyState = 1;
302 this._url = url; 303 this._url = url;
303 }, 304 },
304 305
305 send: function(data) 306 send(data)
306 { 307 {
307 if (this.readyState != 1) 308 if (this.readyState != 1)
308 throw new Error("XMLHttpRequest.send() is being called before XMLHttpReque st.open()"); 309 throw new Error(
310 "XMLHttpRequest.send() is being called before XMLHttpRequest.open()");
309 if (typeof data != "undefined" && data) 311 if (typeof data != "undefined" && data)
310 throw new Error("Sending data to server is not supported"); 312 throw new Error("Sending data to server is not supported");
311 313
312 this.readyState = 3; 314 this.readyState = 3;
313 315
314 var onGetDone = function(result) 316 let onGetDone = result =>
315 { 317 {
316 this.channel.status = result.status; 318 this.channel.status = result.status;
317 this.status = result.responseStatus; 319 this.status = result.responseStatus;
318 this.responseText = result.responseText; 320 this.responseText = result.responseText;
319 this._responseHeaders = result.responseHeaders; 321 this._responseHeaders = result.responseHeaders;
320 this.readyState = 4; 322 this.readyState = 4;
321 323
322 // Notify event listeners 324 // Notify event listeners
323 const NS_OK = 0; 325 const NS_OK = 0;
324 var eventName = (this.channel.status == NS_OK ? "load" : "error"); 326 let eventName = (this.channel.status == NS_OK ? "load" : "error");
325 var event = {type: eventName}; 327 let event = {type: eventName};
326 328
327 if (this["on" + eventName]) 329 if (this["on" + eventName])
328 this["on" + eventName].call(this, event); 330 this["on" + eventName].call(this, event);
329 331
330 var list = this["_" + eventName + "Handlers"]; 332 let list = this["_" + eventName + "Handlers"];
331 for (var i = 0; i < list.length; i++) 333 for (let i = 0; i < list.length; i++)
332 list[i].call(this, event); 334 list[i].call(this, event);
333 }.bind(this); 335 };
334 // HACK (#5066): the code checking whether the connection is allowed is temp orary, 336 // HACK (#5066): the code checking whether the connection is
335 // the actual check should be in the core when we make a decision whether 337 // allowed is temporary, the actual check should be in the core
336 // to update a subscription with current connection or not, thus whether to 338 // when we make a decision whether to update a subscription with
337 // even construct XMLHttpRequest object or not. 339 // current connection or not, thus whether to even construct
338 _isSubscriptionDownloadAllowed(function(isAllowed) 340 // XMLHttpRequest object or not.
341 _isSubscriptionDownloadAllowed(isAllowed =>
339 { 342 {
340 if (!isAllowed) 343 if (!isAllowed)
341 { 344 {
342 onGetDone({ 345 onGetDone({
343 status: 0x804b000d, //NS_ERROR_CONNECTION_REFUSED; 346 status: 0x804b000d, // NS_ERROR_CONNECTION_REFUSED;
344 responseStatus: 0 347 responseStatus: 0
345 }); 348 });
346 return; 349 return;
347 } 350 }
348 window._webRequest.GET(this._url, this._requestHeaders, onGetDone); 351 window._webRequest.GET(this._url, this._requestHeaders, onGetDone);
349 }.bind(this)); 352 });
350 }, 353 },
351 354
352 overrideMimeType: function(mime) 355 overrideMimeType(mime)
353 { 356 {
354 }, 357 },
355 358
356 setRequestHeader: function(name, value) 359 setRequestHeader(name, value)
357 { 360 {
358 if (this.readyState > 1) 361 if (this.readyState > 1)
359 throw new Error("Cannot set request header after sending"); 362 throw new Error("Cannot set request header after sending");
360 363
361 if (this._isRequestHeaderAllowed(name)) 364 if (this._isRequestHeaderAllowed(name))
362 this._requestHeaders[name] = value; 365 this._requestHeaders[name] = value;
363 else 366 else
364 console.warn("Attempt to set a forbidden header was denied: " + name); 367 console.warn("Attempt to set a forbidden header was denied: " + name);
365 }, 368 },
366 369
367 getResponseHeader: function(name) 370 getResponseHeader(name)
368 { 371 {
369 name = name.toLowerCase(); 372 name = name.toLowerCase();
370 if (!this._responseHeaders || !this._responseHeaders.hasOwnProperty(name)) 373 if (!this._responseHeaders || !this._responseHeaders.hasOwnProperty(name))
371 return null; 374 return null;
372 else 375 return this._responseHeaders[name];
373 return this._responseHeaders[name];
374 }, 376 },
375 377
376 channel: 378 channel:
377 { 379 {
378 status: -1, 380 status: -1,
379 notificationCallbacks: {}, 381 notificationCallbacks: {},
380 loadFlags: 0, 382 loadFlags: 0,
381 INHIBIT_CACHING: 0, 383 INHIBIT_CACHING: 0,
382 VALIDATE_ALWAYS: 0, 384 VALIDATE_ALWAYS: 0,
383 QueryInterface: function() 385 QueryInterface()
384 { 386 {
385 return this; 387 return this;
386 } 388 }
387 } 389 }
388 }; 390 };
389 391
390 function _isSubscriptionDownloadAllowed(callback) { 392 function _isSubscriptionDownloadAllowed(callback)
393 {
391 // It's a bit hacky, JsEngine interface which is used by FilterEngine does 394 // It's a bit hacky, JsEngine interface which is used by FilterEngine does
392 // not allow to inject an arbitrary callback, so we use triggerEvent 395 // not allow to inject an arbitrary callback, so we use triggerEvent
393 // mechanism. 396 // mechanism.
394 // Yet one hack (#5039). 397 // Yet one hack (#5039).
395 var allowed_connection_type = require("prefs").Prefs.allowed_connection_type; 398 let allowedConnectionType = require("prefs").Prefs.allowed_connection_type;
396 if (allowed_connection_type == "") 399 if (allowedConnectionType == "")
397 allowed_connection_type = null; 400 allowedConnectionType = null;
398 _triggerEvent("_isSubscriptionDownloadAllowed", allowed_connection_type, callb ack); 401 _triggerEvent("_isSubscriptionDownloadAllowed", allowedConnectionType,
402 callback);
399 } 403 }
400
401 // Polyfill Array.prototype.find
402 // from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Ob jects/Array/find
403 // https://tc39.github.io/ecma262/#sec-array.prototype.find
404 if (!Array.prototype.find) {
405 Object.defineProperty(Array.prototype, 'find', {
406 value: function (predicate) {
407 // 1. Let O be ? ToObject(this value).
408 if (this == null) {
409 throw new TypeError('"this" is null or not defined');
410 }
411
412 var o = Object(this);
413
414 // 2. Let len be ? ToLength(? Get(O, "length")).
415 var len = o.length >>> 0;
416
417 // 3. If IsCallable(predicate) is false, throw a TypeError exception.
418 if (typeof predicate !== 'function') {
419 throw new TypeError('predicate must be a function');
420 }
421
422 // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
423 var thisArg = arguments[1];
424
425 // 5. Let k be 0.
426 var k = 0;
427
428 // 6. Repeat, while k < len
429 while (k < len) {
430 // a. Let Pk be ! ToString(k).
431 // b. Let kValue be ? Get(O, Pk).
432 // c. Let testResult be ToBoolean(? Call(predicate, T, "kValue, k, O")).
433 // d. If testResult is true, return kValue.
434 var kValue = o[k];
435 if (predicate.call(thisArg, kValue, k, o)) {
436 return kValue;
437 }
438 // e. Increase k by 1.
439 k++;
440 }
441 }
442 });
443 }
OLDNEW
« no previous file with comments | « lib/api.js ('k') | lib/elemHideHitRegistration.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld