Bug 1896672 - Check user activation for openBlocked popup blocker state r=smaug

Enabled behind new `dom.popup.experimental` pref, off by default.

Differential Revision: https://phabricator.services.mozilla.com/D215361
This commit is contained in:
Oliver Medhurst 2024-07-31 12:19:01 +00:00
Родитель 5d618d3e71
Коммит b3923ff723
4 изменённых файлов: 94 добавлений и 2 удалений

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

@ -2200,21 +2200,32 @@ PopupBlocker::PopupControlState BrowsingContext::RevisePopupAbuseLevel(
PopupBlocker::PopupControlState abuse = aControl;
switch (abuse) {
case PopupBlocker::openControlled:
case PopupBlocker::openBlocked:
case PopupBlocker::openOverridden:
if (IsPopupAllowed()) {
// Go down one state enum step:
// openControlled (1) -> openAllowed (0)
// openOverridden (4) -> openAbused (3)
abuse = PopupBlocker::PopupControlState(abuse - 1);
}
break;
case PopupBlocker::openAbused:
if (IsPopupAllowed() ||
(doc && doc->HasValidTransientUserGestureActivation())) {
// Skip PopupBlocker::openBlocked
// Always go down to openControlled:
// openAbused (3) -> openControlled (1), skip openBlocked (2)
abuse = PopupBlocker::openControlled;
}
break;
case PopupBlocker::openAllowed:
break;
case PopupBlocker::openBlocked:
if (IsPopupAllowed() || (StaticPrefs::dom_popup_experimental() && doc &&
doc->HasValidTransientUserGestureActivation())) {
// Go down one state enum step:
// openBlocked (2) -> openControlled (1)
abuse = PopupBlocker::openControlled;
}
break;
default:
NS_WARNING("Strange PopupControlState!");
}

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

@ -18,6 +18,8 @@ prefs = ["formhelper.autozoom.force-disable.test-only=true"]
["test_popup_blocker_pointer_event.html"]
["test_popup_blocker_postmessage.html"]
["test_useractivation_has_been_activated.html"]
["test_useractivation_key_events.html"]

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

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test for triggering popup by postMessage</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<button id="target">click me</button>
<script>
function sendMouseEvent(element, eventName, button) {
synthesizeMouseAtCenter(element, {type: eventName, button});
}
add_setup(async function() {
// Deny popup permission.
const DENY_ACTION = SpecialPowers.Ci.nsIPermissionManager.DENY_ACTION;
let xorigin = SimpleTest.getTestFileURL("").replace(location.hostname, 'mochi.xorigin-test');
await SpecialPowers.pushPermissions([
{'type': 'popup', 'allow': DENY_ACTION,
'context': document},
{'type': 'popup', 'allow': DENY_ACTION,
'context': xorigin}
]);
await new Promise(resolve => SimpleTest.waitForFocus(resolve));
// Set popup preferences.
await SpecialPowers.pushPrefEnv({ set: [["dom.block_multiple_popups", true]] });
await SpecialPowers.pushPrefEnv({ set: [["dom.popup.experimental", true]] });
});
const LEFT_BUTTON = 0;
const MIDDLE_BUTTON = 1;
const RIGHT_BUTTON = 2;
let target = document.getElementById("target");
let waits = [];
target.addEventListener("mouseup", () => {
waits.push(Promise.withResolvers());
window.postMessage({ openPopup: waits.length - 1 }, "*");
});
window.addEventListener("message", (e) => {
if (e.data.openPopup != null) {
let w = window.open("");
ok(w, "Should allow popup");
if (w) {
w.close();
}
let w2 = window.open("");
ok(!w2, "Should block another popup");
if (w2) {
w2.close();
}
waits[e.data.openPopup].resolve();
}
});
add_task(async function testMouseInitiated() {
sendMouseEvent(target, "mousedown", LEFT_BUTTON);
sendMouseEvent(target, "mouseup", LEFT_BUTTON);
await Promise.all(waits.map(x => x.promise));
});
</script>
</body>
</html>

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

@ -2287,6 +2287,12 @@
value: 20
mirror: always
# Enable experimental popup blocker changes.
- name: dom.popup.experimental
type: bool
value: false
mirror: always
# Enable CacheAPI in private browsing mode with encryption
- name: dom.cache.privateBrowsing.enabled
type: RelaxedAtomicBool