Bug 1646780 - use a template to wrap the identity popup while it's not needed, r=johannh

Differential Revision: https://phabricator.services.mozilla.com/D78894
This commit is contained in:
Gijs Kruitbosch 2020-06-23 14:04:49 +00:00
parent 31ae9b52fb
commit fca766666b
27 changed files with 178 additions and 114 deletions

View File

@ -143,8 +143,8 @@ add_task(async () => {
is(rootChildCount(), 5, "Root has 5 children");
// Open site identity popup
const identityPopup = document.getElementById("identity-popup");
document.getElementById("identity-box").click();
const identityPopup = document.getElementById("identity-popup");
await BrowserTestUtils.waitForPopupEvent(identityPopup, "shown");
// Now root has 6 children

View File

@ -148,8 +148,26 @@ var gIdentityHandler = {
);
},
_popupInitialized: false,
_initializePopup() {
if (!this._popupInitialized) {
let wrapper = document.getElementById("template-identity-popup");
wrapper.replaceWith(wrapper.content);
this._popupInitialized = true;
}
},
hidePopup() {
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
},
// smart getters
get _identityPopup() {
if (!this._popupInitialized) {
return null;
}
delete this._identityPopup;
return (this._identityPopup = document.getElementById("identity-popup"));
},
@ -416,7 +434,9 @@ var gIdentityHandler = {
histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
// Reload the page with the content unblocked
BrowserReloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
PanelMultiView.hidePopup(this._identityPopup);
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
},
enableMixedContentProtection() {
@ -426,7 +446,9 @@ var gIdentityHandler = {
"BrowserTab"
);
BrowserReload();
PanelMultiView.hidePopup(this._identityPopup);
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
},
removeCertException() {
@ -440,7 +462,9 @@ var gIdentityHandler = {
let port = this._uri.port > 0 ? this._uri.port : 443;
this._overrideService.clearValidityOverride(host, port);
BrowserReloadSkipCache();
PanelMultiView.hidePopup(this._identityPopup);
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
},
/**
@ -501,7 +525,7 @@ var gIdentityHandler = {
this.refreshIdentityBlock();
// Handle a location change while the Control Center is focused
// by closing the popup (bug 1207542)
if (shouldHidePopup) {
if (shouldHidePopup && this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
@ -567,7 +591,7 @@ var gIdentityHandler = {
}
}
if (this._identityPopup.state == "open") {
if (this._popupInitialized && this._identityPopup.state != "closed") {
this.updateSitePermissions();
PanelView.forNode(
this._identityPopupMainView
@ -1107,9 +1131,8 @@ var gIdentityHandler = {
},
_openPopup(event) {
// Make sure that the display:none style we set in xul is removed now that
// the popup is actually needed
this._identityPopup.hidden = false;
// Make the popup available.
this._initializePopup();
// Remove the reload hint that we show after a user has cleared a permission.
this._permissionReloadHint.setAttribute("hidden", "true");
@ -1120,9 +1143,10 @@ var gIdentityHandler = {
// Add the "open" attribute to the identity box for styling
this._identityBox.setAttribute("open", "true");
// Check the panel state of the protections panel. Hide it if needed.
if (gProtectionsHandler._protectionsPopup.state != "closed") {
PanelMultiView.hidePopup(gProtectionsHandler._protectionsPopup);
// Check the panel state of other panels. Hide them if needed.
let openPanels = Array.from(document.querySelectorAll("panel[openpanel]"));
for (let panel of openPanels) {
PanelMultiView.hidePopup(panel);
}
// Now open the popup, anchored off the primary chrome element
@ -1263,10 +1287,12 @@ var gIdentityHandler = {
},
onLocationChange() {
this._permissionReloadHint.setAttribute("hidden", "true");
if (this._popupInitialized && this._identityPopup.state != "closed") {
this._permissionReloadHint.setAttribute("hidden", "true");
if (!this._permissionList.hasChildNodes()) {
this._permissionEmptyHint.removeAttribute("hidden");
if (!this._permissionList.hasChildNodes()) {
this._permissionEmptyHint.removeAttribute("hidden");
}
}
},

View File

@ -2191,9 +2191,10 @@ var gProtectionsHandler = {
// for styling.
this._trackingProtectionIconContainer.setAttribute("open", "true");
// Check the panel state of the identity panel. Hide it if needed.
if (gIdentityHandler._identityPopup.state != "closed") {
PanelMultiView.hidePopup(gIdentityHandler._identityPopup);
// Check the panel state of other panels. Hide them if needed.
let openPanels = Array.from(document.querySelectorAll("panel[openpanel]"));
for (let panel of openPanels) {
PanelMultiView.hidePopup(panel);
}
// Now open the popup, anchored off the primary chrome element

View File

@ -3550,7 +3550,7 @@ function BrowserReloadWithFlags(reloadFlags) {
// Also reset DOS mitigations for the basic auth prompt on reload.
delete tab.linkedBrowser.authPromptAbuseCounter;
}
PanelMultiView.hidePopup(gIdentityHandler._identityPopup);
gIdentityHandler.hidePopup();
let handlingUserInput = window.windowUtils.isHandlingUserInput;

View File

@ -4101,7 +4101,7 @@
SitePermissions.clearTemporaryPermissions(browser);
// Also reset DOS mitigations for the basic auth prompt on reload.
delete browser.authPromptAbuseCounter;
PanelMultiView.hidePopup(gIdentityHandler._identityPopup);
gIdentityHandler.hidePopup();
browser.reload();
},

View File

@ -22,15 +22,15 @@ add_task(async function test_identityPopupCausesFSExit() {
await loaded;
let identityBox = document.getElementById("identity-box");
let identityPopup = document.getElementById("identity-popup");
info("Entering DOM fullscreen");
await changeFullscreen(browser, true);
let popupShown = BrowserTestUtils.waitForEvent(
identityPopup,
window,
"popupshown",
true
true,
event => event.target == document.getElementById("identity-popup")
);
let fsExit = waitForFullScreenState(browser, false);
@ -39,6 +39,7 @@ add_task(async function test_identityPopupCausesFSExit() {
info("Waiting for fullscreen exit and identity popup to show");
await Promise.all([fsExit, popupShown]);
let identityPopup = document.getElementById("identity-popup");
ok(
identityPopup.hasAttribute("panelopen"),
"Identity popup should be open"

View File

@ -15,8 +15,10 @@ add_task(async function() {
let { gIdentityHandler } = gBrowser.ownerGlobal;
let promisePanelOpen = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
gBrowser.ownerGlobal,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
await promisePanelOpen;
@ -65,7 +67,7 @@ add_task(async function() {
"Using expected icon image in the Control Center subview"
);
gIdentityHandler._identityPopup.hidden = true;
gIdentityHandler._identityPopup.hidePopup();
let certOverrideService = Cc[
"@mozilla.org/security/certoverride;1"

View File

@ -25,8 +25,10 @@ const AUTOPLAY_PERM = "autoplay-media";
function openIdentityPopup() {
let promise = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
gBrowser.ownerGlobal,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
return promise;

View File

@ -13,8 +13,10 @@ const kStrictKeyPressEvents = SpecialPowers.getBoolPref(
function openIdentityPopup() {
let promise = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
return promise;
@ -31,13 +33,12 @@ function closeIdentityPopup() {
add_task(async function testMainViewVisible() {
await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function() {
await openIdentityPopup();
let permissionsList = document.getElementById(
"identity-popup-permission-list"
);
let emptyLabel = permissionsList.nextElementSibling.nextElementSibling;
await openIdentityPopup();
ok(!BrowserTestUtils.is_hidden(emptyLabel), "List of permissions is empty");
await closeIdentityPopup();

View File

@ -24,8 +24,10 @@ const PRINCIPAL = Services.scriptSecurityManager.createContentPrincipal(
function openIdentityPopup() {
let promise = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
return promise;

View File

@ -10,11 +10,9 @@ const TRACKING_PAGE =
const COOKIE_PAGE =
"http://tracking.example.com/browser/browser/base/content/test/protectionsUI/cookiePage.html";
async function waitAndAssertPreferencesShown(_spotlight, identityPopup) {
async function waitAndAssertPreferencesShown(_spotlight) {
await BrowserTestUtils.waitForEvent(
identityPopup
? gIdentityHandler._identityPopup
: gProtectionsHandler._protectionsPopup,
gProtectionsHandler._protectionsPopup,
"popuphidden"
);
await TestUtils.waitForCondition(

View File

@ -168,13 +168,6 @@ function promiseTabLoadEvent(tab, url) {
return loaded;
}
function openIdentityPopup() {
let mainView = document.getElementById("identity-popup-mainView");
let viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
gIdentityHandler._identityBox.click();
return viewShown;
}
function waitForSecurityChange(numChanges = 1, win = null) {
if (!win) {
win = window;

View File

@ -14,13 +14,6 @@ function getIdentityMode(aWindow = window) {
return aWindow.document.getElementById("identity-box").className;
}
function openIdentityPopup() {
let mainView = document.getElementById("identity-popup-mainView");
let viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
gIdentityHandler._identityBox.click();
return viewShown;
}
function closeIdentityPopup() {
let promise = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,

View File

@ -51,8 +51,10 @@ async function testClearing(
// Open the identity popup.
let { gIdentityHandler } = gBrowser.ownerGlobal;
let promisePanelOpen = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
gBrowser.ownerGlobal,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
await promisePanelOpen;

View File

@ -15,9 +15,12 @@ const TEST_PATH = getRootDirectory(gTestPath).replace(
add_task(async function test_https() {
await BrowserTestUtils.withNewTab("https://example.com", async function() {
let promisePanelOpen = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
await promisePanelOpen;
let customRootWarning = document.getElementById(
@ -47,8 +50,10 @@ add_task(async function test_https() {
add_task(async function test_http() {
await BrowserTestUtils.withNewTab("http://example.com", async function() {
let promisePanelOpen = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
await promisePanelOpen;

View File

@ -19,8 +19,10 @@ add_task(async function testIdentityPopupFocusClick() {
await SpecialPowers.pushPrefEnv({ set: [["accessibility.tabfocus", 7]] });
await BrowserTestUtils.withNewTab("https://example.com", async function() {
let shown = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
EventUtils.synthesizeMouseAtCenter(gIdentityHandler._identityBox, {});
await shown;
@ -37,8 +39,10 @@ add_task(async function testIdentityPopupFocusKeyboard() {
await BrowserTestUtils.withNewTab("https://example.com", async function() {
await focusIdentityBox();
let shown = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
EventUtils.sendString(" ");
await shown;
@ -57,8 +61,10 @@ add_task(async function testSiteSecurityTabOrder() {
// 1. Access the identity popup.
await focusIdentityBox();
let shown = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
EventUtils.sendString(" ");
await shown;

View File

@ -111,7 +111,8 @@ async function runTest(i, forward) {
await loaded;
await popupHidden;
ok(
BrowserTestUtils.is_hidden(gIdentityHandler._identityPopup),
!gIdentityHandler._identityPopup ||
BrowserTestUtils.is_hidden(gIdentityHandler._identityPopup),
"Control Center is hidden"
);
@ -132,8 +133,10 @@ async function runTest(i, forward) {
// Open the Control Center and make sure it closes after nav (Bug 1207542).
let popupShown = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
info("Waiting for the Control Center to be shown");

View File

@ -3,6 +3,7 @@ var { XPCOMUtils } = ChromeUtils.import(
);
function openIdentityPopup() {
gIdentityHandler._initializePopup();
let mainView = document.getElementById("identity-popup-mainView");
let viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
gIdentityHandler._identityBox.click();
@ -241,8 +242,10 @@ async function assertMixedContentBlockingState(tabbrowser, states = {}) {
// Make sure the identity popup has the correct mixedcontent states
let promisePanelOpen = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
tabbrowser.ownerGlobal,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
await promisePanelOpen;

View File

@ -78,8 +78,10 @@ add_task(async function() {
// Check if the control center shows the correct permission.
let shown = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
await shown;

View File

@ -743,10 +743,7 @@ var gTests = [
await indicator;
await checkSharingUI({ video: true });
ok(
gIdentityHandler._identityPopup.hidden,
"control center should be hidden"
);
ok(identityPopupHidden(), "control center should be hidden");
if (USING_LEGACY_INDICATOR && IS_MAC) {
let activeStreams = webrtcUI.getActiveStreams(true, false, false);
webrtcUI.showSharingDoorhanger(activeStreams[0]);
@ -763,16 +760,14 @@ var gTests = [
let elt = win.document.getElementById(buttonID);
EventUtils.synthesizeMouseAtCenter(elt, {}, win);
await TestUtils.waitForCondition(
() => !gIdentityHandler._identityPopup.hidden
);
}
ok(
!gIdentityHandler._identityPopup.hidden,
"control center should be open"
await TestUtils.waitForCondition(
() => !identityPopupHidden(),
"wait for control center to open"
);
ok(!identityPopupHidden(), "control center should be open");
gIdentityHandler._identityPopup.hidden = true;
gIdentityHandler._identityPopup.hidePopup();
await closeStream();
},

View File

@ -664,10 +664,7 @@ var gTests = [
await indicator;
await checkSharingUI({ screen: "Screen" });
ok(
gIdentityHandler._identityPopup.hidden,
"control center should be hidden"
);
ok(identityPopupHidden(), "control center should be hidden");
if (IS_MAC) {
let activeStreams = webrtcUI.getActiveStreams(false, false, true);
webrtcUI.showSharingDoorhanger(activeStreams[0]);
@ -677,16 +674,14 @@ var gTests = [
);
let elt = win.document.getElementById("screenShareButton");
EventUtils.synthesizeMouseAtCenter(elt, {}, win);
await TestUtils.waitForCondition(
() => !gIdentityHandler._identityPopup.hidden
);
}
ok(
!gIdentityHandler._identityPopup.hidden,
"control center should be open"
await TestUtils.waitForCondition(
() => !identityPopupHidden(),
"wait for control center to open"
);
ok(!identityPopupHidden(), "control center should be open");
gIdentityHandler._identityPopup.hidden = true;
gIdentityHandler._identityPopup.hidePopup();
await closeStream();
},

View File

@ -48,21 +48,23 @@ var gTests = [
// Clicking the global sharing indicator should open the control center in
// the second window.
ok(
win.gIdentityHandler._identityPopup.hidden,
"control center should be hidden"
);
ok(identityPopupHidden(win), "control center should be hidden");
let activeStreams = webrtcUI.getActiveStreams(true, false, false);
webrtcUI.showSharingDoorhanger(activeStreams[0], "Devices");
// If the popup gets hidden before being shown, by stray focus/activate
// events, don't bother failing the test. It's enough to know that we
// started showing the popup.
let popup = win.gIdentityHandler._identityPopup;
let hiddenEvent = BrowserTestUtils.waitForEvent(popup, "popuphidden");
let shownEvent = BrowserTestUtils.waitForEvent(popup, "popupshown");
let ev = await Promise.race([hiddenEvent, shownEvent]);
ok(ev.type, "Tried to show popup");
win.gIdentityHandler._identityPopup.hidePopup();
ok(
!win.gIdentityHandler._identityPopup.hidden,
"control center should be open in the second window"
);
ok(
gIdentityHandler._identityPopup.hidden,
identityPopupHidden(window),
"control center should be hidden in the first window"
);
win.gIdentityHandler._identityPopup.hidden = true;
await disableObserverVerification();

View File

@ -88,8 +88,10 @@ async function assertWebRTCIndicatorStatus(expected) {
if (!expected && ui.showGlobalIndicator) {
// It seems the global indicator is not always removed synchronously
// in some cases.
info("waiting for the global indicator to be hidden");
await TestUtils.waitForCondition(() => !ui.showGlobalIndicator);
await TestUtils.waitForCondition(
() => !ui.showGlobalIndicator,
"waiting for the global indicator to be hidden"
);
}
is(ui.showGlobalIndicator, !!expected, msg);
@ -524,6 +526,13 @@ async function stopSharing(
aFrameBC
);
aWindow.gIdentityHandler._identityBox.click();
let popup = aWindow.gIdentityHandler._identityPopup;
// If the popup gets hidden before being shown, by stray focus/activate
// events, don't bother failing the test. It's enough to know that we
// started showing the popup.
let hiddenEvent = BrowserTestUtils.waitForEvent(popup, "popuphidden");
let shownEvent = BrowserTestUtils.waitForEvent(popup, "popupshown");
await Promise.race([hiddenEvent, shownEvent]);
let doc = aWindow.document;
let permissions = doc.getElementById("identity-popup-permission-list");
let cancelButton = permissions.querySelector(
@ -550,7 +559,7 @@ async function stopSharing(
}
cancelButton.click();
aWindow.gIdentityHandler._identityPopup.hidden = true;
popup.hidePopup();
await promiseRecordingEvent;
await observerPromise1;
@ -725,6 +734,13 @@ async function checkSharingUI(
// Then check the sharing indicators inside the control center panel.
identityBox.click();
let popup = aWin.gIdentityHandler._identityPopup;
// If the popup gets hidden before being shown, by stray focus/activate
// events, don't bother failing the test. It's enough to know that we
// started showing the popup.
let hiddenEvent = BrowserTestUtils.waitForEvent(popup, "popuphidden");
let shownEvent = BrowserTestUtils.waitForEvent(popup, "popupshown");
await Promise.race([hiddenEvent, shownEvent]);
let permissions = doc.getElementById("identity-popup-permission-list");
for (let id of ["microphone", "camera", "screen"]) {
let convertId = idToConvert => {
@ -763,7 +779,11 @@ async function checkSharingUI(
is(icon.length, 1, "should not show more than 1 " + id + " icon");
}
}
aWin.gIdentityHandler._identityPopup.hidden = true;
aWin.gIdentityHandler._identityPopup.hidePopup();
await TestUtils.waitForCondition(
() => identityPopupHidden(aWin),
"identity popup should be hidden"
);
// Check the global indicators.
await assertWebRTCIndicatorStatus(aExpectedGlobal || aExpected);
@ -874,6 +894,11 @@ async function disableObserverVerification() {
}
}
function identityPopupHidden(win = window) {
let popup = win.gIdentityHandler._identityPopup;
return !popup || popup.state == "closed";
}
async function runTests(tests, options = {}) {
let browser = await openNewTestTab(options.relativeURI);
@ -883,7 +908,7 @@ async function runTests(tests, options = {}) {
"should start the test without any prior popup notification"
);
ok(
gIdentityHandler._identityPopup.hidden,
identityPopupHidden(),
"should start the test with the control center hidden"
);

View File

@ -2,10 +2,10 @@
- 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/. -->
<html:template id="template-identity-popup">
<panel id="identity-popup"
class="panel-no-padding"
type="arrow"
hidden="true"
role="alertdialog"
noautofocus="true"
aria-labelledby="identity-popup-mainView-panel-header-span"
@ -177,3 +177,4 @@
</panelview>
</panelmultiview>
</panel>
</html:template>

View File

@ -8,8 +8,10 @@ const { PermissionTestUtils } = ChromeUtils.import(
function openIdentityPopup() {
let promise = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
return promise;

View File

@ -297,6 +297,8 @@ async function openIdentityPopup(expand) {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let gBrowser = browserWindow.gBrowser;
let { gIdentityHandler } = gBrowser.ownerGlobal;
// Ensure the popup is available, if it's never been opened.
gIdentityHandler._initializePopup();
gIdentityHandler._identityPopup.hidePopup();
// Disable the popup shadow on OSX until we have figured out bug 1425253.
if (AppConstants.platform == "macosx") {

View File

@ -2,8 +2,10 @@
function openIdentityPopup() {
let promise = BrowserTestUtils.waitForEvent(
gIdentityHandler._identityPopup,
"popupshown"
window,
"popupshown",
true,
event => event.target == gIdentityHandler._identityPopup
);
gIdentityHandler._identityBox.click();
return promise;