| Index: new-options.js |
| =================================================================== |
| --- a/new-options.js |
| +++ b/new-options.js |
| @@ -25,6 +25,7 @@ |
| let filtersMap = Object.create(null); |
| let collections = Object.create(null); |
| let acceptableAdsUrl = null; |
| + let acceptableAdsPrivacyUrl = null; |
| let isCustomFiltersLoaded = false; |
| let {getMessage} = ext.i18n; |
| let customFilters = []; |
| @@ -83,8 +84,6 @@ |
| Collection.prototype._getItemTitle = function(item, i) |
| { |
| - if (item.url == acceptableAdsUrl) |
| - return getMessage("options_acceptableAds_description"); |
| if (this.details[i].useOriginalTitle && item.originalTitle) |
| return item.originalTitle; |
| return item.title || item.url || item.text; |
| @@ -98,9 +97,9 @@ |
| // disabled, but only be removed. That way it's grouped together with |
| // the "Own filter list" which cannot be disabled either at the bottom |
| // of the filter lists in the Advanced tab. |
| - if (a.url == acceptableAdsUrl) |
| + if (isAcceptableAds(a.url)) |
| return 1; |
| - if (b.url == acceptableAdsUrl) |
| + if (isAcceptableAds(b.url)) |
| return -1; |
| // Make sure that newly added entries always appear on top in descending |
| @@ -134,12 +133,15 @@ |
| listItem.setAttribute("data-access", item.url || item.text); |
| listItem.setAttribute("role", "section"); |
| - let label = listItem.querySelector(".display"); |
| - if (item.recommended && label.hasAttribute("data-tooltip")) |
| + let tooltip = listItem.querySelector("[data-tooltip]"); |
| + if (tooltip) |
| { |
| - let tooltipId = label.getAttribute("data-tooltip"); |
| + let tooltipId = tooltip.getAttribute("data-tooltip"); |
| tooltipId = tooltipId.replace("%value%", item.recommended); |
| - label.setAttribute("data-tooltip", tooltipId); |
| + if (getMessage(tooltipId)) |
| + { |
| + tooltip.setAttribute("data-tooltip", tooltipId); |
| + } |
| } |
| for (let control of listItem.querySelectorAll(".control")) |
| @@ -214,7 +216,10 @@ |
| continue; |
| let title = this._getItemTitle(item, i); |
| - element.querySelector(".display").textContent = title; |
| + let displays = element.querySelectorAll(".display"); |
| + for (let j = 0; j < displays.length; j++) |
| + displays[j].textContent = title; |
| + |
| element.setAttribute("aria-label", title); |
| if (this.details[i].searchable) |
| element.setAttribute("data-search", title.toLowerCase()); |
| @@ -222,7 +227,7 @@ |
| if (control) |
| { |
| control.setAttribute("aria-checked", item.disabled == false); |
| - if (item.url == acceptableAdsUrl && this == collections.filterLists) |
| + if (isAcceptableAds(item.url) && this == collections.filterLists) |
| control.disabled = true; |
| } |
| @@ -330,31 +335,21 @@ |
| return true; |
| } |
| - collections.popular = new Collection([ |
| + collections.protection = new Collection([ |
| { |
| - id: "recommend-list-table" |
| + id: "recommend-protection-list-table" |
| } |
| ]); |
| collections.langs = new Collection([ |
| { |
| id: "blocking-languages-table", |
| - emptyText: ["options_dialog_language_added_empty"] |
| - }, |
| - { |
| - id: "blocking-languages-dialog-table", |
| - emptyText: ["options_dialog_language_added_empty"] |
| + emptyText: ["options_language_empty"] |
| } |
| ]); |
| collections.allLangs = new Collection([ |
| { |
| - id: "all-lang-table", |
| - emptyText: ["options_dialog_language_other_empty"], |
| - searchable: true |
| - } |
| - ]); |
| - collections.acceptableAds = new Collection([ |
| - { |
| - id: "acceptableads-table" |
| + id: "all-lang-table-add", |
| + emptyText: ["options_dialog_language_other_empty"] |
| } |
| ]); |
| collections.custom = new Collection([ |
| @@ -375,43 +370,32 @@ |
| } |
| ]); |
| - function toggleShowLanguage(subscription) |
| + function addSubscription(subscription) |
| { |
| - if (subscription.recommended == "ads") |
| + let collection = null; |
| + if (subscription.recommended) |
| { |
| - if (subscription.disabled) |
| + if (subscription.recommended == "ads") |
| { |
| + if (subscription.disabled == false) |
| + collection = collections.langs; |
| + |
| collections.allLangs.addItem(subscription); |
| - collections.langs.removeItem(subscription); |
| } |
| else |
| { |
| - collections.allLangs.removeItem(subscription); |
| - collections.langs.addItem(subscription); |
| + collection = collections.protection; |
| } |
| } |
| - } |
| + else if (!isAcceptableAds(subscription.url)) |
| + { |
| + collection = collections.custom; |
| + } |
| - function addSubscription(subscription) |
| - { |
| - let collection; |
| - if (subscription.recommended) |
| - { |
| - if (subscription.recommended != "ads") |
| - collection = collections.popular; |
| - else if (subscription.disabled == false) |
| - collection = collections.langs; |
| - else |
| - collection = collections.allLangs; |
| - } |
| - else if (subscription.url == acceptableAdsUrl) |
| - collection = collections.acceptableAds; |
| - else |
| - collection = collections.custom; |
| + if (collection) |
| + collection.addItem(subscription); |
| - collection.addItem(subscription); |
| subscriptionsMap[subscription.url] = subscription; |
| - toggleShowLanguage(subscription); |
| updateTooltips(); |
| } |
| @@ -420,7 +404,25 @@ |
| for (let name in collections) |
| collections[name].updateItem(subscription); |
| - toggleShowLanguage(subscription); |
| + if (subscription.recommended == "ads") |
| + { |
| + if (subscription.disabled) |
| + collections.langs.removeItem(subscription); |
| + else |
| + collections.langs.addItem(subscription); |
| + } |
| + else if (!subscription.recommended && !isAcceptableAds(subscription.url)) |
| + { |
| + if (subscription.disabled == false) |
| + { |
| + collections.custom.addItem(subscription); |
| + updateTooltips(); |
| + } |
| + else |
| + { |
| + collections.custom.removeItem(subscription); |
| + } |
| + } |
| } |
| function updateFilter(filter) |
| @@ -561,6 +563,25 @@ |
| case "cancel-custom-filters": |
| setCustomFiltersView("read"); |
| break; |
| + case "change-language-subscription": |
| + for (let key in subscriptionsMap) |
| + { |
| + let subscription = subscriptionsMap[key]; |
| + let subscriptionType = subscription.recommended; |
| + if (subscriptionType == "ads" && subscription.disabled == false) |
| + { |
| + ext.backgroundPage.sendMessage({ |
| + type: "subscriptions.remove", |
| + url: subscription.url |
| + }); |
| + ext.backgroundPage.sendMessage({ |
| + type: "subscriptions.add", |
| + url: findParentData(element, "access", false) |
| + }); |
| + break; |
| + } |
| + } |
| + break; |
| case "close-dialog": |
| closeDialog(); |
| break; |
| @@ -612,6 +633,18 @@ |
| setCustomFiltersView("read"); |
| }); |
| break; |
| + case "switch-acceptable-ads": |
| + let {value} = element; |
| + ext.backgroundPage.sendMessage({ |
| + type: value == "privacy" ? "subscriptions.add" : |
| + "subscriptions.remove", |
| + url: acceptableAdsPrivacyUrl |
| + }); |
| + ext.backgroundPage.sendMessage({ |
| + type: value == "ads" ? "subscriptions.add" : "subscriptions.remove", |
| + url: acceptableAdsUrl |
| + }); |
| + break; |
| case "switch-tab": |
| let tabId = findParentData(element, "tab", false); |
| switchTab(tabId); |
| @@ -788,17 +821,6 @@ |
| function onDOMLoaded() |
| { |
| populateLists(); |
| - function onFindLanguageKeyUp() |
| - { |
| - let searchStyle = E("search-style"); |
| - if (!this.value) |
| - searchStyle.innerHTML = ""; |
| - else |
| - { |
| - searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + |
| - this.value.toLowerCase() + "\"]) { display: none; }"; |
| - } |
| - } |
| // Initialize navigation sidebar |
| ext.backgroundPage.sendMessage({ |
| @@ -820,9 +842,6 @@ |
| // Initialize interactive UI elements |
| document.body.addEventListener("click", onClick, false); |
| document.body.addEventListener("keyup", onKeyUp, false); |
| - let placeholderValue = getMessage("options_dialog_language_find"); |
| - E("find-language").setAttribute("placeholder", placeholderValue); |
| - E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); |
| let exampleValue = getMessage("options_whitelist_placeholder_example", |
| ["www.example.com"]); |
| E("whitelisting-textbox").setAttribute("placeholder", exampleValue); |
| @@ -831,6 +850,11 @@ |
| E("whitelisting-add-button").disabled = !e.target.value; |
| }, false); |
| + getDocLink("acceptable_ads_criteria", (link) => |
| + { |
| + setLinks("enable-aa-description", link); |
| + }); |
| + |
| // Advanced tab |
| let customize = document.querySelectorAll("#customize li[data-pref]"); |
| customize = Array.prototype.map.call(customize, (checkbox) => |
| @@ -969,6 +993,29 @@ |
| focusedBeforeDialog.focus(); |
| } |
| + function setAcceptableAds() |
| + { |
| + let option = "none"; |
| + document.forms["acceptable-ads"].classList.remove("show-dnt-notification"); |
| + if (acceptableAdsUrl in subscriptionsMap) |
| + { |
| + option = "ads"; |
| + } |
| + else if (acceptableAdsPrivacyUrl in subscriptionsMap) |
| + { |
| + option = "privacy"; |
| + |
| + if (!navigator.doNotTrack) |
| + document.forms["acceptable-ads"].classList.add("show-dnt-notification"); |
| + } |
| + document.forms["acceptable-ads"]["acceptable-ads"].value = option; |
| + } |
| + |
| + function isAcceptableAds(url) |
| + { |
| + return url == acceptableAdsUrl || url == acceptableAdsPrivacyUrl; |
| + } |
| + |
| function populateLists() |
| { |
| subscriptionsMap = Object.create(null); |
| @@ -1014,15 +1061,24 @@ |
| disabled: true |
| }); |
| - // Load user subscriptions |
| ext.backgroundPage.sendMessage({ |
| - type: "subscriptions.get", |
| - downloadable: true |
| + type: "prefs.get", |
| + key: "subscriptions_exceptionsurl_privacy" |
| }, |
| - (subscriptions) => |
| + (urlPrivacy) => |
| { |
| - for (let subscription of subscriptions) |
| - onSubscriptionMessage("added", subscription); |
| + acceptableAdsPrivacyUrl = urlPrivacy; |
| + |
| + // Load user subscriptions |
| + ext.backgroundPage.sendMessage({ |
| + type: "subscriptions.get", |
| + downloadable: true |
| + }, |
| + (subscriptions) => |
| + { |
| + for (let subscription of subscriptions) |
| + onSubscriptionMessage("added", subscription); |
| + }); |
| }); |
| }); |
| } |
| @@ -1130,18 +1186,28 @@ |
| else |
| addSubscription(subscription); |
| + if (isAcceptableAds(subscription.url)) |
| + setAcceptableAds(); |
| + |
| collections.filterLists.addItem(subscription); |
| break; |
| case "removed": |
| - if (subscription.url == acceptableAdsUrl || subscription.recommended) |
| + if (subscription.recommended) |
| { |
| subscription.disabled = true; |
| onSubscriptionMessage("disabled", subscription); |
| } |
| else |
| { |
| - collections.custom.removeItem(subscription); |
| delete subscriptionsMap[subscription.url]; |
| + if (isAcceptableAds(subscription.url)) |
| + { |
| + setAcceptableAds(); |
| + } |
| + else |
| + { |
| + collections.custom.removeItem(subscription); |
| + } |
| } |
| collections.filterLists.removeItem(subscription); |
| break; |
| @@ -1232,20 +1298,6 @@ |
| checkShareResource(sharedResource, onResult); |
| } |
| - function getMessages(id) |
| - { |
| - let messages = []; |
| - for (let i = 1; true; i++) |
| - { |
| - let message = ext.i18n.getMessage(id + "_" + i); |
| - if (!message) |
| - break; |
| - |
| - messages.push(message); |
| - } |
| - return messages; |
| - } |
| - |
| function updateTooltips() |
| { |
| let anchors = document.querySelectorAll(":not(.tooltip) > [data-tooltip]"); |
| @@ -1258,52 +1310,12 @@ |
| anchor.parentNode.replaceChild(wrapper, anchor); |
| wrapper.appendChild(anchor); |
| - let topTexts = getMessages(id); |
| - let bottomTexts = getMessages(id + "_notes"); |
| - |
| - // We have to use native tooltips to avoid issues when attaching a tooltip |
| - // to an element in a scrollable list or otherwise it might get cut off |
| - if (anchor.hasAttribute("data-tooltip-native")) |
| - { |
| - let title = topTexts.concat(bottomTexts).join("\n\n"); |
| - anchor.setAttribute("title", title); |
| - continue; |
| - } |
| - |
| let tooltip = document.createElement("div"); |
| tooltip.setAttribute("role", "tooltip"); |
| - let flip = anchor.getAttribute("data-tooltip-flip"); |
| - if (flip) |
| - tooltip.className = "flip-" + flip; |
| - |
| - let imageSource = anchor.getAttribute("data-tooltip-image"); |
| - if (imageSource) |
| - { |
| - let image = document.createElement("img"); |
| - image.src = imageSource; |
| - image.alt = ""; |
| - tooltip.appendChild(image); |
| - } |
| - |
| - for (let topText of topTexts) |
| - { |
| - let paragraph = document.createElement("p"); |
| - paragraph.innerHTML = topText; |
| - tooltip.appendChild(paragraph); |
| - } |
| - if (bottomTexts.length > 0) |
| - { |
| - let notes = document.createElement("div"); |
| - notes.className = "notes"; |
| - for (let bottomText of bottomTexts) |
| - { |
| - let paragraph = document.createElement("p"); |
| - paragraph.innerHTML = bottomText; |
| - notes.appendChild(paragraph); |
| - } |
| - tooltip.appendChild(notes); |
| - } |
| + let paragraph = document.createElement("p"); |
| + paragraph.textContent = getMessage(id); |
| + tooltip.appendChild(paragraph); |
| wrapper.appendChild(tooltip); |
| } |