mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 918780 - Add new PopupControlState for permitting file/color picker popup regardless of dom_allowed_events. r=smaug
MozReview-Commit-ID: 1GbjQ6IkMsv --HG-- extra : rebase_source : 4ea11b78007d9ab67a932536843b3e12175732b3
This commit is contained in:
parent
c86980aa3c
commit
91cfa95229
@ -567,7 +567,7 @@ TimeoutManager::SetTimeout(nsITimeoutHandler* aHandler,
|
||||
}
|
||||
|
||||
if (gRunningTimeoutDepth == 0 &&
|
||||
mWindow.GetPopupControlState() < openAbused) {
|
||||
mWindow.GetPopupControlState() < openBlocked) {
|
||||
// This timeout is *not* set from another timeout and it's set
|
||||
// while popups are enabled. Propagate the state to the timeout if
|
||||
// its delay (interval) is equal to or less than what
|
||||
|
@ -7865,7 +7865,7 @@ nsGlobalWindow::FocusOuter(ErrorResult& aError)
|
||||
// (bugs 355482 and 369306).
|
||||
bool canFocus = CanSetProperty("dom.disable_window_flip") ||
|
||||
(opener == callerOuter &&
|
||||
RevisePopupAbuseLevel(gPopupControlState) < openAbused);
|
||||
RevisePopupAbuseLevel(gPopupControlState) < openBlocked);
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> activeDOMWindow;
|
||||
fm->GetActiveWindow(getter_AddRefs(activeDOMWindow));
|
||||
@ -8860,18 +8860,25 @@ nsGlobalWindow::RevisePopupAbuseLevel(PopupControlState aControl)
|
||||
PopupControlState abuse = aControl;
|
||||
switch (abuse) {
|
||||
case openControlled:
|
||||
case openAbused:
|
||||
case openBlocked:
|
||||
case openOverridden:
|
||||
if (PopupWhitelisted())
|
||||
abuse = PopupControlState(abuse - 1);
|
||||
break;
|
||||
case openAbused:
|
||||
if (PopupWhitelisted())
|
||||
//Skip openBlocked
|
||||
abuse = openControlled;
|
||||
break;
|
||||
case openAllowed: break;
|
||||
default:
|
||||
NS_WARNING("Strange PopupControlState!");
|
||||
}
|
||||
|
||||
// limit the number of simultaneously open popups
|
||||
if (abuse == openAbused || abuse == openControlled) {
|
||||
if (abuse == openAbused ||
|
||||
abuse == openBlocked ||
|
||||
abuse == openControlled) {
|
||||
int32_t popupMax = Preferences::GetInt("dom.popup_maximum", -1);
|
||||
if (popupMax >= 0 && gOpenPopupSpamCount >= popupMax)
|
||||
abuse = openOverridden;
|
||||
@ -12993,7 +13000,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||
PopupControlState abuseLevel = gPopupControlState;
|
||||
if (checkForPopup) {
|
||||
abuseLevel = RevisePopupAbuseLevel(abuseLevel);
|
||||
if (abuseLevel >= openAbused) {
|
||||
if (abuseLevel >= openBlocked) {
|
||||
if (!aCalledNoScript) {
|
||||
// If script in some other window is doing a window.open on us and
|
||||
// it's being blocked, then it's OK to close us afterwards, probably.
|
||||
@ -13031,9 +13038,9 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||
nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
|
||||
NS_ENSURE_STATE(pwwatch);
|
||||
|
||||
MOZ_ASSERT_IF(checkForPopup, abuseLevel < openAbused);
|
||||
MOZ_ASSERT_IF(checkForPopup, abuseLevel < openBlocked);
|
||||
// At this point we should know for a fact that if checkForPopup then
|
||||
// abuseLevel < openAbused, so we could just check for abuseLevel ==
|
||||
// abuseLevel < openBlocked, so we could just check for abuseLevel ==
|
||||
// openControlled. But let's be defensive just in case and treat anything
|
||||
// that fails the above assert as a spam popup too, if it ever happens.
|
||||
bool isPopupSpamWindow = checkForPopup && (abuseLevel >= openControlled);
|
||||
|
@ -65,6 +65,7 @@ enum class CallerType : uint32_t;
|
||||
enum PopupControlState {
|
||||
openAllowed = 0, // open that window without worries
|
||||
openControlled, // it's a popup, but allow it
|
||||
openBlocked, // it's a popup, but not from an allowed event
|
||||
openAbused, // it's a popup. disallow it, but allow domain override.
|
||||
openOverridden // disallow window open
|
||||
};
|
||||
|
@ -713,6 +713,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
// triggered while handling user input. See
|
||||
// nsPresShell::HandleEventInternal() for details.
|
||||
if (EventStateManager::IsHandlingUserInput()) {
|
||||
abuse = openBlocked;
|
||||
switch(aEvent->mMessage) {
|
||||
case eFormSelect:
|
||||
if (PopupAllowedForEvent("select")) {
|
||||
@ -734,6 +735,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
// while handling user input. See
|
||||
// nsPresShell::HandleEventInternal() for details.
|
||||
if (EventStateManager::IsHandlingUserInput()) {
|
||||
abuse = openBlocked;
|
||||
switch(aEvent->mMessage) {
|
||||
case eEditorInput:
|
||||
if (PopupAllowedForEvent("input")) {
|
||||
@ -750,6 +752,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
// while handling user input. See
|
||||
// nsPresShell::HandleEventInternal() for details.
|
||||
if (EventStateManager::IsHandlingUserInput()) {
|
||||
abuse = openBlocked;
|
||||
switch(aEvent->mMessage) {
|
||||
case eFormChange:
|
||||
if (PopupAllowedForEvent("change")) {
|
||||
@ -766,6 +769,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
break;
|
||||
case eKeyboardEventClass:
|
||||
if (aEvent->IsTrusted()) {
|
||||
abuse = openBlocked;
|
||||
uint32_t key = aEvent->AsKeyboardEvent()->mKeyCode;
|
||||
switch(aEvent->mMessage) {
|
||||
case eKeyPress:
|
||||
@ -796,6 +800,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
break;
|
||||
case eTouchEventClass:
|
||||
if (aEvent->IsTrusted()) {
|
||||
abuse = openBlocked;
|
||||
switch (aEvent->mMessage) {
|
||||
case eTouchStart:
|
||||
if (PopupAllowedForEvent("touchstart")) {
|
||||
@ -815,6 +820,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
case eMouseEventClass:
|
||||
if (aEvent->IsTrusted() &&
|
||||
aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
|
||||
abuse = openBlocked;
|
||||
switch(aEvent->mMessage) {
|
||||
case eMouseUp:
|
||||
if (PopupAllowedForEvent("mouseup")) {
|
||||
@ -869,6 +875,7 @@ Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
|
||||
// triggered while handling user input. See
|
||||
// nsPresShell::HandleEventInternal() for details.
|
||||
if (EventStateManager::IsHandlingUserInput()) {
|
||||
abuse = openBlocked;
|
||||
switch(aEvent->mMessage) {
|
||||
case eFormSubmit:
|
||||
if (PopupAllowedForEvent("submit")) {
|
||||
|
@ -818,8 +818,8 @@ HTMLInputElement::IsPopupBlocked() const
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if page is allowed to open the popup
|
||||
if (win->GetPopupControlState() <= openControlled) {
|
||||
// Check if page can open a popup without abuse regardless of allowed events
|
||||
if (win->GetPopupControlState() <= openBlocked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,8 @@
|
||||
<button id='button-up' onclick="document.getElementById('by-button').click();">foo</button>
|
||||
<div id='div-click' onclick="document.getElementById('by-button').click();" tabindex='1'>foo</div>
|
||||
<div id='div-click-on-demand' onclick="var i=document.createElement('input'); i.type='file'; i.click();" tabindex='1'>foo</div>
|
||||
<div id='div-keydown' onkeydown="document.getElementById('by-button').click();" tabindex='1'>foo</div>
|
||||
<a id='link-click' href="javascript:document.getElementById('by-button').click();" tabindex='1'>foo</a>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
@ -129,6 +131,8 @@ var testData = [["a", 1, MockFilePicker.filterImages, 1],
|
||||
["button-up", 0, undefined, 0],
|
||||
["div-click", 0, undefined, 0],
|
||||
["div-click-on-demand", 0, undefined, 0],
|
||||
["div-keydown", 0, undefined, 0],
|
||||
["link-click", 0, undefined, 0],
|
||||
];
|
||||
|
||||
var currentTest = 0;
|
||||
@ -137,9 +141,8 @@ var filters;
|
||||
var filterIndex;
|
||||
var mixRefExtensionList;
|
||||
|
||||
// disable popups to make sure that the popup blocker does not interfere
|
||||
// with manually opened file pickers.
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.disable_open_during_load", false]]}, runTests);
|
||||
// Make sure picker works with popup blocker enabled and no allowed events
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.popup_allowed_events", ""]]}, runTests);
|
||||
|
||||
function launchNextTest() {
|
||||
MockFilePicker.shown = false;
|
||||
@ -192,8 +195,11 @@ function launchNextTest() {
|
||||
testData[currentTest][0] == 'button-down' ||
|
||||
testData[currentTest][0] == 'button-up' ||
|
||||
testData[currentTest][0] == 'div-click' ||
|
||||
testData[currentTest][0] == 'div-click-on-demand') {
|
||||
testData[currentTest][0] == 'div-click-on-demand' ||
|
||||
testData[currentTest][0] == 'link-click') {
|
||||
synthesizeMouseAtCenter(document.getElementById(testData[currentTest][0]), {});
|
||||
} else if (testData[currentTest][0] == 'div-keydown') {
|
||||
synthesizeKey("a", {});
|
||||
} else {
|
||||
document.getElementById(testData[currentTest][0]).click();
|
||||
}
|
||||
|
@ -1380,8 +1380,9 @@ pref("content.sink.pending_event_mode", 0);
|
||||
// Disable popups from plugins by default
|
||||
// 0 = openAllowed
|
||||
// 1 = openControlled
|
||||
// 2 = openAbused
|
||||
pref("privacy.popups.disable_from_plugins", 2);
|
||||
// 2 = openBlocked
|
||||
// 3 = openAbused
|
||||
pref("privacy.popups.disable_from_plugins", 3);
|
||||
|
||||
// send "do not track" HTTP header, disabled by default
|
||||
pref("privacy.donottrackheader.enabled", false);
|
||||
|
Loading…
Reference in New Issue
Block a user