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

Delta Between Two Patch Sets: new-options.js

Issue 29346555: Issue 4156 - Adblocking filter only being removed in advanced tab fix (Closed)
Left Patch Set: Created June 15, 2016, 5:35 p.m.
Right Patch Set: Changed addItems method to only accept 1 parameter and changed recommendations initial status Created Aug. 17, 2016, 2:55 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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 "use strict"; 18 "use strict";
19 19
20 (function() 20 (function()
21 { 21 {
22 var subscriptionsMap = Object.create(null); 22 var subscriptionsMap = Object.create(null);
23 var filtersMap = Object.create(null); 23 var filtersMap = Object.create(null);
24 var collections = Object.create(null); 24 var collections = Object.create(null);
25 var acceptableAdsUrl = null; 25 var acceptableAdsUrl = null;
26 var maxLabelId = 0;
27 var getMessage = ext.i18n.getMessage; 26 var getMessage = ext.i18n.getMessage;
28 var filterErrors = 27 var filterErrors =
29 { 28 {
30 "synchronize_invalid_url": "options_filterList_lastDownload_invalidURL", 29 "synchronize_invalid_url": "options_filterList_lastDownload_invalidURL",
31 "synchronize_connection_error": "options_filterList_lastDownload_connectionE rror", 30 "synchronize_connection_error": "options_filterList_lastDownload_connectionE rror",
32 "synchronize_invalid_data": "options_filterList_lastDownload_invalidData", 31 "synchronize_invalid_data": "options_filterList_lastDownload_invalidData",
33 "synchronize_checksum_mismatch": "options_filterList_lastDownload_checksumMi smatch" 32 "synchronize_checksum_mismatch": "options_filterList_lastDownload_checksumMi smatch"
34 }; 33 };
35 34
36 function Collection(details) 35 function Collection(details)
(...skipping 27 matching lines...) Expand all
64 63
65 Collection.prototype._getItemTitle = function(item, i) 64 Collection.prototype._getItemTitle = function(item, i)
66 { 65 {
67 if (item.url == acceptableAdsUrl) 66 if (item.url == acceptableAdsUrl)
68 return getMessage("options_acceptableAds_description"); 67 return getMessage("options_acceptableAds_description");
69 if (this.details[i].useOriginalTitle && item.originalTitle) 68 if (this.details[i].useOriginalTitle && item.originalTitle)
70 return item.originalTitle; 69 return item.originalTitle;
71 return item.title || item.url || item.text; 70 return item.title || item.url || item.text;
72 }; 71 };
73 72
74 Collection.prototype.addItems = function() 73 Collection.prototype.addItem = function(item)
75 { 74 {
76 var length = Array.prototype.push.apply(this.items, arguments); 75 if (this.items.indexOf(item) >= 0)
77 if (length == 0)
78 return; 76 return;
79 77
78 this.items.push(item);
80 this.items.sort(function(a, b) 79 this.items.sort(function(a, b)
81 { 80 {
82 // Make sure that Acceptable Ads is always last, since it cannot be 81 // Make sure that Acceptable Ads is always last, since it cannot be
83 // disabled, but only be removed. That way it's grouped together with 82 // disabled, but only be removed. That way it's grouped together with
84 // the "Own filter list" which cannot be disabled either at the bottom 83 // the "Own filter list" which cannot be disabled either at the bottom
85 // of the filter lists in the Advanced tab. 84 // of the filter lists in the Advanced tab.
86 if (a.url == acceptableAdsUrl) 85 if (a.url == acceptableAdsUrl)
87 return 1; 86 return 1;
88 if (b.url == acceptableAdsUrl) 87 if (b.url == acceptableAdsUrl)
89 return -1; 88 return -1;
90 89
91 var aTitle = this._getItemTitle(a, 0).toLowerCase(); 90 var aTitle = this._getItemTitle(a, 0).toLowerCase();
92 var bTitle = this._getItemTitle(b, 0).toLowerCase(); 91 var bTitle = this._getItemTitle(b, 0).toLowerCase();
93 return aTitle.localeCompare(bTitle); 92 return aTitle.localeCompare(bTitle);
94 }.bind(this)); 93 }.bind(this));
95 94
96 for (var j = 0; j < this.details.length; j++) 95 for (var j = 0; j < this.details.length; j++)
97 { 96 {
98 var table = E(this.details[j].id); 97 var table = E(this.details[j].id);
99 var template = table.querySelector("template"); 98 var template = table.querySelector("template");
100 for (var i = 0; i < arguments.length; i++) 99 var listItem = document.createElement("li");
101 { 100 listItem.appendChild(document.importNode(template.content, true));
102 var item = arguments[i]; 101 listItem.setAttribute("aria-label", this._getItemTitle(item, j));
103 var listItem = document.createElement("li"); 102 listItem.setAttribute("data-access", item.url || item.text);
104 listItem.appendChild(document.importNode(template.content, true)); 103 listItem.setAttribute("role", "section");
105 listItem.setAttribute("data-access", item.url || item.text); 104
106 105 var label = listItem.querySelector(".display");
107 var labelId = "label-" + (++maxLabelId); 106 if (item.recommended && label.hasAttribute("data-tooltip"))
108 var label = listItem.querySelector(".display"); 107 {
109 label.setAttribute("id", labelId); 108 var tooltipId = label.getAttribute("data-tooltip");
110 if (item.recommended && label.hasAttribute("data-tooltip")) 109 tooltipId = tooltipId.replace("%value%", item.recommended);
111 { 110 label.setAttribute("data-tooltip", tooltipId);
112 var tooltipId = label.getAttribute("data-tooltip"); 111 }
113 tooltipId = tooltipId.replace("%value%", item.recommended); 112
114 label.setAttribute("data-tooltip", tooltipId); 113 var controls = listItem.querySelectorAll(".control");
114 for (var k = 0; k < controls.length; k++)
115 {
116 if (controls[k].hasAttribute("title"))
117 {
118 var titleValue = getMessage(controls[k].getAttribute("title"));
119 controls[k].setAttribute("title", titleValue)
115 } 120 }
116 121 }
117 var control = listItem.querySelector(".control"); 122
118 if (control) 123 this._setEmpty(table, null);
119 { 124 if (table.hasChildNodes())
120 control.setAttribute("aria-labelledby", labelId); 125 {
121 control.addEventListener("click", this.details[j].onClick, false); 126 table.insertBefore(listItem,
122 127 table.childNodes[this.items.indexOf(item)]);
123 var role = control.getAttribute("role"); 128 }
124 if (role == "checkbox" && !label.hasAttribute("data-action")) 129 else
125 { 130 table.appendChild(listItem);
126 var controlId = "control-" + maxLabelId; 131 this.updateItem(item);
127 control.setAttribute("id", controlId);
128 label.setAttribute("for", controlId);
129 }
130 }
131
132 this._setEmpty(table, null);
133 if (table.hasChildNodes())
134 {
135 table.insertBefore(listItem,
136 table.childNodes[this.items.indexOf(item)]);
137 }
138 else
139 table.appendChild(listItem);
140 this.updateItem(item);
141 }
142 } 132 }
143 return length; 133 return length;
144 }; 134 };
145 135
146 Collection.prototype.removeItem = function(item) 136 Collection.prototype.removeItem = function(item)
147 { 137 {
148 var index = this.items.indexOf(item); 138 var index = this.items.indexOf(item);
149 if (index == -1) 139 if (index == -1)
150 return; 140 return;
151 141
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 var access = (item.url || item.text).replace(/'/g, "\\'"); 177 var access = (item.url || item.text).replace(/'/g, "\\'");
188 for (var i = 0; i < this.details.length; i++) 178 for (var i = 0; i < this.details.length; i++)
189 { 179 {
190 var table = E(this.details[i].id); 180 var table = E(this.details[i].id);
191 var element = table.querySelector("[data-access='" + access + "']"); 181 var element = table.querySelector("[data-access='" + access + "']");
192 if (!element) 182 if (!element)
193 continue; 183 continue;
194 184
195 var title = this._getItemTitle(item, i); 185 var title = this._getItemTitle(item, i);
196 element.querySelector(".display").textContent = title; 186 element.querySelector(".display").textContent = title;
197 if (title) 187 element.setAttribute("aria-label", title);
188 if (this.details[i].searchable)
198 element.setAttribute("data-search", title.toLowerCase()); 189 element.setAttribute("data-search", title.toLowerCase());
199 var control = element.querySelector(".control[role='checkbox']"); 190 var control = element.querySelector(".control[role='checkbox']");
200 if (control) 191 if (control)
201 { 192 {
202 control.setAttribute("aria-checked", item.disabled == false); 193 control.setAttribute("aria-checked", item.disabled == false);
203 if (item.url == acceptableAdsUrl && this.details[i].onClick == 194 if (item.url == acceptableAdsUrl && this == collections.filterLists)
204 toggleDisableSubscription)
205 control.setAttribute("disabled", true); 195 control.setAttribute("disabled", true);
206 } 196 }
207 197
208 var dateElement = element.querySelector(".date"); 198 var dateElement = element.querySelector(".date");
209 var timeElement = element.querySelector(".time"); 199 var timeElement = element.querySelector(".time");
210 if (dateElement && timeElement) 200 if (dateElement && timeElement)
211 { 201 {
212 var message = element.querySelector(".message"); 202 var message = element.querySelector(".message");
213 if (item.isDownloading) 203 if (item.isDownloading)
214 { 204 {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 index += (index == focusables.length - 1) ? -1 : 1; 265 index += (index == focusables.length - 1) ? -1 : 1;
276 266
277 var nextElement = focusables[index]; 267 var nextElement = focusables[index];
278 if (!nextElement) 268 if (!nextElement)
279 return false; 269 return false;
280 270
281 nextElement.focus(); 271 nextElement.focus();
282 return true; 272 return true;
283 } 273 }
284 274
285 function toggleRemoveSubscription(e)
286 {
287 e.preventDefault();
288 var subscriptionUrl = findParentData(e.target, "access", false);
289 if (e.target.getAttribute("aria-checked") == "true")
290 {
291 ext.backgroundPage.sendMessage({
292 type: "subscriptions.remove",
293 url: subscriptionUrl
294 });
295 }
296 else
297 addEnableSubscription(subscriptionUrl);
298 }
299
300 function toggleDisableSubscription(e)
301 {
302 e.preventDefault();
303 var subscriptionUrl = findParentData(e.target, "access", false);
304 ext.backgroundPage.sendMessage(
305 {
306 type: "subscriptions.toggle",
307 keepInstalled: true,
308 url: subscriptionUrl
309 });
310 }
311
312 function onAddLanguageSubscriptionClick(e)
313 {
314 e.preventDefault();
315 var url = findParentData(this, "access", false);
316 addEnableSubscription(url);
317 }
318
319 function onRemoveFilterClick()
320 {
321 var filter = findParentData(this, "access", false);
322 ext.backgroundPage.sendMessage(
323 {
324 type: "filters.remove",
325 text: filter
326 });
327 }
328
329 collections.popular = new Collection( 275 collections.popular = new Collection(
330 [ 276 [
331 { 277 {
332 id: "recommend-list-table", 278 id: "recommend-list-table"
333 onClick: toggleRemoveSubscription
334 } 279 }
335 ]); 280 ]);
336 collections.langs = new Collection( 281 collections.langs = new Collection(
337 [ 282 [
338 { 283 {
339 id: "blocking-languages-table", 284 id: "blocking-languages-table",
340 emptyText: "options_dialog_language_added_empty", 285 emptyText: "options_dialog_language_added_empty"
341 onClick: toggleRemoveSubscription
342 }, 286 },
343 { 287 {
344 id: "blocking-languages-dialog-table", 288 id: "blocking-languages-dialog-table",
345 emptyText: "options_dialog_language_added_empty" 289 emptyText: "options_dialog_language_added_empty"
346 } 290 }
347 ]); 291 ]);
348 collections.allLangs = new Collection( 292 collections.allLangs = new Collection(
349 [ 293 [
350 { 294 {
351 id: "all-lang-table", 295 id: "all-lang-table",
352 emptyText: "options_dialog_language_other_empty", 296 emptyText: "options_dialog_language_other_empty",
353 onClick: onAddLanguageSubscriptionClick 297 searchable: true
354 } 298 }
355 ]); 299 ]);
356 collections.acceptableAds = new Collection( 300 collections.acceptableAds = new Collection(
357 [ 301 [
358 { 302 {
359 id: "acceptableads-table", 303 id: "acceptableads-table"
360 onClick: toggleRemoveSubscription
361 } 304 }
362 ]); 305 ]);
363 collections.custom = new Collection( 306 collections.custom = new Collection(
364 [ 307 [
365 { 308 {
366 id: "custom-list-table", 309 id: "custom-list-table"
367 onClick: toggleRemoveSubscription
368 } 310 }
369 ]); 311 ]);
370 collections.whitelist = new Collection( 312 collections.whitelist = new Collection(
371 [ 313 [
372 { 314 {
373 id: "whitelisting-table", 315 id: "whitelisting-table",
374 emptyText: "options_whitelisted_empty", 316 emptyText: "options_whitelisted_empty"
375 onClick: onRemoveFilterClick
376 } 317 }
377 ]); 318 ]);
378 collections.customFilters = new Collection( 319 collections.customFilters = new Collection(
379 [ 320 [
380 { 321 {
381 id: "custom-filters-table", 322 id: "custom-filters-table",
382 emptyText: "options_customFilters_empty" 323 emptyText: "options_customFilters_empty"
383 } 324 }
384 ]); 325 ]);
385 collections.filterLists = new Collection( 326 collections.filterLists = new Collection(
386 [ 327 [
387 { 328 {
388 id: "all-filter-lists-table", 329 id: "all-filter-lists-table",
389 onClick: toggleDisableSubscription,
390 useOriginalTitle: true 330 useOriginalTitle: true
391 } 331 }
392 ]); 332 ]);
393 333
394 function updateLanguageCollections(subscription) 334 function toggleShowLanguage(subscription)
395 { 335 {
396 if (subscription.recommended == "ads") 336 if (subscription.recommended == "ads")
397 { 337 {
398 if (subscription.disabled) 338 if (subscription.disabled)
399 { 339 {
400 collections.allLangs.addItems(subscription); 340 collections.allLangs.addItem(subscription);
401 collections.langs.removeItem(subscription); 341 collections.langs.removeItem(subscription);
402 } 342 }
403 else 343 else
404 { 344 {
405 collections.allLangs.removeItem(subscription); 345 collections.allLangs.removeItem(subscription);
406 collections.langs.addItems(subscription); 346 collections.langs.addItem(subscription);
407 } 347 }
408 } 348 }
409 } 349 }
410 350
411 function addSubscription(subscription) 351 function addSubscription(subscription)
412 { 352 {
413 var collection; 353 var collection;
414 if (subscription.recommended) 354 if (subscription.recommended)
415 { 355 {
416 if (subscription.recommended != "ads") 356 if (subscription.recommended != "ads")
417 collection = collections.popular; 357 collection = collections.popular;
418 else if (subscription.disabled == false) 358 else if (subscription.disabled == false)
419 collection = collections.langs; 359 collection = collections.langs;
420 else 360 else
421 collection = collections.allLangs; 361 collection = collections.allLangs;
422 } 362 }
423 else if (subscription.url == acceptableAdsUrl) 363 else if (subscription.url == acceptableAdsUrl)
424 collection = collections.acceptableAds; 364 collection = collections.acceptableAds;
425 else 365 else
426 collection = collections.custom; 366 collection = collections.custom;
427 367
428 collection.addItems(subscription); 368 collection.addItem(subscription);
429 subscriptionsMap[subscription.url] = subscription; 369 subscriptionsMap[subscription.url] = subscription;
370 toggleShowLanguage(subscription);
430 updateTooltips(); 371 updateTooltips();
431 } 372 }
432 373
433 function updateSubscription(subscription) 374 function updateSubscription(subscription)
434 { 375 {
435 for (var name in collections) 376 for (var name in collections)
436 collections[name].updateItem(subscription); 377 collections[name].updateItem(subscription);
378
379 toggleShowLanguage(subscription);
437 } 380 }
438 381
439 function updateFilter(filter) 382 function updateFilter(filter)
440 { 383 {
441 var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/); 384 var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/);
442 if (match && !filtersMap[filter.text]) 385 if (match && !filtersMap[filter.text])
443 { 386 {
444 filter.title = match[1]; 387 filter.title = match[1];
445 collections.whitelist.addItems(filter); 388 collections.whitelist.addItem(filter);
446 } 389 }
447 else 390 else
448 collections.customFilters.addItems(filter); 391 collections.customFilters.addItem(filter);
449 392
450 filtersMap[filter.text] = filter; 393 filtersMap[filter.text] = filter;
451 } 394 }
452 395
453 function loadRecommendations() 396 function loadRecommendations()
454 { 397 {
455 fetch("subscriptions.xml") 398 fetch("subscriptions.xml")
456 .then(function(response) 399 .then(function(response)
457 { 400 {
458 return response.text(); 401 return response.text();
459 }) 402 })
460 .then(function(text) 403 .then(function(text)
461 { 404 {
462 var list = document.getElementById("subscriptionSelector"); 405 var list = document.getElementById("subscriptionSelector");
463 var doc = new DOMParser().parseFromString(text, "application/xml"); 406 var doc = new DOMParser().parseFromString(text, "application/xml");
464 var elements = doc.documentElement.getElementsByTagName("subscription"); 407 var elements = doc.documentElement.getElementsByTagName("subscription");
465 for (var i = 0; i < elements.length; i++) 408 for (var i = 0; i < elements.length; i++)
466 { 409 {
467 var element = elements[i]; 410 var element = elements[i];
468 var type = element.getAttribute("type"); 411 var type = element.getAttribute("type");
469 var subscription = { 412 var subscription = {
470 disabled: null, 413 disabled: true,
471 downloadStatus: null, 414 downloadStatus: null,
472 homepage: null, 415 homepage: null,
473 originalTitle: element.getAttribute("title"), 416 originalTitle: element.getAttribute("title"),
474 recommended: type, 417 recommended: type,
475 url: element.getAttribute("url") 418 url: element.getAttribute("url")
476 }; 419 };
477 420
478 var prefix = element.getAttribute("prefixes"); 421 var prefix = element.getAttribute("prefixes");
479 if (prefix) 422 if (prefix)
480 { 423 {
(...skipping 27 matching lines...) Expand all
508 { 451 {
509 ext.backgroundPage.sendMessage(message, function(errors) 452 ext.backgroundPage.sendMessage(message, function(errors)
510 { 453 {
511 if (errors.length > 0) 454 if (errors.length > 0)
512 alert(errors.join("\n")); 455 alert(errors.join("\n"));
513 else if (onSuccess) 456 else if (onSuccess)
514 onSuccess(); 457 onSuccess();
515 }); 458 });
516 } 459 }
517 460
461 function openDocLink(id)
462 {
463 getDocLink(id, function(link)
464 {
465 if (id == "share-general")
466 openSharePopup(link);
467 else
468 location.href = link;
469 });
470 }
471
472 function switchTab(id)
473 {
474 location.hash = id;
475 }
476
518 function onClick(e) 477 function onClick(e)
519 { 478 {
520 var context = document.querySelector(".show-context-menu"); 479 var context = document.querySelector(".show-context-menu");
521 if (context) 480 if (context)
522 context.classList.remove("show-context-menu"); 481 context.classList.remove("show-context-menu");
523 482
524 var element = e.target; 483 var element = e.target;
525 while (true) 484 while (true)
526 { 485 {
527 if (!element) 486 if (!element)
528 return; 487 return;
529 488
530 if (element.hasAttribute("data-action")) 489 if (element.hasAttribute("data-action"))
531 break; 490 break;
532 491
533 element = element.parentElement; 492 element = element.parentElement;
534 } 493 }
535 494
495 var element = findParentData(e.target, "action", true);
536 var actions = element.getAttribute("data-action").split(","); 496 var actions = element.getAttribute("data-action").split(",");
537 for (var i = 0; i < actions.length; i++) 497 for (var i = 0; i < actions.length; i++)
538 { 498 {
539 switch (actions[i]) 499 switch (actions[i])
540 { 500 {
541 case "add-domain-exception": 501 case "add-domain-exception":
542 addWhitelistedDomain(); 502 addWhitelistedDomain();
543 break; 503 break;
544 case "add-predefined-subscription": 504 case "add-predefined-subscription":
545 var dialog = E("dialog-content-predefined"); 505 var dialog = E("dialog-content-predefined");
(...skipping 19 matching lines...) Expand all
565 case "edit-domain-exception": 525 case "edit-domain-exception":
566 document.querySelector("#whitelisting .controls").classList.add("mode- edit"); 526 document.querySelector("#whitelisting .controls").classList.add("mode- edit");
567 E("whitelisting-textbox").focus(); 527 E("whitelisting-textbox").focus();
568 break; 528 break;
569 case "import-subscription": 529 case "import-subscription":
570 var url = E("blockingList-textbox").value; 530 var url = E("blockingList-textbox").value;
571 addEnableSubscription(url); 531 addEnableSubscription(url);
572 closeDialog(); 532 closeDialog();
573 break; 533 break;
574 case "open-dialog": 534 case "open-dialog":
575 openDialog(element.getAttribute("data-dialog")); 535 var dialog = findParentData(element, "dialog", false);
536 openDialog(dialog);
537 break;
538 case "open-doclink":
539 var doclink = findParentData(element, "doclink", false);
540 openDocLink(doclink);
576 break; 541 break;
577 case "save-custom-filters": 542 case "save-custom-filters":
578 sendMessageHandleErrors( 543 sendMessageHandleErrors(
579 { 544 {
580 type: "filters.importRaw", 545 type: "filters.importRaw",
581 text: E("custom-filters-raw").value, 546 text: E("custom-filters-raw").value,
582 removeExisting: true 547 removeExisting: true
583 }, 548 },
584 function() 549 function()
585 { 550 {
586 E("custom-filters").classList.remove("mode-edit"); 551 E("custom-filters").classList.remove("mode-edit");
587 }); 552 });
588 break; 553 break;
589 case "switch-tab": 554 case "switch-tab":
590 document.body.setAttribute("data-tab", 555 var tabId = findParentData(e.target, "tab", false);
591 element.getAttribute("data-tab")); 556 switchTab(tabId);
592 break; 557 break;
593 case "toggle-pref": 558 case "toggle-pref":
594 ext.backgroundPage.sendMessage( 559 ext.backgroundPage.sendMessage(
595 { 560 {
596 type: "prefs.toggle", 561 type: "prefs.toggle",
597 key: findParentData(element, "pref", false) 562 key: findParentData(element, "pref", false)
598 }); 563 });
599 break; 564 break;
600 case "update-all-subscriptions": 565 case "update-all-subscriptions":
601 ext.backgroundPage.sendMessage( 566 ext.backgroundPage.sendMessage(
(...skipping 13 matching lines...) Expand all
615 url: findParentData(element, "access", false) 580 url: findParentData(element, "access", false)
616 }); 581 });
617 break; 582 break;
618 case "remove-subscription": 583 case "remove-subscription":
619 ext.backgroundPage.sendMessage( 584 ext.backgroundPage.sendMessage(
620 { 585 {
621 type: "subscriptions.remove", 586 type: "subscriptions.remove",
622 url: findParentData(element, "access", false) 587 url: findParentData(element, "access", false)
623 }); 588 });
624 break; 589 break;
625 } 590 case "toggle-remove-subscription":
591 var subscriptionUrl = findParentData(element, "access", false);
592 if (element.getAttribute("aria-checked") == "true")
593 {
594 ext.backgroundPage.sendMessage({
595 type: "subscriptions.remove",
596 url: subscriptionUrl
597 });
598 }
599 else
600 addEnableSubscription(subscriptionUrl);
601 break;
602 case "toggle-disable-subscription":
603 ext.backgroundPage.sendMessage(
604 {
605 type: "subscriptions.toggle",
606 keepInstalled: true,
607 url: findParentData(element, "access", false)
608 });
609 break;
610 case "add-language-subscription":
611 addEnableSubscription(findParentData(element, "access", false));
612 break;
613 case "remove-filter":
614 ext.backgroundPage.sendMessage(
615 {
616 type: "filters.remove",
617 text: findParentData(element, "access", false)
618 });
619 break;
620 }
621 }
622 }
623
624 function getKey(e)
625 {
626 // e.keyCode has been deprecated so we attempt to use e.key
627 if ("key" in e)
628 return e.key;
629 return getKey.keys[e.keyCode];
630 }
631 getKey.keys = {
632 9: "Tab",
633 13: "Enter",
634 27: "Escape",
635 37: "ArrowLeft",
636 38: "ArrowUp",
637 39: "ArrowRight",
638 40: "ArrowDown"
639 };
640
641 function onKeyUp(e)
642 {
643 var key = getKey(e);
644 var element = document.activeElement;
645 if (!key || !element)
646 return;
647
648 var container = findParentData(element, "action", true);
649 if (!container || !container.hasAttribute("data-keys"))
650 return;
651
652 var keys = container.getAttribute("data-keys").split(" ");
653 if (keys.indexOf(key) < 0)
654 return;
655
656 switch (container.getAttribute("data-action"))
657 {
658 case "add-domain-exception":
659 addWhitelistedDomain();
660 break;
661 case "open-doclink":
662 var doclink = findParentData(element, "doclink", false);
663 openDocLink(doclink);
664 break;
665 case "switch-tab":
666 if (key == "Enter")
667 {
668 var tabId = findParentData(element, "tab", false);
669 switchTab(tabId);
670 }
671 else if (element.hasAttribute("aria-selected"))
672 {
673 if (key == "ArrowLeft" || key == "ArrowUp")
674 {
675 element = element.previousElementSibling
676 || container.lastElementChild;
677 }
678 else if (key == "ArrowRight" || key == "ArrowDown")
679 {
680 element = element.nextElementSibling
681 || container.firstElementChild;
682 }
683
684 var tabId = findParentData(element, "tab", false);
685 switchTab(tabId);
686 }
687 break;
688 }
689 }
690
691 function selectTabItem(tabId, container, focus)
692 {
693 // Show tab content
694 document.body.setAttribute("data-tab", tabId);
695
696 // Select tab
697 var tabList = container.querySelector("[role='tablist']");
698 if (!tabList)
699 return null;
700
701 var previousTab = tabList.querySelector("[aria-selected]");
702 previousTab.removeAttribute("aria-selected");
703 previousTab.setAttribute("tabindex", -1);
704
705 var tab = tabList.querySelector("li[data-tab='" + tabId + "']");
706 tab.setAttribute("aria-selected", true);
707 tab.setAttribute("tabindex", 0);
708
709 var tabContentId = tab.getAttribute("aria-controls");
710 var tabContent = document.getElementById(tabContentId);
711
712 // Select sub tabs
713 if (tab.hasAttribute("data-subtab"))
714 selectTabItem(tab.getAttribute("data-subtab"), tabContent, false);
715
716 if (tab && focus)
717 tab.focus();
718
719 return tabContent;
720 }
721
722 function onHashChange()
723 {
724 var hash = location.hash.substr(1);
725 if (!hash)
726 return;
727
728 // Select tab and parent tabs
729 var tabIds = hash.split("-");
730 var tabContent = document.body;
731 for (var i = 0; i < tabIds.length; i++)
732 {
733 var tabId = tabIds.slice(0, i + 1).join("-");
734 tabContent = selectTabItem(tabId, tabContent, true);
735 if (!tabContent)
736 break;
626 } 737 }
627 } 738 }
628 739
629 function onDOMLoaded() 740 function onDOMLoaded()
630 { 741 {
631 populateLists(); 742 populateLists();
632 function onFindLanguageKeyUp() 743 function onFindLanguageKeyUp()
633 { 744 {
634 var searchStyle = E("search-style"); 745 var searchStyle = E("search-style");
635 if (!this.value) 746 if (!this.value)
636 searchStyle.innerHTML = ""; 747 searchStyle.innerHTML = "";
637 else 748 else
638 searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + this .value.toLowerCase() + "\"]) { display: none; }"; 749 searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + this .value.toLowerCase() + "\"]) { display: none; }";
639 } 750 }
640 751
641 function getKey(e)
642 {
643 // e.keyCode has been deprecated so we attempt to use e.key
644 if ("key" in e)
645 return e.key;
646 return getKey.keys[e.keyCode];
647 }
648 getKey.keys = {
649 9: "Tab",
650 13: "Enter",
651 27: "Escape"
652 };
653
654 // Initialize navigation sidebar 752 // Initialize navigation sidebar
655 ext.backgroundPage.sendMessage( 753 ext.backgroundPage.sendMessage(
656 { 754 {
657 type: "app.get", 755 type: "app.get",
658 what: "addonVersion" 756 what: "addonVersion"
659 }, 757 },
660 function(addonVersion) 758 function(addonVersion)
661 { 759 {
662 E("abp-version").textContent = addonVersion; 760 E("abp-version").textContent = addonVersion;
663 }); 761 });
664 getDocLink("releases", function(link) 762 getDocLink("releases", function(link)
665 { 763 {
666 E("link-version").setAttribute("href", link); 764 E("link-version").setAttribute("href", link);
667 }); 765 });
668 766
669 getDocLink("contribute", function(link)
670 {
671 document.querySelector("#tab-contribute a").setAttribute("href", link);
672 });
673
674 updateShareLink(); 767 updateShareLink();
675 updateTooltips(); 768 updateTooltips();
676 769
677 // Initialize interactive UI elements 770 // Initialize interactive UI elements
678 document.body.addEventListener("click", onClick, false); 771 document.body.addEventListener("click", onClick, false);
772 document.body.addEventListener("keyup", onKeyUp, false);
679 var placeholderValue = getMessage("options_dialog_language_find"); 773 var placeholderValue = getMessage("options_dialog_language_find");
680 E("find-language").setAttribute("placeholder", placeholderValue); 774 E("find-language").setAttribute("placeholder", placeholderValue);
681 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); 775 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
682 E("whitelisting-textbox").addEventListener("keypress", function(e) 776 E("whitelisting-textbox").addEventListener("keypress", function(e)
683 { 777 {
684 if (getKey(e) == "Enter") 778 if (getKey(e) == "Enter")
685 addWhitelistedDomain(); 779 addWhitelistedDomain();
686 }, false); 780 }, false);
687 781
688 // Advanced tab 782 // Advanced tab
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 } 850 }
757 } 851 }
758 else if (e.target.classList.contains("focus-last")) 852 else if (e.target.classList.contains("focus-last"))
759 { 853 {
760 e.preventDefault(); 854 e.preventDefault();
761 this.querySelector(".focus-first").focus(); 855 this.querySelector(".focus-first").focus();
762 } 856 }
763 break; 857 break;
764 } 858 }
765 }, false); 859 }, false);
860
861 onHashChange();
766 } 862 }
767 863
768 var focusedBeforeDialog = null; 864 var focusedBeforeDialog = null;
769 function openDialog(name) 865 function openDialog(name)
770 { 866 {
771 var dialog = E("dialog"); 867 var dialog = E("dialog");
772 dialog.setAttribute("aria-hidden", false); 868 dialog.setAttribute("aria-hidden", false);
773 dialog.setAttribute("aria-labelledby", "dialog-title-" + name); 869 dialog.setAttribute("aria-labelledby", "dialog-title-" + name);
774 document.body.setAttribute("data-dialog", name); 870 document.body.setAttribute("data-dialog", name);
775 871
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 collections.whitelist.removeItem(knownFilter); 1007 collections.whitelist.removeItem(knownFilter);
912 collections.customFilters.removeItem(knownFilter); 1008 collections.customFilters.removeItem(knownFilter);
913 delete filtersMap[filter.text]; 1009 delete filtersMap[filter.text];
914 updateShareLink(); 1010 updateShareLink();
915 break; 1011 break;
916 } 1012 }
917 } 1013 }
918 1014
919 function onSubscriptionMessage(action, subscription) 1015 function onSubscriptionMessage(action, subscription)
920 { 1016 {
921 var knownSubscription = subscriptionsMap[subscription.url]; 1017 if (subscription.url in subscriptionsMap)
Thomas Greiner 2016/06/16 11:09:33 I'd prefer not having to deal with two different v
saroyanm 2016/06/16 13:35:48 Very good point!
922 if (knownSubscription) 1018 {
923 { 1019 var knownSubscription = subscriptionsMap[subscription.url];
924 for (var property in subscription) 1020 for (var property in subscription)
925 { 1021 {
926 if (property == "title" && knownSubscription.recommended) 1022 if (property == "title" && knownSubscription.recommended)
927 knownSubscription.originalTitle = subscription.title; 1023 knownSubscription.originalTitle = subscription.title;
928 else 1024 else
929 knownSubscription[property] = subscription[property]; 1025 knownSubscription[property] = subscription[property];
930 } 1026 }
931 } 1027 subscription = knownSubscription;
932 1028 }
933 switch (action) 1029 switch (action)
934 { 1030 {
935 case "disabled": 1031 case "disabled":
936 updateSubscription(knownSubscription); 1032 updateSubscription(subscription);
937 updateLanguageCollections(knownSubscription);
938 break; 1033 break;
939 case "downloading": 1034 case "downloading":
940 case "downloadStatus": 1035 case "downloadStatus":
941 case "homepage": 1036 case "homepage":
942 case "lastDownload": 1037 case "lastDownload":
943 case "title": 1038 case "title":
944 updateSubscription(knownSubscription); 1039 updateSubscription(subscription);
945 break; 1040 break;
946 case "added": 1041 case "added":
947 if (knownSubscription) 1042 if (subscription.url in subscriptionsMap)
948 updateLanguageCollections(knownSubscription); 1043 updateSubscription(subscription);
949 else 1044 else
950 addSubscription(subscription); 1045 addSubscription(subscription);
951 1046
952 subscription = updateSubscription(knownSubscription || subscription); 1047 collections.filterLists.addItem(subscription);
953 collections.filterLists.addItems(knownSubscription || subscription);
954 break; 1048 break;
955 case "removed": 1049 case "removed":
956 if (subscription.url == acceptableAdsUrl || knownSubscription.recommende d) 1050 if (subscription.url == acceptableAdsUrl || subscription.recommended)
957 { 1051 {
958 subscription.disabled = true; 1052 subscription.disabled = true;
959 onSubscriptionMessage("disabled", subscription); 1053 onSubscriptionMessage("disabled", subscription);
960 } 1054 }
961 else 1055 else
962 { 1056 {
963 collections.custom.removeItem(knownSubscription); 1057 collections.custom.removeItem(subscription);
964 delete subscriptionsMap[subscription.url]; 1058 delete subscriptionsMap[subscription.url];
965 } 1059 }
966 collections.filterLists.removeItem(knownSubscription); 1060 collections.filterLists.removeItem(subscription);
967 break; 1061 break;
968 } 1062 }
969 1063
970 updateShareLink(); 1064 updateShareLink();
971 } 1065 }
972 1066
973 function hidePref(key, value) 1067 function hidePref(key, value)
974 { 1068 {
975 var element = document.querySelector("[data-pref='" + key + "']"); 1069 var element = document.querySelector("[data-pref='" + key + "']");
976 if (element) 1070 if (element)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 break; 1116 break;
1023 1117
1024 case "safari_contentblocker": 1118 case "safari_contentblocker":
1025 E("restart-safari").setAttribute("aria-hidden", value || initial); 1119 E("restart-safari").setAttribute("aria-hidden", value || initial);
1026 break; 1120 break;
1027 } 1121 }
1028 1122
1029 var checkbox = document.querySelector("[data-pref='" + key + "'] button[role ='checkbox']"); 1123 var checkbox = document.querySelector("[data-pref='" + key + "'] button[role ='checkbox']");
1030 if (checkbox) 1124 if (checkbox)
1031 checkbox.setAttribute("aria-checked", value); 1125 checkbox.setAttribute("aria-checked", value);
1032 }
1033
1034 function onShareLinkClick(e)
1035 {
1036 e.preventDefault();
1037
1038 getDocLink("share-general", openSharePopup);
1039 } 1126 }
1040 1127
1041 function updateShareLink() 1128 function updateShareLink()
1042 { 1129 {
1043 var shareResources = [ 1130 var shareResources = [
1044 "https://facebook.com/plugins/like.php?", 1131 "https://facebook.com/plugins/like.php?",
1045 "https://platform.twitter.com/widgets/", 1132 "https://platform.twitter.com/widgets/",
1046 "https://apis.google.com/se/0/_/+1/fastbutton?" 1133 "https://apis.google.com/se/0/_/+1/fastbutton?"
1047 ]; 1134 ];
1048 var isAnyBlocked = false; 1135 var isAnyBlocked = false;
1049 var checksRemaining = shareResources.length; 1136 var checksRemaining = shareResources.length;
1050 1137
1051 function onResult(isBlocked) 1138 function onResult(isBlocked)
1052 { 1139 {
1053 isAnyBlocked |= isBlocked; 1140 isAnyBlocked |= isBlocked;
1054 if (!--checksRemaining) 1141 if (!--checksRemaining)
1055 { 1142 {
1056 // Hide the share tab if a script on the share page would be blocked 1143 // Hide the share tab if a script on the share page would be blocked
1057 var tab = E("tab-share"); 1144 E("tab-share").hidden = isAnyBlocked;
1058 if (isAnyBlocked)
1059 {
1060 tab.hidden = true;
1061 tab.removeEventListener("click", onShareLinkClick, false);
1062 }
1063 else
1064 tab.addEventListener("click", onShareLinkClick, false);
1065 } 1145 }
1066 } 1146 }
1067 1147
1068 for (var i = 0; i < shareResources.length; i++) 1148 for (var i = 0; i < shareResources.length; i++)
1069 checkShareResource(shareResources[i], onResult); 1149 checkShareResource(shareResources[i], onResult);
1070 } 1150 }
1071 1151
1072 function getMessages(id) 1152 function getMessages(id)
1073 { 1153 {
1074 var messages = []; 1154 var messages = [];
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 "shouldShowBlockElementMenu"] 1276 "shouldShowBlockElementMenu"]
1197 }); 1277 });
1198 ext.backgroundPage.sendMessage( 1278 ext.backgroundPage.sendMessage(
1199 { 1279 {
1200 type: "subscriptions.listen", 1280 type: "subscriptions.listen",
1201 filter: ["added", "disabled", "homepage", "lastDownload", "removed", 1281 filter: ["added", "disabled", "homepage", "lastDownload", "removed",
1202 "title", "downloadStatus", "downloading"] 1282 "title", "downloadStatus", "downloading"]
1203 }); 1283 });
1204 1284
1205 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); 1285 window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
1286 window.addEventListener("hashchange", onHashChange, false);
1206 })(); 1287 })();
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld