| Index: options.js |
| =================================================================== |
| --- a/options.js |
| +++ b/options.js |
| @@ -10,738 +10,27 @@ |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| -/* global $, i18n, i18nTimeDateStrings */ |
| - |
| "use strict"; |
| -/** |
| - * Creates a wrapping function used to conveniently send a type of message. |
| - * |
| - * @param {Object} baseMessage The part of the message that's always sent |
| - * @param {...string} paramKeys Any message keys that have dynamic values. The |
| - * returned function will take the corresponding |
| - * values as arguments. |
| - * @return {function} The generated messaging function, optionally |
| - * taking any values as specified by the paramKeys |
| - * and finally an optional callback. (Although the |
| - * value arguments are optional their index must be |
| - * maintained. E.g. if you omit the first value you |
| - * must omit the second too.) |
| - */ |
| -function wrapper(baseMessage, ...paramKeys) |
| -{ |
| - return function(...paramValues /* , callback */) |
| - { |
| - let message = Object.assign(Object.create(null), baseMessage); |
| - let callback; |
| - |
| - if (paramValues.length > 0) |
| - { |
| - let lastArg = paramValues[paramValues.length - 1]; |
| - if (typeof lastArg == "function") |
| - callback = lastArg; |
| - |
| - for (let i = 0; i < paramValues.length - (callback ? 1 : 0); i++) |
| - message[paramKeys[i]] = paramValues[i]; |
| - } |
| - |
| - ext.backgroundPage.sendMessage(message, callback); |
| - }; |
| -} |
| - |
| -const getDocLink = wrapper({type: "app.get", what: "doclink"}, "link"); |
| -const getInfo = wrapper({type: "app.get"}, "what"); |
| -const getPref = wrapper({type: "prefs.get"}, "key"); |
| -const togglePref = wrapper({type: "prefs.toggle"}, "key"); |
| -const getSubscriptions = wrapper({type: "subscriptions.get"}, |
| - "downloadable", "special"); |
| -const removeSubscription = wrapper({type: "subscriptions.remove"}, "url"); |
| -const addSubscription = wrapper({type: "subscriptions.add"}, |
| - "url", "title", "homepage"); |
| -const toggleSubscription = wrapper({type: "subscriptions.toggle"}, |
| - "url", "keepInstalled"); |
| -const updateSubscription = wrapper({type: "subscriptions.update"}, "url"); |
| -const importRawFilters = wrapper({type: "filters.importRaw"}, |
| - "text", "removeExisting"); |
| -const addFilter = wrapper({type: "filters.add"}, "text"); |
| -const removeFilter = wrapper({type: "filters.remove"}, "text"); |
| -const quoteCSS = wrapper({type: "composer.quoteCSS"}, "CSS"); |
| - |
| -const whitelistedDomainRegexp = /^@@\|\|([^/:]+)\^\$document$/; |
| -const statusMessages = new Map([ |
| - ["synchronize_invalid_url", |
| - "filters_subscription_lastDownload_invalidURL"], |
| - ["synchronize_connection_error", |
| - "filters_subscription_lastDownload_connectionError"], |
| - ["synchronize_invalid_data", |
| - "filters_subscription_lastDownload_invalidData"], |
| - ["synchronize_checksum_mismatch", |
| - "filters_subscription_lastDownload_checksumMismatch"] |
| -]); |
| - |
| -let delayedSubscriptionSelection = null; |
| -let acceptableAdsUrl; |
| - |
| -// Loads options from localStorage and sets UI elements accordingly |
| -function loadOptions() |
| -{ |
| - // Set page title to i18n version of "Adblock Plus Options" |
| - document.title = i18n.getMessage("options"); |
| +let iframe = document.getElementById("content"); |
| - // Set links |
| - getPref("subscriptions_exceptionsurl", url => |
| - { |
| - acceptableAdsUrl = url; |
| - $("#acceptableAdsLink").attr("href", acceptableAdsUrl); |
| - }); |
| - getDocLink("acceptable_ads", url => |
| - { |
| - $("#acceptableAdsDocs").attr("href", url); |
| - }); |
| - getDocLink("filterdoc", url => |
| - { |
| - setLinks("filter-must-follow-syntax", url); |
| - }); |
| - getInfo("application", application => |
| - { |
| - getInfo("platform", platform => |
| - { |
| - if (platform == "chromium" && application != "opera") |
| - application = "chrome"; |
| - |
| - getDocLink(application + "_support", url => |
| - { |
| - setLinks("found-a-bug", url); |
| - }); |
| - |
| - if (platform == "gecko") |
| - $("#firefox-warning").removeAttr("hidden"); |
| - }); |
| - }); |
| - |
| - // Add event listeners |
| - $("#updateFilterLists").click(updateFilterLists); |
| - $("#startSubscriptionSelection").click(startSubscriptionSelection); |
| - $("#subscriptionSelector").change(updateSubscriptionSelection); |
| - $("#addSubscription").click(addSubscriptionClicked); |
| - $("#acceptableAds").click(toggleAcceptableAds); |
| - $("#whitelistForm").submit(addWhitelistDomain); |
| - $("#removeWhitelist").click(removeSelectedExcludedDomain); |
| - $("#customFilterForm").submit(addTypedFilter); |
| - $("#removeCustomFilter").click(removeSelectedFilters); |
| - $("#rawFiltersButton").click(toggleFiltersInRawFormat); |
| - $("#importRawFilters").click(importRawFiltersText); |
| - |
| - // Display jQuery UI elements |
| - $("#tabs").tabs(); |
| - $("button:not(.subscriptionRemoveButton)").button(); |
| - $(".refreshButton").button("option", "icons", {primary: "ui-icon-refresh"}); |
| - $(".addButton").button("option", "icons", {primary: "ui-icon-plus"}); |
| - $(".removeButton").button("option", "icons", {primary: "ui-icon-minus"}); |
| - |
| - // Popuplate option checkboxes |
| - initCheckbox("shouldShowBlockElementMenu"); |
| - initCheckbox("show_devtools_panel"); |
| - initCheckbox("shouldShowNotifications", "notifications_ignoredcategories"); |
| - |
| - getInfo("features", features => |
| - { |
| - if (!features.devToolsPanel) |
| - document.getElementById("showDevtoolsPanelContainer").hidden = true; |
| - }); |
| - getPref("notifications_showui", showNotificationsUI => |
| - { |
| - if (!showNotificationsUI) |
| - document.getElementById("shouldShowNotificationsContainer").hidden = true; |
| - }); |
| - |
| - // Register listeners in the background message responder |
| - ext.backgroundPage.sendMessage({ |
| - type: "app.listen", |
| - filter: ["addSubscription", "focusSection"] |
| - }); |
| - ext.backgroundPage.sendMessage({ |
| - type: "filters.listen", |
| - filter: ["added", "loaded", "removed"] |
| - }); |
| - ext.backgroundPage.sendMessage({ |
| - type: "prefs.listen", |
| - filter: ["notifications_ignoredcategories", "notifications_showui", |
| - "show_devtools_panel", "shouldShowBlockElementMenu"] |
| - }); |
| - ext.backgroundPage.sendMessage({ |
| - type: "subscriptions.listen", |
| - filter: ["added", "disabled", "homepage", "lastDownload", "removed", |
| - "title", "downloadStatus", "downloading"] |
| - }); |
| - |
| - // Load recommended subscriptions |
| - loadRecommendations(); |
| - |
| - // Show user's filters |
| - reloadFilters(); |
| -} |
| -$(loadOptions); |
| - |
| -function convertSpecialSubscription(subscription) |
| +iframe.onload = () => |
| { |
| - for (let filter of subscription.filters) |
| - { |
| - if (whitelistedDomainRegexp.test(filter.text)) |
| - appendToListBox("excludedDomainsBox", RegExp.$1); |
| - else |
| - appendToListBox("userFiltersBox", filter.text); |
| - } |
| -} |
| - |
| -// Reloads the displayed subscriptions and filters |
| -function reloadFilters() |
| -{ |
| - // Load user filter URLs |
| - let container = document.getElementById("filterLists"); |
| - while (container.lastChild) |
| - container.removeChild(container.lastChild); |
| - |
| - getSubscriptions(true, false, subscriptions => |
| - { |
| - for (let subscription of subscriptions) |
| - { |
| - if (subscription.url == acceptableAdsUrl) |
| - $("#acceptableAds").prop("checked", !subscription.disabled); |
| - else |
| - addSubscriptionEntry(subscription); |
| - } |
| - }); |
| - |
| - // User-entered filters |
| - getSubscriptions(false, true, subscriptions => |
| - { |
| - document.getElementById("userFiltersBox").innerHTML = ""; |
| - document.getElementById("excludedDomainsBox").innerHTML = ""; |
| - |
| - for (let subscription of subscriptions) |
| - convertSpecialSubscription(subscription); |
| - }); |
| -} |
| - |
| -function initCheckbox(id, key) |
| -{ |
| - key = key || id; |
| - let checkbox = document.getElementById(id); |
| - |
| - getPref(key, value => |
| - { |
| - onPrefMessage(key, value); |
| - }); |
| - |
| - checkbox.addEventListener("click", () => |
| - { |
| - togglePref(key); |
| - }, false); |
| -} |
| - |
| -function loadRecommendations() |
| -{ |
| - fetch("subscriptions.xml") |
| - .then(response => |
| - { |
| - return response.text(); |
| - }) |
| - .then(text => |
| - { |
| - let selectedIndex = 0; |
| - let selectedPrefix = null; |
| - let matchCount = 0; |
| - |
| - let list = document.getElementById("subscriptionSelector"); |
| - let doc = new DOMParser().parseFromString(text, "application/xml"); |
| - let elements = doc.documentElement.getElementsByTagName("subscription"); |
| - |
| - for (let i = 0; i < elements.length; i++) |
| - { |
| - let element = elements[i]; |
| - let option = new Option(); |
| - option.text = element.getAttribute("title") + " (" + |
| - element.getAttribute("specialization") + ")"; |
| - option._data = { |
| - title: element.getAttribute("title"), |
| - url: element.getAttribute("url"), |
| - homepage: element.getAttribute("homepage") |
| - }; |
| - |
| - let prefix = element.getAttribute("prefixes"); |
| - if (prefix) |
| - { |
| - prefix = prefix.replace(/\W/g, "_"); |
| - option.style.fontWeight = "bold"; |
| - option.style.backgroundColor = "#E0FFE0"; |
| - option.style.color = "#000000"; |
| - if (!selectedPrefix || selectedPrefix.length < prefix.length) |
| - { |
| - selectedIndex = i; |
| - selectedPrefix = prefix; |
| - matchCount = 1; |
| - } |
| - else if (selectedPrefix && selectedPrefix.length == prefix.length) |
| - { |
| - matchCount++; |
| - |
| - // If multiple items have a matching prefix of the same length: |
| - // Select one of the items randomly, probability should be the same |
| - // for all items. So we replace the previous match here with |
| - // probability 1/N (N being the number of matches). |
| - if (Math.random() * matchCount < 1) |
| - { |
| - selectedIndex = i; |
| - selectedPrefix = prefix; |
| - } |
| - } |
| - } |
| - list.appendChild(option); |
| - } |
| - |
| - let option = new Option(); |
| - let label = i18n.getMessage("filters_addSubscriptionOther_label"); |
| - option.text = label + "\u2026"; |
| - option._data = null; |
| - list.appendChild(option); |
| - |
| - list.selectedIndex = selectedIndex; |
| - |
| - if (delayedSubscriptionSelection) |
| - startSubscriptionSelection(...delayedSubscriptionSelection); |
| - }); |
| -} |
| - |
| -function startSubscriptionSelection(title, url) |
| -{ |
| - let list = document.getElementById("subscriptionSelector"); |
| - if (list.length == 0) |
| - { |
| - delayedSubscriptionSelection = [title, url]; |
| - return; |
| - } |
| - |
| - $("#tabs").tabs("option", "active", 0); |
| - $("#addSubscriptionContainer").show(); |
| - $("#addSubscriptionButton").hide(); |
| - $("#subscriptionSelector").focus(); |
| - if (typeof url != "undefined") |
| - { |
| - list.selectedIndex = list.length - 1; |
| - document.getElementById("customSubscriptionTitle").value = title; |
| - document.getElementById("customSubscriptionLocation").value = url; |
| - } |
| - updateSubscriptionSelection(); |
| - document.getElementById("addSubscriptionContainer").scrollIntoView(true); |
| -} |
| - |
| -function updateSubscriptionSelection() |
| -{ |
| - let list = document.getElementById("subscriptionSelector"); |
| - let data = list.options[list.selectedIndex]._data; |
| - if (data) |
| - $("#customSubscriptionContainer").hide(); |
| - else |
| - { |
| - $("#customSubscriptionContainer").show(); |
| - $("#customSubscriptionTitle").focus(); |
| - } |
| -} |
| - |
| -function addSubscriptionClicked() |
| -{ |
| - let list = document.getElementById("subscriptionSelector"); |
| - let data = list.options[list.selectedIndex]._data; |
| - if (data) |
| - addSubscription(data.url, data.title, data.homepage); |
| - else |
| - { |
| - let url = document.getElementById("customSubscriptionLocation") |
| - .value.trim(); |
| - if (!/^https?:/i.test(url)) |
| - { |
| - alert(i18n.getMessage("global_subscription_invalid_location")); |
| - $("#customSubscriptionLocation").focus(); |
| - return; |
| - } |
| - |
| - let title = document.getElementById("customSubscriptionTitle").value.trim(); |
| - if (!title) |
| - title = url; |
| - |
| - addSubscription(url, title, null); |
| - } |
| + document.title = iframe.contentDocument.title; |
| +}; |
| - $("#addSubscriptionContainer").hide(); |
| - $("#customSubscriptionContainer").hide(); |
| - $("#addSubscriptionButton").show(); |
| -} |
| - |
| -function toggleAcceptableAds() |
| -{ |
| - toggleSubscription(acceptableAdsUrl, true); |
| -} |
| - |
| -function findSubscriptionElement(subscription) |
| -{ |
| - for (let child of document.getElementById("filterLists").childNodes) |
| - { |
| - if (child._subscription.url == subscription.url) |
| - return child; |
| - } |
| - return null; |
| -} |
| - |
| -function updateSubscriptionInfo(element, subscription) |
| -{ |
| - if (subscription) |
| - element._subscription = subscription; |
| - else |
| - subscription = element._subscription; |
| - |
| - let title = element.getElementsByClassName("subscriptionTitle")[0]; |
| - title.textContent = subscription.title; |
| - title.setAttribute("title", subscription.url); |
| - if (subscription.homepage) |
| - title.href = subscription.homepage; |
| - else |
| - title.href = subscription.url; |
| - |
| - let enabled = element.getElementsByClassName("subscriptionEnabled")[0]; |
| - enabled.checked = !subscription.disabled; |
| - |
| - let lastUpdate = element.getElementsByClassName("subscriptionUpdate")[0]; |
| - lastUpdate.classList.remove("error"); |
| - |
| - let {downloadStatus} = subscription; |
| - if (subscription.isDownloading) |
| - { |
| - lastUpdate.textContent = i18n.getMessage( |
| - "filters_subscription_lastDownload_inProgress" |
| - ); |
| - } |
| - else if (downloadStatus && downloadStatus != "synchronize_ok") |
| - { |
| - if (statusMessages.has(downloadStatus)) |
| - { |
| - lastUpdate.textContent = i18n.getMessage( |
| - statusMessages.get(downloadStatus) |
| - ); |
| - } |
| - else |
| - lastUpdate.textContent = downloadStatus; |
| - lastUpdate.classList.add("error"); |
| - } |
| - else if (subscription.lastDownload > 0) |
| - { |
| - let timeDate = i18nTimeDateStrings(subscription.lastDownload * 1000); |
| - let messageID = (timeDate[1] ? "last_updated_at" : "last_updated_at_today"); |
| - lastUpdate.textContent = i18n.getMessage(messageID, timeDate); |
| - } |
| -} |
| - |
| -function onSubscriptionMessage(action, subscription) |
| -{ |
| - let element = findSubscriptionElement(subscription); |
| - |
| - switch (action) |
| - { |
| - case "disabled": |
| - case "downloading": |
| - case "downloadStatus": |
| - case "homepage": |
| - case "lastDownload": |
| - case "title": |
| - if (element) |
| - updateSubscriptionInfo(element, subscription); |
| - break; |
| - case "added": |
| - if (subscription.url.indexOf("~user") == 0) |
| - convertSpecialSubscription(subscription); |
| - else if (subscription.url == acceptableAdsUrl) |
| - $("#acceptableAds").prop("checked", true); |
| - else if (!element) |
| - addSubscriptionEntry(subscription); |
| - break; |
| - case "removed": |
| - if (subscription.url == acceptableAdsUrl) |
| - $("#acceptableAds").prop("checked", false); |
| - else if (element) |
| - element.parentNode.removeChild(element); |
| - break; |
| - } |
| -} |
| - |
| -function onPrefMessage(key, value) |
| -{ |
| - switch (key) |
| - { |
| - case "notifications_showui": |
| - document.getElementById( |
| - "shouldShowNotificationsContainer" |
| - ).hidden = !value; |
| - return; |
| - case "notifications_ignoredcategories": |
| - key = "shouldShowNotifications"; |
| - value = value.indexOf("*") == -1; |
| - break; |
| - } |
| - let checkbox = document.getElementById(key); |
| - if (checkbox) |
| - checkbox.checked = value; |
| -} |
| - |
| -function onFilterMessage(action, filter) |
| -{ |
| - switch (action) |
| - { |
| - case "loaded": |
| - reloadFilters(); |
| - break; |
| - case "added": |
| - if (whitelistedDomainRegexp.test(filter.text)) |
| - appendToListBox("excludedDomainsBox", RegExp.$1); |
| - else |
| - appendToListBox("userFiltersBox", filter.text); |
| - break; |
| - case "removed": |
| - if (whitelistedDomainRegexp.test(filter.text)) |
| - removeFromListBox("excludedDomainsBox", RegExp.$1); |
| - else |
| - removeFromListBox("userFiltersBox", filter.text); |
| - break; |
| - } |
| -} |
| - |
| -// Add a filter string to the list box. |
| -function appendToListBox(boxId, text) |
| -{ |
| - // Note: document.createElement("option") is unreliable in Opera |
| - let elt = new Option(); |
| - elt.text = text; |
| - elt.value = text; |
| - document.getElementById(boxId).appendChild(elt); |
| -} |
| - |
| -// Remove a filter string from a list box. |
| -function removeFromListBox(boxId, text) |
| -{ |
| - let list = document.getElementById(boxId); |
| - // Edge does not support CSS.escape yet: |
| - // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/101410/ |
| - quoteCSS(text, escapedCSS => |
| - { |
| - let selector = "option[value=" + escapedCSS + "]"; |
| - for (let option of list.querySelectorAll(selector)) |
| - list.removeChild(option); |
| - }); |
| -} |
| - |
| -function addWhitelistDomain(event) |
| -{ |
| - event.preventDefault(); |
| - |
| - let domain = document.getElementById( |
| - "newWhitelistDomain" |
| - ).value.replace(/\s/g, ""); |
| - document.getElementById("newWhitelistDomain").value = ""; |
| - if (!domain) |
| - return; |
| - |
| - let filterText = "@@||" + domain + "^$document"; |
| - addFilter(filterText); |
| -} |
| - |
| -// Adds filter text that user typed to the selection box |
| -function addTypedFilter(event) |
| +chrome.runtime.sendMessage({ |
| + type: "app.get", |
| + what: "application" |
| +}, |
| +application => |
| { |
| - event.preventDefault(); |
| - |
| - let element = document.getElementById("newFilter"); |
| - addFilter(element.value, errors => |
| - { |
| - if (errors.length > 0) |
| - alert(errors.join("\n")); |
| - else |
| - element.value = ""; |
| - }); |
| -} |
| - |
| -// Removes currently selected whitelisted domains |
| -function removeSelectedExcludedDomain(event) |
| -{ |
| - event.preventDefault(); |
| - let remove = []; |
| - for (let option of document.getElementById("excludedDomainsBox").options) |
| - { |
| - if (option.selected) |
| - remove.push(option.value); |
| - } |
| - if (!remove.length) |
| - return; |
| - |
| - for (let domain of remove) |
| - removeFilter("@@||" + domain + "^$document"); |
| -} |
| - |
| -// Removes all currently selected filters |
| -function removeSelectedFilters(event) |
| -{ |
| - event.preventDefault(); |
| - let options = document.querySelectorAll("#userFiltersBox > option:checked"); |
| - for (let option of options) |
| - removeFilter(option.value); |
| -} |
| - |
| -// Shows raw filters box and fills it with the current user filters |
| -function toggleFiltersInRawFormat(event) |
| -{ |
| - event.preventDefault(); |
| - |
| - let rawFilters = document.getElementById("rawFilters"); |
| - let filters = []; |
| - |
| - if (rawFilters.style.display != "table-row") |
| - { |
| - rawFilters.style.display = "table-row"; |
| - for (let option of document.getElementById("userFiltersBox").options) |
| - filters.push(option.value); |
| - } |
| - else |
| - { |
| - rawFilters.style.display = "none"; |
| - } |
| - |
| - document.getElementById("rawFiltersText").value = filters.join("\n"); |
| -} |
| - |
| -// Imports filters in the raw text box |
| -function importRawFiltersText() |
| -{ |
| - let text = document.getElementById("rawFiltersText").value; |
| - |
| - importRawFilters(text, true, errors => |
| - { |
| - if (errors.length > 0) |
| - alert(errors.join("\n")); |
| - else |
| - $("#rawFilters").hide(); |
| - }); |
| -} |
| - |
| -// Called when user explicitly requests filter list updates |
| -function updateFilterLists() |
| -{ |
| - // Without the URL parameter this will update all subscriptions |
| - updateSubscription(); |
| -} |
| - |
| -// Adds a subscription entry to the UI. |
| -function addSubscriptionEntry(subscription) |
| -{ |
| - let template = document.getElementById("subscriptionTemplate"); |
| - let element = template.cloneNode(true); |
| - element.removeAttribute("id"); |
| - element._subscription = subscription; |
| - |
| - let removeButton = element.getElementsByClassName( |
| - "subscriptionRemoveButton" |
| - )[0]; |
| - removeButton.setAttribute("title", removeButton.textContent); |
| - removeButton.textContent = "\xD7"; |
| - removeButton.addEventListener("click", () => |
| - { |
| - if (!confirm(i18n.getMessage("global_remove_subscription_warning"))) |
| - return; |
| - |
| - removeSubscription(subscription.url); |
| - }, false); |
| - |
| - getPref("additional_subscriptions", additionalSubscriptions => |
| - { |
| - if (additionalSubscriptions.includes(subscription.url)) |
| - removeButton.style.visibility = "hidden"; |
| - }); |
| - |
| - let enabled = element.getElementsByClassName("subscriptionEnabled")[0]; |
| - enabled.addEventListener("click", () => |
| - { |
| - subscription.disabled = !subscription.disabled; |
| - toggleSubscription(subscription.url, true); |
| - }, false); |
| - |
| - updateSubscriptionInfo(element); |
| - |
| - document.getElementById("filterLists").appendChild(element); |
| -} |
| - |
| -function setLinks(id, ...args) |
| -{ |
| - let element = document.getElementById(id); |
| - if (!element) |
| - return; |
| - |
| - let links = element.getElementsByTagName("a"); |
| - for (let i = 0; i < links.length; i++) |
| - { |
| - if (typeof args[i] == "string") |
| - { |
| - links[i].href = args[i]; |
| - links[i].setAttribute("target", "_blank"); |
| - } |
| - else if (typeof args[i] == "function") |
| - { |
| - links[i].href = "javascript:void(0);"; |
| - links[i].addEventListener("click", args[i], false); |
| - } |
| - } |
| -} |
| - |
| -ext.onMessage.addListener(message => |
| -{ |
| - switch (message.type) |
| - { |
| - case "app.respond": |
| - switch (message.action) |
| - { |
| - case "addSubscription": |
| - let subscription = message.args[0]; |
| - startSubscriptionSelection(subscription.title, subscription.url); |
| - break; |
| - case "focusSection": |
| - for (let tab of document.getElementsByClassName("ui-tabs-panel")) |
| - { |
| - let found = tab.querySelector( |
| - "[data-section='" + message.args[0] + "']" |
| - ); |
| - if (!found) |
| - continue; |
| - |
| - let previous = document.getElementsByClassName("focused"); |
| - if (previous.length > 0) |
| - previous[0].classList.remove("focused"); |
| - |
| - let index = $("[href='#" + tab.id + "']").parent().index(); |
| - $("#tabs").tabs("option", "active", index); |
| - found.classList.add("focused"); |
| - } |
| - break; |
| - } |
| - break; |
| - case "filters.respond": |
| - onFilterMessage(message.action, message.args[0]); |
| - break; |
| - case "prefs.respond": |
| - onPrefMessage(message.action, message.args[0]); |
| - break; |
| - case "subscriptions.respond": |
| - onSubscriptionMessage(message.action, message.args[0]); |
| - break; |
| - } |
| + // Load the mobile version of the options page on Firefox for Android. |
| + iframe.src = iframe.getAttribute("data-src-" + application) || |
| + iframe.getAttribute("data-src"); |
| }); |