Bug 1206229 - Inform the user that changes may require a page reload r?paolo
MozReview-Commit-ID: 3tJRhxeDnUb
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4468,16 +4468,18 @@ var XULBrowserWindow = {
} else {
this.reloadCommand.removeAttribute("disabled");
}
URLBarSetURI(aLocationURI);
BookmarkingUI.onLocationChange();
+ gIdentityHandler.onLocationChange();
+
SocialUI.updateState();
UITour.onLocationChange(location);
gTabletModePageCounter.inc();
// Utility functions for disabling find
var shouldDisableFind = function shouldDisableFind(aDocument) {
@@ -6546,16 +6548,21 @@ var gIdentityHandler = {
*/
_sslStatus: null,
/**
* Bitmask provided by nsIWebProgressListener.onSecurityChange.
*/
_state: 0,
+ /**
+ * Whether a permission is just removed from permission list.
+ */
+ _permissionJustRemoved: false,
+
get _isBroken() {
return this._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
},
get _isSecure() {
// If a <browser> is included within a chrome document, then this._state
// will refer to the security state for the <browser> and not the top level
// document. In this case, don't upgrade the security state in the UI
@@ -6672,16 +6679,24 @@ var gIdentityHandler = {
get _identityIcon () {
delete this._identityIcon;
return this._identityIcon = document.getElementById("identity-icon");
},
get _permissionList () {
delete this._permissionList;
return this._permissionList = document.getElementById("identity-popup-permission-list");
},
+ get _permissionEmptyHint() {
+ delete this._permissionEmptyHint;
+ return this._permissionEmptyHint = document.getElementById("identity-popup-permission-empty-hint");
+ },
+ get _permissionReloadHint () {
+ delete this._permissionReloadHint;
+ return this._permissionReloadHint = document.getElementById("identity-popup-permission-reload-hint");
+ },
get _permissionAnchors () {
delete this._permissionAnchors;
let permissionAnchors = {};
for (let anchor of document.getElementById("blocked-permissions-container").children) {
permissionAnchors[anchor.getAttribute("data-permission-id")] = anchor;
}
return this._permissionAnchors = permissionAnchors;
},
@@ -7291,16 +7306,35 @@ var gIdentityHandler = {
let dt = event.dataTransfer;
dt.setData("text/x-moz-url", urlString);
dt.setData("text/uri-list", value);
dt.setData("text/plain", value);
dt.setData("text/html", htmlString);
dt.setDragImage(this._identityIcon, 16, 16);
},
+ onLocationChange: function () {
+ this._permissionJustRemoved = false;
+ this.updatePermissionHint();
+ },
+
+ updatePermissionHint: function () {
+ if (!this._permissionList.hasChildNodes() && !this._permissionJustRemoved) {
+ this._permissionEmptyHint.removeAttribute("hidden");
+ } else {
+ this._permissionEmptyHint.setAttribute("hidden", "true");
+ }
+
+ if (this._permissionJustRemoved) {
+ this._permissionReloadHint.removeAttribute("hidden");
+ } else {
+ this._permissionReloadHint.setAttribute("hidden", "true");
+ }
+ },
+
updateSitePermissions: function () {
while (this._permissionList.hasChildNodes())
this._permissionList.removeChild(this._permissionList.lastChild);
let uri = gBrowser.currentURI;
let permissions = SitePermissions.getPermissionDetailsByURI(uri);
if (this._sharingState) {
@@ -7326,16 +7360,18 @@ var gIdentityHandler = {
}
}
}
}
for (let permission of permissions) {
let item = this._createPermissionItem(permission);
this._permissionList.appendChild(item);
}
+
+ this.updatePermissionHint();
},
_createPermissionItem: function (aPermission) {
let container = document.createElement("hbox");
container.setAttribute("class", "identity-popup-permission-item");
container.setAttribute("align", "center");
let img = document.createElement("image");
@@ -7380,16 +7416,18 @@ var gIdentityHandler = {
SitePermissions.remove(uri, id);
}
}
}
let mm = gBrowser.selectedBrowser.messageManager;
mm.sendAsyncMessage("webrtc:StopSharing", windowId);
}
SitePermissions.remove(gBrowser.currentURI, aPermission.id);
+ this._permissionJustRemoved = true;
+ this.updatePermissionHint();
});
container.appendChild(img);
container.appendChild(nameLabel);
container.appendChild(stateLabel);
container.appendChild(button);
return container;
--- a/browser/base/content/test/general/browser_permissions.js
+++ b/browser/base/content/test/general/browser_permissions.js
@@ -12,47 +12,68 @@ registerCleanupFunction(function() {
SitePermissions.remove(gBrowser.currentURI, "camera");
SitePermissions.remove(gBrowser.currentURI, "microphone");
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
});
+function* openIdentityPopup() {
+ let {gIdentityHandler} = gBrowser.ownerGlobal;
+ let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
+ gIdentityHandler._identityBox.click();
+ return promise;
+}
+
+function* closeIdentityPopup() {
+ let {gIdentityHandler} = gBrowser.ownerGlobal;
+ let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden");
+ gIdentityHandler._identityPopup.hidePopup();
+ return promise;
+}
+
add_task(function* testMainViewVisible() {
let {gIdentityHandler} = gBrowser.ownerGlobal;
let tab = gBrowser.selectedTab = gBrowser.addTab();
yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
let permissionsList = document.getElementById("identity-popup-permission-list");
let emptyLabel = permissionsList.nextSibling;
- gIdentityHandler._identityBox.click();
+ yield openIdentityPopup();
+
ok(!is_hidden(emptyLabel), "List of permissions is empty");
- gIdentityHandler._identityPopup.hidden = true;
+
+ yield closeIdentityPopup();
SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.ALLOW);
- gIdentityHandler._identityBox.click();
+ yield openIdentityPopup();
+
ok(is_hidden(emptyLabel), "List of permissions is not empty");
let labelText = SitePermissions.getPermissionLabel("camera");
let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
is(labels.length, 1, "One permission visible in main view");
is(labels[0].textContent, labelText, "Correct value");
let img = permissionsList.querySelector("image.identity-popup-permission-icon");
ok(img, "There is an image for the permissions");
ok(img.classList.contains("camera-icon"), "proper class is in image class");
+ yield closeIdentityPopup();
+
SitePermissions.remove(gBrowser.currentURI, "camera");
- gIdentityHandler._identityBox.click();
+ yield openIdentityPopup();
+
ok(!is_hidden(emptyLabel), "List of permissions is empty");
- gIdentityHandler._identityPopup.hidden = true;
+
+ yield closeIdentityPopup();
});
add_task(function* testIdentityIcon() {
let {gIdentityHandler} = gBrowser.ownerGlobal;
let tab = gBrowser.selectedTab = gBrowser.addTab();
yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
@@ -86,31 +107,77 @@ add_task(function* testCancelPermission(
yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
let permissionsList = document.getElementById("identity-popup-permission-list");
let emptyLabel = permissionsList.nextSibling;
SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK);
- gIdentityHandler._identityBox.click();
+ yield openIdentityPopup();
ok(is_hidden(emptyLabel), "List of permissions is not empty");
let cancelButtons = permissionsList
.querySelectorAll(".identity-popup-permission-remove-button");
cancelButtons[0].click();
let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
is(labels.length, 1, "One permission should be removed");
cancelButtons[1].click();
labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
is(labels.length, 0, "One permission should be removed");
- gIdentityHandler._identityPopup.hidden = true;
+ yield closeIdentityPopup();
+});
+
+add_task(function* testPermissionHints() {
+ let {gIdentityHandler} = gBrowser.ownerGlobal;
+ let tab = gBrowser.selectedTab = gBrowser.addTab();
+ yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
+
+ let permissionsList = document.getElementById("identity-popup-permission-list");
+ let emptyHint = document.getElementById("identity-popup-permission-empty-hint");
+ let reloadHint = document.getElementById("identity-popup-permission-reload-hint");
+
+ yield openIdentityPopup();
+
+ ok(!is_hidden(emptyHint), "Empty hint is visible");
+ ok(is_hidden(reloadHint), "Reload hint is hidden");
+
+ yield closeIdentityPopup();
+
+ SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
+ SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK);
+
+ yield openIdentityPopup();
+
+ ok(is_hidden(emptyHint), "Empty hint is hidden");
+ ok(is_hidden(reloadHint), "Reload hint is hidden");
+
+ let cancelButtons = permissionsList
+ .querySelectorAll(".identity-popup-permission-remove-button");
+ SitePermissions.remove(gBrowser.currentURI, "camera");
+
+ cancelButtons[0].click();
+ ok(is_hidden(emptyHint), "Empty hint is hidden");
+ ok(!is_hidden(reloadHint), "Reload hint is visible");
+
+ cancelButtons[1].click();
+ ok(is_hidden(emptyHint), "Empty hint is hidden");
+ ok(!is_hidden(reloadHint), "Reload hint is visible");
+
+ yield closeIdentityPopup();
+ yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
+ yield openIdentityPopup();
+
+ ok(!is_hidden(emptyHint), "Empty hint is visible after reloading");
+ ok(is_hidden(reloadHint), "Reload hint is hidden after reloading");
+
+ yield closeIdentityPopup();
});
add_task(function* testPermissionIcons() {
let {gIdentityHandler} = gBrowser.ownerGlobal;
let tab = gBrowser.selectedTab = gBrowser.addTab();
yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.ALLOW);
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -86,17 +86,18 @@
<!-- Permissions Section -->
<hbox class="identity-popup-section">
<vbox id="identity-popup-permissions-content" flex="1">
<label id="identity-popup-permissions-headline"
class="identity-popup-headline"
value="&identity.permissions;"/>
<vbox id="identity-popup-permission-list"/>
- <description>&identity.permissionsEmpty;</description>
+ <description id="identity-popup-permission-empty-hint">&identity.permissionsEmpty;</description>
+ <description id="identity-popup-permission-reload-hint">&identity.permissionsReloadHint;</description>
</vbox>
</hbox>
</panelview>
<!-- Security SubView -->
<panelview id="identity-popup-securityView" flex="1">
<vbox id="identity-popup-securityView-header">
<label class="plain">
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -726,16 +726,17 @@ you can use these alternative items. Oth
<!ENTITY identity.removeCertException.label "Remove Exception">
<!ENTITY identity.removeCertException.accesskey "R">
<!ENTITY identity.moreInfoLinkText2 "More Information">
<!ENTITY identity.permissions "Permissions">
<!ENTITY identity.permissionsEmpty "You have not granted this site any special permissions.">
+<!ENTITY identity.permissionsReloadHint "You may need to reload the page for changes to apply.">
<!-- Name for the tabs toolbar as spoken by screen readers.
The word "toolbar" is appended automatically and should not be contained below! -->
<!ENTITY tabsToolbar.label "Browser tabs">
<!-- LOCALIZATION NOTE (syncTabsMenu3.label): This appears in the history menu -->
<!ENTITY syncTabsMenu3.label "Synced Tabs">
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -367,20 +367,16 @@ description#identity-popup-content-verif
.identity-popup-permission-item {
min-height: 24px;
}
#identity-popup-permission-list:not(:empty) {
margin-top: 5px;
}
-#identity-popup-permission-list:not(:empty) + description {
- display: none;
-}
-
.identity-popup-permission-icon {
width: 16px;
height: 16px;
}
.identity-popup-permission-icon.in-use {
fill: rgb(224, 41, 29);
animation: 1.5s ease in-use-blink infinite;