diff --git a/src/js/background.js b/src/js/background.js index 791c42ddd7..d8b40ff418 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -25,6 +25,7 @@ var constants = require("constants"); var pbStorage = require("storage"); var HeuristicBlocking = require("heuristicblocking"); +var FirefoxAndroid = require("firefoxandroid"); var webrequest = require("webrequest"); var SocialWidgetLoader = require("socialwidgetloader"); window.SocialWidgetList = SocialWidgetLoader.loadSocialWidgetsFromFile("data/socialwidgets.json"); @@ -55,11 +56,9 @@ function Badger() { } // Show icon as page action for all tabs that already exist - chrome.windows.getAll({populate: true}, function (windows) { - for (var i = 0; i < windows.length; i++) { - for (var j = 0; j < windows[i].tabs.length; j++) { - badger.refreshIconAndContextMenu(windows[i].tabs[j]); - } + chrome.tabs.query({}, function (tabs) { + for (var i = 0; i < tabs.length; i++) { + badger.refreshIconAndContextMenu(tabs[i]); } }); @@ -532,6 +531,10 @@ Badger.prototype = { * @param {Integer} tabId chrome tab id */ updateBadge: function(tabId){ + if(FirefoxAndroid.isUsed){ + return; + } + if (!this.showCounter()){ chrome.browserAction.setBadgeText({tabId: tabId, text: ""}); return; @@ -603,7 +606,7 @@ Badger.prototype = { } return true; }, - + /** * Check if privacy badger is disabled, take an origin and * check against the disabledSites list @@ -745,7 +748,7 @@ Badger.prototype = { * @param {Object} tab The tab to set the badger icon for */ refreshIconAndContextMenu: function (tab) { - if (!tab) { + if (!tab || FirefoxAndroid.isUsed) { return; } @@ -763,7 +766,6 @@ Badger.prototype = { } chrome.browserAction.setIcon({tabId: tab.id, path: iconFilename}); - chrome.browserAction.setTitle({tabId: tab.id, title: "Privacy Badger"}); }, }; @@ -777,7 +779,6 @@ function startBackgroundListeners() { } }, {urls: ["http://*/*", "https://*/*"]}, []); - // Update icon if a tab changes location chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if(changeInfo.status == "loading") { @@ -827,6 +828,7 @@ var badger = window.badger = new Badger(); incognito.startListeners(); webrequest.startListeners(); HeuristicBlocking.startListeners(); +FirefoxAndroid.startListeners(); startBackgroundListeners(); // TODO move listeners and this message behind INITIALIZED diff --git a/src/js/firefoxandroid.js b/src/js/firefoxandroid.js new file mode 100644 index 0000000000..f5eaec890c --- /dev/null +++ b/src/js/firefoxandroid.js @@ -0,0 +1,89 @@ +/* + * This file is part of Privacy Badger + * Copyright (C) 2014 Electronic Frontier Foundation + * + * Privacy Badger is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Privacy Badger is distributed in the hope that it will be useful, + * 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 Privacy Badger. If not, see . + */ + + /* + * Temporary polyfill for firefox android, + * while it doesn't support the full browserAction API + * Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1330159 + */ + +require.scopes.firefoxandroid = (function() { +var isFirefoxAndroid = !( + chrome.browserAction.setBadgeText && + chrome.browserAction.setPopup && + chrome.browserAction.getPopup +); + +// keeps track of popup id while one is open +var openPopupId = false; +var popup_url = chrome.runtime.getManifest().browser_action.default_popup; + +// fakes a popup +function openPopup() { + chrome.tabs.query({active: true, lastFocusedWindow: true}, (tabs) => { + var url = popup_url + "?tabId=" + tabs[0].id; + chrome.tabs.create({url, index: tabs[0].index + 1}, (tab) => { + openPopupId = tab.id; + }); + }); +} + +// remove the 'popup' when another tab is activated +function onActivated(activeInfo) { + if(openPopupId != false && openPopupId != activeInfo.tabId) { + chrome.tabs.remove(openPopupId, () => { + openPopupId = false; + }); + } +} + +// forgets the popup when the url is overwritten by the user +function onUpdated(tabId, changeInfo, tab) { + if(tab.url && openPopupId == tabId){ + var new_url = new URL(tab.url); + + if(new_url.origin + new_url.pathname != popup_url){ + openPopupId = false; + } + } +} + +// Subscribe to events needed to fake a popup +function startListeners() { + if(isFirefoxAndroid){ + chrome.browserAction.onClicked.addListener(openPopup); + chrome.tabs.onActivated.addListener(onActivated); + chrome.tabs.onUpdated.addListener(onUpdated); + } +} + +// Used in popup.js, figures out which tab opened the 'fake' popup +function getParentOfPopup(callback){ + chrome.tabs.query({active: true, lastFocusedWindow: true}, function(focusedTab) { + var parentId = parseInt(new URL(focusedTab[0].url).searchParams.get('tabId')); + chrome.tabs.get(parentId, callback); + }); +} + +/************************************** exports */ +var exports = {}; +exports.startListeners = startListeners; +exports.isUsed = isFirefoxAndroid; +exports.getParentOfPopup = getParentOfPopup; +return exports; +/************************************** exports */ +})(); diff --git a/src/js/popup.js b/src/js/popup.js index 0a4ba55512..13e3b524e3 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -22,6 +22,7 @@ var backgroundPage = chrome.extension.getBackgroundPage(); var require = backgroundPage.require; var constants = backgroundPage.constants; var badger = backgroundPage.badger; +var FirefoxAndroid = backgroundPage.FirefoxAndroid; var htmlUtils = require("htmlutils").htmlUtils; var i18n = chrome.i18n; @@ -512,6 +513,12 @@ function syncUISelections() { * seems to be that it is synchronous. */ function getTab(callback) { + // Temporary fix for Firefox Android + if(FirefoxAndroid.isUsed){ + FirefoxAndroid.getParentOfPopup(callback); + return; + } + chrome.tabs.query({active: true, lastFocusedWindow: true}, function(t) { callback(t[0]); }); } diff --git a/src/manifest.json b/src/manifest.json index 98d4ef9add..cb88b0f5c1 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -38,6 +38,7 @@ "js/heuristicblocking.js", "js/socialwidgetloader.js", "js/migrations.js", + "js/firefoxandroid.js", "js/background.js" ] }, diff --git a/src/skin/options.html b/src/skin/options.html index b8a1f119d9..ec78443e6f 100644 --- a/src/skin/options.html +++ b/src/skin/options.html @@ -21,6 +21,7 @@ + diff --git a/src/skin/popup.css b/src/skin/popup.css index bfd9709527..cdae4ff735 100644 --- a/src/skin/popup.css +++ b/src/skin/popup.css @@ -18,17 +18,21 @@ /*csslint ids:ignore*/ body { - min-width: 200px; - max-width: 400px; + margin: 0; + min-width: 430px; /* Chrome */ + max-width: 100%; /* FF android */ font-size: 12px; background: #fefefe; color: #333; font-family: helvetica, arial, sans-serif; - padding-left: 7px; - padding-right: 7px; - overflow-y: hidden; - overflow-x: hidden; - width: 400px; + padding: 8px 15px; + box-sizing: border-box; +} +@media screen and (min--moz-device-pixel-ratio:0) { + body{ + min-width: 200px; /* FF android */ + width: 430px; /* FF desktop */ + } } a { text-decoration: none } @@ -218,11 +222,13 @@ font-size: 16px; max-height: 290px; overflow-y: auto; background-color: #E8E9EA; + position: relative; } .key { - position: fixed; + position: absolute; height: 25px; - width: 235px; + left: 0; + right: 0; z-index: 30; background: #fefefe; padding-top: 4px; @@ -325,6 +331,7 @@ font-size: 16px; z-index: -1; opacity: 0; padding: 3%; + box-sizing: border-box; color: #ccc; background: url("/skin/background.png"); transition: opacity .1s ease; diff --git a/src/tests/index.html b/src/tests/index.html index 0b31e3a517..4a7086a55d 100644 --- a/src/tests/index.html +++ b/src/tests/index.html @@ -55,6 +55,7 @@ +