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: Merged updateLanguageCollections function Created June 21, 2016, 12:42 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 ]);
333
334 function toggleShowLanguage(subscription)
335 {
336 if (subscription.recommended == "ads")
337 {
338 if (subscription.disabled)
339 {
340 collections.allLangs.addItem(subscription);
341 collections.langs.removeItem(subscription);
342 }
343 else
344 {
345 collections.allLangs.removeItem(subscription);
346 collections.langs.addItem(subscription);
347 }
348 }
349 }
393 350
394 function addSubscription(subscription) 351 function addSubscription(subscription)
395 { 352 {
396 var collection; 353 var collection;
397 if (subscription.recommended) 354 if (subscription.recommended)
398 { 355 {
399 if (subscription.recommended != "ads") 356 if (subscription.recommended != "ads")
400 collection = collections.popular; 357 collection = collections.popular;
401 else if (subscription.disabled == false) 358 else if (subscription.disabled == false)
402 collection = collections.langs; 359 collection = collections.langs;
403 else 360 else
404 collection = collections.allLangs; 361 collection = collections.allLangs;
405 } 362 }
406 else if (subscription.url == acceptableAdsUrl) 363 else if (subscription.url == acceptableAdsUrl)
407 collection = collections.acceptableAds; 364 collection = collections.acceptableAds;
408 else 365 else
409 collection = collections.custom; 366 collection = collections.custom;
410 367
411 collection.addItems(subscription); 368 collection.addItem(subscription);
412 subscriptionsMap[subscription.url] = subscription; 369 subscriptionsMap[subscription.url] = subscription;
370 toggleShowLanguage(subscription);
413 updateTooltips(); 371 updateTooltips();
414 } 372 }
415 373
416 function updateSubscription(subscription) 374 function updateSubscription(subscription)
417 { 375 {
418 for (var name in collections) 376 for (var name in collections)
419 collections[name].updateItem(subscription); 377 collections[name].updateItem(subscription);
378
379 toggleShowLanguage(subscription);
420 } 380 }
421 381
422 function updateFilter(filter) 382 function updateFilter(filter)
423 { 383 {
424 var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/); 384 var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/);
425 if (match && !filtersMap[filter.text]) 385 if (match && !filtersMap[filter.text])
426 { 386 {
427 filter.title = match[1]; 387 filter.title = match[1];
428 collections.whitelist.addItems(filter); 388 collections.whitelist.addItem(filter);
429 } 389 }
430 else 390 else
431 collections.customFilters.addItems(filter); 391 collections.customFilters.addItem(filter);
432 392
433 filtersMap[filter.text] = filter; 393 filtersMap[filter.text] = filter;
434 } 394 }
435 395
436 function loadRecommendations() 396 function loadRecommendations()
437 { 397 {
438 fetch("subscriptions.xml") 398 fetch("subscriptions.xml")
439 .then(function(response) 399 .then(function(response)
440 { 400 {
441 return response.text(); 401 return response.text();
442 }) 402 })
443 .then(function(text) 403 .then(function(text)
444 { 404 {
445 var list = document.getElementById("subscriptionSelector"); 405 var list = document.getElementById("subscriptionSelector");
446 var doc = new DOMParser().parseFromString(text, "application/xml"); 406 var doc = new DOMParser().parseFromString(text, "application/xml");
447 var elements = doc.documentElement.getElementsByTagName("subscription"); 407 var elements = doc.documentElement.getElementsByTagName("subscription");
448 for (var i = 0; i < elements.length; i++) 408 for (var i = 0; i < elements.length; i++)
449 { 409 {
450 var element = elements[i]; 410 var element = elements[i];
451 var type = element.getAttribute("type"); 411 var type = element.getAttribute("type");
452 var subscription = { 412 var subscription = {
453 disabled: null, 413 disabled: true,
454 downloadStatus: null, 414 downloadStatus: null,
455 homepage: null, 415 homepage: null,
456 originalTitle: element.getAttribute("title"), 416 originalTitle: element.getAttribute("title"),
457 recommended: type, 417 recommended: type,
458 url: element.getAttribute("url") 418 url: element.getAttribute("url")
459 }; 419 };
460 420
461 var prefix = element.getAttribute("prefixes"); 421 var prefix = element.getAttribute("prefixes");
462 if (prefix) 422 if (prefix)
463 { 423 {
(...skipping 27 matching lines...) Expand all
491 { 451 {
492 ext.backgroundPage.sendMessage(message, function(errors) 452 ext.backgroundPage.sendMessage(message, function(errors)
493 { 453 {
494 if (errors.length > 0) 454 if (errors.length > 0)
495 alert(errors.join("\n")); 455 alert(errors.join("\n"));
496 else if (onSuccess) 456 else if (onSuccess)
497 onSuccess(); 457 onSuccess();
498 }); 458 });
499 } 459 }
500 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
501 function onClick(e) 477 function onClick(e)
502 { 478 {
503 var context = document.querySelector(".show-context-menu"); 479 var context = document.querySelector(".show-context-menu");
504 if (context) 480 if (context)
505 context.classList.remove("show-context-menu"); 481 context.classList.remove("show-context-menu");
506 482
507 var element = e.target; 483 var element = e.target;
508 while (true) 484 while (true)
509 { 485 {
510 if (!element) 486 if (!element)
511 return; 487 return;
512 488
513 if (element.hasAttribute("data-action")) 489 if (element.hasAttribute("data-action"))
514 break; 490 break;
515 491
516 element = element.parentElement; 492 element = element.parentElement;
517 } 493 }
518 494
495 var element = findParentData(e.target, "action", true);
519 var actions = element.getAttribute("data-action").split(","); 496 var actions = element.getAttribute("data-action").split(",");
520 for (var i = 0; i < actions.length; i++) 497 for (var i = 0; i < actions.length; i++)
521 { 498 {
522 switch (actions[i]) 499 switch (actions[i])
523 { 500 {
524 case "add-domain-exception": 501 case "add-domain-exception":
525 addWhitelistedDomain(); 502 addWhitelistedDomain();
526 break; 503 break;
527 case "add-predefined-subscription": 504 case "add-predefined-subscription":
528 var dialog = E("dialog-content-predefined"); 505 var dialog = E("dialog-content-predefined");
(...skipping 19 matching lines...) Expand all
548 case "edit-domain-exception": 525 case "edit-domain-exception":
549 document.querySelector("#whitelisting .controls").classList.add("mode- edit"); 526 document.querySelector("#whitelisting .controls").classList.add("mode- edit");
550 E("whitelisting-textbox").focus(); 527 E("whitelisting-textbox").focus();
551 break; 528 break;
552 case "import-subscription": 529 case "import-subscription":
553 var url = E("blockingList-textbox").value; 530 var url = E("blockingList-textbox").value;
554 addEnableSubscription(url); 531 addEnableSubscription(url);
555 closeDialog(); 532 closeDialog();
556 break; 533 break;
557 case "open-dialog": 534 case "open-dialog":
558 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);
559 break; 541 break;
560 case "save-custom-filters": 542 case "save-custom-filters":
561 sendMessageHandleErrors( 543 sendMessageHandleErrors(
562 { 544 {
563 type: "filters.importRaw", 545 type: "filters.importRaw",
564 text: E("custom-filters-raw").value, 546 text: E("custom-filters-raw").value,
565 removeExisting: true 547 removeExisting: true
566 }, 548 },
567 function() 549 function()
568 { 550 {
569 E("custom-filters").classList.remove("mode-edit"); 551 E("custom-filters").classList.remove("mode-edit");
570 }); 552 });
571 break; 553 break;
572 case "switch-tab": 554 case "switch-tab":
573 document.body.setAttribute("data-tab", 555 var tabId = findParentData(e.target, "tab", false);
574 element.getAttribute("data-tab")); 556 switchTab(tabId);
575 break; 557 break;
576 case "toggle-pref": 558 case "toggle-pref":
577 ext.backgroundPage.sendMessage( 559 ext.backgroundPage.sendMessage(
578 { 560 {
579 type: "prefs.toggle", 561 type: "prefs.toggle",
580 key: findParentData(element, "pref", false) 562 key: findParentData(element, "pref", false)
581 }); 563 });
582 break; 564 break;
583 case "update-all-subscriptions": 565 case "update-all-subscriptions":
584 ext.backgroundPage.sendMessage( 566 ext.backgroundPage.sendMessage(
(...skipping 13 matching lines...) Expand all
598 url: findParentData(element, "access", false) 580 url: findParentData(element, "access", false)
599 }); 581 });
600 break; 582 break;
601 case "remove-subscription": 583 case "remove-subscription":
602 ext.backgroundPage.sendMessage( 584 ext.backgroundPage.sendMessage(
603 { 585 {
604 type: "subscriptions.remove", 586 type: "subscriptions.remove",
605 url: findParentData(element, "access", false) 587 url: findParentData(element, "access", false)
606 }); 588 });
607 break; 589 break;
608 } 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;
609 } 737 }
610 } 738 }
611 739
612 function onDOMLoaded() 740 function onDOMLoaded()
613 { 741 {
614 populateLists(); 742 populateLists();
615 function onFindLanguageKeyUp() 743 function onFindLanguageKeyUp()
616 { 744 {
617 var searchStyle = E("search-style"); 745 var searchStyle = E("search-style");
618 if (!this.value) 746 if (!this.value)
619 searchStyle.innerHTML = ""; 747 searchStyle.innerHTML = "";
620 else 748 else
621 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; }";
622 } 750 }
623 751
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 };
636
637 // Initialize navigation sidebar 752 // Initialize navigation sidebar
638 ext.backgroundPage.sendMessage( 753 ext.backgroundPage.sendMessage(
639 { 754 {
640 type: "app.get", 755 type: "app.get",
641 what: "addonVersion" 756 what: "addonVersion"
642 }, 757 },
643 function(addonVersion) 758 function(addonVersion)
644 { 759 {
645 E("abp-version").textContent = addonVersion; 760 E("abp-version").textContent = addonVersion;
646 }); 761 });
647 getDocLink("releases", function(link) 762 getDocLink("releases", function(link)
648 { 763 {
649 E("link-version").setAttribute("href", link); 764 E("link-version").setAttribute("href", link);
650 }); 765 });
651 766
652 getDocLink("contribute", function(link)
653 {
654 document.querySelector("#tab-contribute a").setAttribute("href", link);
655 });
656
657 updateShareLink(); 767 updateShareLink();
658 updateTooltips(); 768 updateTooltips();
659 769
660 // Initialize interactive UI elements 770 // Initialize interactive UI elements
661 document.body.addEventListener("click", onClick, false); 771 document.body.addEventListener("click", onClick, false);
772 document.body.addEventListener("keyup", onKeyUp, false);
662 var placeholderValue = getMessage("options_dialog_language_find"); 773 var placeholderValue = getMessage("options_dialog_language_find");
663 E("find-language").setAttribute("placeholder", placeholderValue); 774 E("find-language").setAttribute("placeholder", placeholderValue);
664 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); 775 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
665 E("whitelisting-textbox").addEventListener("keypress", function(e) 776 E("whitelisting-textbox").addEventListener("keypress", function(e)
666 { 777 {
667 if (getKey(e) == "Enter") 778 if (getKey(e) == "Enter")
668 addWhitelistedDomain(); 779 addWhitelistedDomain();
669 }, false); 780 }, false);
670 781
671 // Advanced tab 782 // Advanced tab
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 } 850 }
740 } 851 }
741 else if (e.target.classList.contains("focus-last")) 852 else if (e.target.classList.contains("focus-last"))
742 { 853 {
743 e.preventDefault(); 854 e.preventDefault();
744 this.querySelector(".focus-first").focus(); 855 this.querySelector(".focus-first").focus();
745 } 856 }
746 break; 857 break;
747 } 858 }
748 }, false); 859 }, false);
860
861 onHashChange();
749 } 862 }
750 863
751 var focusedBeforeDialog = null; 864 var focusedBeforeDialog = null;
752 function openDialog(name) 865 function openDialog(name)
753 { 866 {
754 var dialog = E("dialog"); 867 var dialog = E("dialog");
755 dialog.setAttribute("aria-hidden", false); 868 dialog.setAttribute("aria-hidden", false);
756 dialog.setAttribute("aria-labelledby", "dialog-title-" + name); 869 dialog.setAttribute("aria-labelledby", "dialog-title-" + name);
757 document.body.setAttribute("data-dialog", name); 870 document.body.setAttribute("data-dialog", name);
758 871
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 if (property == "title" && knownSubscription.recommended) 1022 if (property == "title" && knownSubscription.recommended)
910 knownSubscription.originalTitle = subscription.title; 1023 knownSubscription.originalTitle = subscription.title;
911 else 1024 else
912 knownSubscription[property] = subscription[property]; 1025 knownSubscription[property] = subscription[property];
913 } 1026 }
914 subscription = knownSubscription; 1027 subscription = knownSubscription;
915 } 1028 }
916 switch (action) 1029 switch (action)
917 { 1030 {
918 case "disabled": 1031 case "disabled":
919 if (subscription.recommended == "ads")
920 {
921 if (subscription.disabled == true)
922 {
923 collections.allLangs.addItems(subscription);
924 collections.langs.removeItem(subscription);
925 }
926 else
927 {
928 collections.allLangs.removeItem(subscription);
929 collections.langs.addItems(subscription);
930 }
931 }
932 updateSubscription(subscription); 1032 updateSubscription(subscription);
933 break; 1033 break;
934 case "downloading": 1034 case "downloading":
935 case "downloadStatus": 1035 case "downloadStatus":
936 case "homepage": 1036 case "homepage":
937 case "lastDownload": 1037 case "lastDownload":
938 case "title": 1038 case "title":
939 updateSubscription(subscription); 1039 updateSubscription(subscription);
940 break; 1040 break;
941 case "added": 1041 case "added":
942 if (subscription.recommended == "ads") 1042 if (subscription.url in subscriptionsMap)
943 {
944 collections.allLangs.removeItem(subscription);
Thomas Greiner 2016/06/22 10:08:04 The subscription might be disabled when it's added
saroyanm 2016/06/22 12:31:59 Well spotted, done
945 collections.langs.addItems(subscription);
946 }
947 else if (subscription.url in subscriptionsMap)
948 updateSubscription(subscription); 1043 updateSubscription(subscription);
949 else 1044 else
950 addSubscription(subscription); 1045 addSubscription(subscription);
951 1046
952 collections.filterLists.addItems(subscription); 1047 collections.filterLists.addItem(subscription);
953 break; 1048 break;
954 case "removed": 1049 case "removed":
955 if (subscription.url == acceptableAdsUrl || subscription.recommended) 1050 if (subscription.url == acceptableAdsUrl || subscription.recommended)
956 { 1051 {
957 subscription.disabled = true; 1052 subscription.disabled = true;
958 onSubscriptionMessage("disabled", subscription); 1053 onSubscriptionMessage("disabled", subscription);
959 } 1054 }
960 else 1055 else
961 { 1056 {
962 collections.custom.removeItem(subscription); 1057 collections.custom.removeItem(subscription);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 break; 1116 break;
1022 1117
1023 case "safari_contentblocker": 1118 case "safari_contentblocker":
1024 E("restart-safari").setAttribute("aria-hidden", value || initial); 1119 E("restart-safari").setAttribute("aria-hidden", value || initial);
1025 break; 1120 break;
1026 } 1121 }
1027 1122
1028 var checkbox = document.querySelector("[data-pref='" + key + "'] button[role ='checkbox']"); 1123 var checkbox = document.querySelector("[data-pref='" + key + "'] button[role ='checkbox']");
1029 if (checkbox) 1124 if (checkbox)
1030 checkbox.setAttribute("aria-checked", value); 1125 checkbox.setAttribute("aria-checked", value);
1031 }
1032
1033 function onShareLinkClick(e)
1034 {
1035 e.preventDefault();
1036
1037 getDocLink("share-general", openSharePopup);
1038 } 1126 }
1039 1127
1040 function updateShareLink() 1128 function updateShareLink()
1041 { 1129 {
1042 var shareResources = [ 1130 var shareResources = [
1043 "https://facebook.com/plugins/like.php?", 1131 "https://facebook.com/plugins/like.php?",
1044 "https://platform.twitter.com/widgets/", 1132 "https://platform.twitter.com/widgets/",
1045 "https://apis.google.com/se/0/_/+1/fastbutton?" 1133 "https://apis.google.com/se/0/_/+1/fastbutton?"
1046 ]; 1134 ];
1047 var isAnyBlocked = false; 1135 var isAnyBlocked = false;
1048 var checksRemaining = shareResources.length; 1136 var checksRemaining = shareResources.length;
1049 1137
1050 function onResult(isBlocked) 1138 function onResult(isBlocked)
1051 { 1139 {
1052 isAnyBlocked |= isBlocked; 1140 isAnyBlocked |= isBlocked;
1053 if (!--checksRemaining) 1141 if (!--checksRemaining)
1054 { 1142 {
1055 // 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
1056 var tab = E("tab-share"); 1144 E("tab-share").hidden = isAnyBlocked;
1057 if (isAnyBlocked)
1058 {
1059 tab.hidden = true;
1060 tab.removeEventListener("click", onShareLinkClick, false);
1061 }
1062 else
1063 tab.addEventListener("click", onShareLinkClick, false);
1064 } 1145 }
1065 } 1146 }
1066 1147
1067 for (var i = 0; i < shareResources.length; i++) 1148 for (var i = 0; i < shareResources.length; i++)
1068 checkShareResource(shareResources[i], onResult); 1149 checkShareResource(shareResources[i], onResult);
1069 } 1150 }
1070 1151
1071 function getMessages(id) 1152 function getMessages(id)
1072 { 1153 {
1073 var messages = []; 1154 var messages = [];
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 "shouldShowBlockElementMenu"] 1276 "shouldShowBlockElementMenu"]
1196 }); 1277 });
1197 ext.backgroundPage.sendMessage( 1278 ext.backgroundPage.sendMessage(
1198 { 1279 {
1199 type: "subscriptions.listen", 1280 type: "subscriptions.listen",
1200 filter: ["added", "disabled", "homepage", "lastDownload", "removed", 1281 filter: ["added", "disabled", "homepage", "lastDownload", "removed",
1201 "title", "downloadStatus", "downloading"] 1282 "title", "downloadStatus", "downloading"]
1202 }); 1283 });
1203 1284
1204 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); 1285 window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
1286 window.addEventListener("hashchange", onHashChange, false);
1205 })(); 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