Bug 1175858 - Tracking Protection shield should be animated in when content is blocked on the page;r=MattN

--HG--
extra : commitid : ALRSvWjuFe7
This commit is contained in:
Brian Grinstead 2015-07-23 13:55:32 -07:00
Родитель f8675f433b
Коммит 15d13d435f
7 изменённых файлов: 153 добавлений и 7 удалений

Просмотреть файл

@ -53,11 +53,19 @@ let TrackingProtection = {
return Services.telemetry.getHistogramById("TRACKING_PROTECTION_EVENTS"); return Services.telemetry.getHistogramById("TRACKING_PROTECTION_EVENTS");
}, },
onSecurityChange(state) { onSecurityChange(state, isSimulated) {
if (!this.enabled) { if (!this.enabled) {
return; return;
} }
// Only animate the shield if the event was not fired directly from
// the tabbrowser (due to a browser change).
if (isSimulated) {
this.icon.removeAttribute("animate");
} else {
this.icon.setAttribute("animate", "true");
}
let { let {
STATE_BLOCKED_TRACKING_CONTENT, STATE_LOADED_TRACKING_CONTENT STATE_BLOCKED_TRACKING_CONTENT, STATE_LOADED_TRACKING_CONTENT
} = Ci.nsIWebProgressListener; } = Ci.nsIWebProgressListener;

Просмотреть файл

@ -4009,7 +4009,7 @@ var XULBrowserWindow = {
init: function () { init: function () {
// Initialize the security button's state and tooltip text. // Initialize the security button's state and tooltip text.
var securityUI = gBrowser.securityUI; var securityUI = gBrowser.securityUI;
this.onSecurityChange(null, null, securityUI.state); this.onSecurityChange(null, null, securityUI.state, true);
}, },
setJSStatus: function () { setJSStatus: function () {
@ -4357,7 +4357,13 @@ var XULBrowserWindow = {
_state: null, _state: null,
_lastLocation: null, _lastLocation: null,
onSecurityChange: function (aWebProgress, aRequest, aState) { // This is called in multiple ways:
// 1. Due to the nsIWebProgressListener.onSecurityChange notification.
// 2. Called by tabbrowser.xml when updating the current browser.
// 3. Called directly during this object's initializations.
// aRequest will be null always in case 2 and 3, and sometimes in case 1 (for
// instance, there won't be a request when STATE_BLOCKED_TRACKING_CONTENT is observed).
onSecurityChange: function (aWebProgress, aRequest, aState, aIsSimulated) {
// Don't need to do anything if the data we use to update the UI hasn't // Don't need to do anything if the data we use to update the UI hasn't
// changed // changed
let uri = gBrowser.currentURI; let uri = gBrowser.currentURI;
@ -4368,6 +4374,10 @@ var XULBrowserWindow = {
this._state = aState; this._state = aState;
this._lastLocation = spec; this._lastLocation = spec;
if (typeof(aIsSimulated) != "boolean" && typeof(aIsSimulated) != "undefined") {
throw "onSecurityChange: aIsSimulated receieved an unexpected type";
}
// aState is defined as a bitmask that may be extended in the future. // aState is defined as a bitmask that may be extended in the future.
// We filter out any unknown bits before testing for known values. // We filter out any unknown bits before testing for known values.
const wpl = Components.interfaces.nsIWebProgressListener; const wpl = Components.interfaces.nsIWebProgressListener;
@ -4403,7 +4413,7 @@ var XULBrowserWindow = {
uri = Services.uriFixup.createExposableURI(uri); uri = Services.uriFixup.createExposableURI(uri);
} catch (e) {} } catch (e) {}
gIdentityHandler.checkIdentity(this._state, uri); gIdentityHandler.checkIdentity(this._state, uri);
TrackingProtection.onSecurityChange(this._state); TrackingProtection.onSecurityChange(this._state, aIsSimulated);
}, },
// simulate all change notifications after switching tabs // simulate all change notifications after switching tabs

Просмотреть файл

@ -1100,8 +1100,11 @@
false); false);
if (securityUI) { if (securityUI) {
// Include the true final argument to indicate that this event is
// simulated (instead of being observed by the webProgressListener).
this._callProgressListeners(null, "onSecurityChange", this._callProgressListeners(null, "onSecurityChange",
[webProgress, null, securityUI.state], true, false); [webProgress, null, securityUI.state, true],
true, false);
} }
var listener = this.mTabListeners[this.tabContainer.selectedIndex] || null; var listener = this.mTabListeners[this.tabContainer.selectedIndex] || null;

Просмотреть файл

@ -424,6 +424,8 @@ support-files =
benignPage.html benignPage.html
[browser_trackingUI_3.js] [browser_trackingUI_3.js]
tags = trackingprotection tags = trackingprotection
[browser_trackingUI_4.js]
tags = trackingprotection
support-files = support-files =
trackingPage.html trackingPage.html
benignPage.html benignPage.html

Просмотреть файл

@ -33,7 +33,8 @@ function hidden(sel) {
let win = browser.ownerGlobal; let win = browser.ownerGlobal;
let el = win.document.querySelector(sel); let el = win.document.querySelector(sel);
let display = win.getComputedStyle(el).getPropertyValue("display", null); let display = win.getComputedStyle(el).getPropertyValue("display", null);
return display === "none"; let opacity = win.getComputedStyle(el).getPropertyValue("opacity", null);
return display === "none" || opacity === "0";
} }
function clickButton(sel) { function clickButton(sel) {

Просмотреть файл

@ -0,0 +1,111 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Test that the Tracking Protection icon is properly animated in the identity
// block when loading tabs and switching between tabs.
// See also Bug 1175858.
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const PREF = "privacy.trackingprotection.enabled";
const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
let TrackingProtection = null;
let browser = null;
let {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
registerCleanupFunction(function() {
TrackingProtection = browser = null;
UrlClassifierTestUtils.cleanupTestTrackers();
Services.prefs.clearUserPref(PREF);
Services.prefs.clearUserPref(PB_PREF);
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
});
function waitForSecurityChange(numChanges = 1) {
return new Promise(resolve => {
let n = 0;
let listener = {
onSecurityChange: function() {
n = n + 1;
info ("Recieved onSecurityChange event " + n + " of " + numChanges);
if (n >= numChanges) {
browser.removeProgressListener(listener);
resolve();
}
}
};
browser.addProgressListener(listener);
});
}
function* testTrackingProtectionAnimation() {
info("Load a test page not containing tracking elements");
let benignTab = yield BrowserTestUtils.openNewForegroundTab(browser, BENIGN_PAGE);
ok (!TrackingProtection.icon.hasAttribute("state"), "icon: no state");
ok (TrackingProtection.icon.hasAttribute("animate"), "icon: animate");
info("Load a test page containing tracking elements");
let trackingTab = yield BrowserTestUtils.openNewForegroundTab(browser, TRACKING_PAGE);
ok (TrackingProtection.icon.hasAttribute("state"), "icon: state");
ok (TrackingProtection.icon.hasAttribute("animate"), "icon: animate");
info("Switch from tracking -> benign tab");
let securityChanged = waitForSecurityChange();
browser.selectedTab = benignTab;
yield securityChanged;
ok (!TrackingProtection.icon.hasAttribute("state"), "icon: no state");
ok (!TrackingProtection.icon.hasAttribute("animate"), "icon: no animate");
info("Switch from benign -> tracking tab");
securityChanged = waitForSecurityChange();
browser.selectedTab = trackingTab;
yield securityChanged;
ok (TrackingProtection.icon.hasAttribute("state"), "icon: state");
ok (!TrackingProtection.icon.hasAttribute("animate"), "icon: no animate");
info("Reload tracking tab");
securityChanged = waitForSecurityChange(2);
browser.reload();
yield securityChanged;
ok (TrackingProtection.icon.hasAttribute("state"), "icon: state");
ok (TrackingProtection.icon.hasAttribute("animate"), "icon: animate");
}
add_task(function* testNormalBrowsing() {
yield UrlClassifierTestUtils.addTestTrackers();
browser = gBrowser;
TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
ok (TrackingProtection, "TP is attached to the browser window");
Services.prefs.setBoolPref(PREF, true);
ok (TrackingProtection.enabled, "TP is enabled after setting the pref");
yield testTrackingProtectionAnimation();
});
add_task(function* testPrivateBrowsing() {
let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
browser = privateWin.gBrowser;
TrackingProtection = browser.ownerGlobal.TrackingProtection;
ok (TrackingProtection, "TP is attached to the private window");
Services.prefs.setBoolPref(PB_PREF, true);
ok (TrackingProtection.enabled, "TP is enabled after setting the pref");
yield testTrackingProtectionAnimation();
privateWin.close();
});

Просмотреть файл

@ -27,6 +27,7 @@
font-size: .9em; font-size: .9em;
padding: 2px 5px; padding: 2px 5px;
margin-inline-end: 4px; margin-inline-end: 4px;
overflow: hidden;
} }
#identity-box:hover, #identity-box:hover,
@ -89,14 +90,24 @@
height: 16px; height: 16px;
margin-inline-end: 2px; margin-inline-end: 2px;
list-style-image: url(chrome://browser/skin/tracking-protection-16.svg); list-style-image: url(chrome://browser/skin/tracking-protection-16.svg);
margin-left: 0;
opacity: 1;
} }
#tracking-protection-icon[state="loaded-tracking-content"] { #tracking-protection-icon[state="loaded-tracking-content"] {
list-style-image: url(chrome://browser/skin/tracking-protection-disabled-16.svg); list-style-image: url(chrome://browser/skin/tracking-protection-disabled-16.svg);
} }
#tracking-protection-icon[animate] {
transition: margin-left 200ms ease-out;
}
#tracking-protection-icon:not([state]) { #tracking-protection-icon:not([state]) {
display: none; margin-left: -16px;
pointer-events: none;
opacity: 0;
/* Only animate the shield in, when it disappears hide it immediately. */
transition: none;
} }
/* MAIN IDENTITY ICON */ /* MAIN IDENTITY ICON */