diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 504d11f8d326..277e54076ff3 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -2148,11 +2148,22 @@ void BrowsingContext::Focus(CallerType aCallerType, ErrorResult& aError) { } } -void BrowsingContext::Blur(ErrorResult& aError) { +bool BrowsingContext::CanBlurCheck(CallerType aCallerType) { + // If dom.disable_window_flip == true, then content should not be allowed + // to do blur (this would allow popunders, bug 369306) + return aCallerType == CallerType::System || + !Preferences::GetBool("dom.disable_window_flip", true); +} + +void BrowsingContext::Blur(CallerType aCallerType, ErrorResult& aError) { + if (!CanBlurCheck(aCallerType)) { + return; + } + if (ContentChild* cc = ContentChild::GetSingleton()) { - cc->SendWindowBlur(this); + cc->SendWindowBlur(this, aCallerType); } else if (ContentParent* cp = Canonical()->GetContentParent()) { - Unused << cp->SendWindowBlur(this); + Unused << cp->SendWindowBlur(this, aCallerType); } } diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index d3c6ba44bd4f..13937e0791ac 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -610,7 +610,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { void Close(CallerType aCallerType, ErrorResult& aError); bool GetClosed(ErrorResult&) { return GetClosed(); } void Focus(CallerType aCallerType, ErrorResult& aError); - void Blur(ErrorResult& aError); + void Blur(CallerType aCallerType, ErrorResult& aError); WindowProxyHolder GetFrames(ErrorResult& aError); int32_t Length() const { return Children().Length(); } Nullable GetTop(ErrorResult& aError); @@ -784,6 +784,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { // Returns canFocus, isActive std::tuple CanFocusCheck(CallerType aCallerType); + bool CanBlurCheck(CallerType aCallerType); + PopupBlocker::PopupControlState RevisePopupAbuseLevel( PopupBlocker::PopupControlState aControl); diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index dad4af1f8475..a0a4de6b5c1f 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -3736,8 +3736,8 @@ nsresult nsGlobalWindowInner::Focus(CallerType aCallerType) { return rv.StealNSResult(); } -void nsGlobalWindowInner::Blur(ErrorResult& aError) { - FORWARD_TO_OUTER_OR_THROW(BlurOuter, (), aError, ); +void nsGlobalWindowInner::Blur(CallerType aCallerType, ErrorResult& aError) { + FORWARD_TO_OUTER_OR_THROW(BlurOuter, (aCallerType), aError, ); } void nsGlobalWindowInner::Stop(ErrorResult& aError) { diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 93e1c0ce9202..56c4f5300f97 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -608,7 +608,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget, void Focus(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); nsresult Focus(mozilla::dom::CallerType aCallerType) override; - void Blur(mozilla::ErrorResult& aError); + void Blur(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); mozilla::dom::WindowProxyHolder GetFrames(mozilla::ErrorResult& aError); uint32_t Length(); mozilla::dom::Nullable GetTop( diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index f8f20a796f40..7b535df779f3 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -5117,10 +5117,8 @@ nsresult nsGlobalWindowOuter::Focus(CallerType aCallerType) { FORWARD_TO_INNER(Focus, (aCallerType), NS_ERROR_UNEXPECTED); } -void nsGlobalWindowOuter::BlurOuter() { - // If dom.disable_window_flip == true, then content should not be allowed - // to call this function (this would allow popunders, bug 369306) - if (!CanSetProperty("dom.disable_window_flip")) { +void nsGlobalWindowOuter::BlurOuter(CallerType aCallerType) { + if (!GetBrowsingContext()->CanBlurCheck(aCallerType)) { return; } diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index 50bc8adb4519..0a34b10b0819 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -535,7 +535,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, void FocusOuter(mozilla::dom::CallerType aCallerType, bool aFromOtherProcess, uint64_t aActionId); nsresult Focus(mozilla::dom::CallerType aCallerType) override; - void BlurOuter(); + void BlurOuter(mozilla::dom::CallerType aCallerType); mozilla::dom::WindowProxyHolder GetFramesOuter(); uint32_t Length(); mozilla::dom::Nullable GetTopOuter(); diff --git a/dom/base/test/file_focus_design_mode_inner.html b/dom/base/test/file_focus_design_mode_inner.html new file mode 100644 index 000000000000..43e24652ab68 --- /dev/null +++ b/dom/base/test/file_focus_design_mode_inner.html @@ -0,0 +1,32 @@ + + + + + activeElement design-mode inner document + + +

Inner

+ + + diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index 6bdd5a632318..8cbb1ea4e78a 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -657,6 +657,9 @@ skip-if = toolkit == 'android' && !is_fennec # Bug 1525959 [test_focus_scrollable_input.html] [test_focus_scrollable_fieldset.html] [test_focus_scroll_padding_tab.html] +[test_focus_design_mode.html] +support-files = + file_focus_design_mode_inner.html [test_getAttribute_after_createAttribute.html] [test_getElementById.html] [test_getTranslationNodes.html] diff --git a/dom/base/test/test_focus_design_mode.html b/dom/base/test/test_focus_design_mode.html new file mode 100644 index 000000000000..342e0fbbccf6 --- /dev/null +++ b/dom/base/test/test_focus_design_mode.html @@ -0,0 +1,62 @@ + + + + + Test for Bug 1690747 + + + + + +Mozilla Bug 1690747 +

+
+
+
+
+
+
+ + diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 4480609f8bb8..f669d90a4790 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -3734,7 +3734,7 @@ mozilla::ipc::IPCResult ContentChild::RecvWindowFocus( } mozilla::ipc::IPCResult ContentChild::RecvWindowBlur( - const MaybeDiscarded& aContext) { + const MaybeDiscarded& aContext, CallerType aCallerType) { if (aContext.IsNullOrDiscarded()) { MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug, ("ChildIPC: Trying to send a message to dead or detached context")); @@ -3748,7 +3748,7 @@ mozilla::ipc::IPCResult ContentChild::RecvWindowBlur( ("ChildIPC: Trying to send a message to a context without a window")); return IPC_OK(); } - nsGlobalWindowOuter::Cast(window)->BlurOuter(); + nsGlobalWindowOuter::Cast(window)->BlurOuter(aCallerType); return IPC_OK(); } diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 2e84ad7c380c..af1c7557f56c 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -712,7 +712,7 @@ class ContentChild final : public PContentChild, const MaybeDiscarded& aContext, CallerType aCallerType, uint64_t aActionId); mozilla::ipc::IPCResult RecvWindowBlur( - const MaybeDiscarded& aContext); + const MaybeDiscarded& aContext, CallerType aCallerType); mozilla::ipc::IPCResult RecvRaiseWindow( const MaybeDiscarded& aContext, CallerType aCallerType, uint64_t aActionId); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index b37e99e8a3c6..3e47037f09e8 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -6817,7 +6817,7 @@ mozilla::ipc::IPCResult ContentParent::RecvWindowFocus( } mozilla::ipc::IPCResult ContentParent::RecvWindowBlur( - const MaybeDiscarded& aContext) { + const MaybeDiscarded& aContext, CallerType aCallerType) { if (aContext.IsNullOrDiscarded()) { MOZ_LOG( BrowsingContext::GetLog(), LogLevel::Debug, @@ -6829,7 +6829,7 @@ mozilla::ipc::IPCResult ContentParent::RecvWindowBlur( ContentProcessManager* cpm = ContentProcessManager::GetSingleton(); ContentParent* cp = cpm->GetContentProcessById(ContentParentId(context->OwnerProcessId())); - Unused << cp->SendWindowBlur(context); + Unused << cp->SendWindowBlur(context, aCallerType); return IPC_OK(); } diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 1a782fbe9af5..bd2d9f5cb599 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -679,7 +679,7 @@ class ContentParent final const MaybeDiscarded& aContext, CallerType aCallerType, uint64_t aActionId); mozilla::ipc::IPCResult RecvWindowBlur( - const MaybeDiscarded& aContext); + const MaybeDiscarded& aContext, CallerType aCallerType); mozilla::ipc::IPCResult RecvRaiseWindow( const MaybeDiscarded& aContext, CallerType aCallerType, uint64_t aActionId); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 48b9e5389bd1..d4d416cfefb3 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -1799,7 +1799,8 @@ both: bool aTrustedCaller); async WindowFocus(MaybeDiscardedBrowsingContext aContext, CallerType aCallerType, uint64_t aActionId); - async WindowBlur(MaybeDiscardedBrowsingContext aContext); + async WindowBlur(MaybeDiscardedBrowsingContext aContext, + CallerType aCallerType); async RaiseWindow(MaybeDiscardedBrowsingContext aContext, CallerType aCallerType, uint64_t aActionId); async ClearFocus(MaybeDiscardedBrowsingContext aContext); async SetFocusedBrowsingContext(MaybeDiscardedBrowsingContext aContext); diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 886661bed33d..ac2a1becc69b 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -226,7 +226,7 @@ typedef OfflineResourceList ApplicationCache; [Throws, CrossOriginReadable] readonly attribute boolean closed; [Throws] void stop(); [Throws, CrossOriginCallable, NeedsCallerType] void focus(); - [Throws, CrossOriginCallable] void blur(); + [Throws, CrossOriginCallable, NeedsCallerType] void blur(); [Replaceable, Pref="dom.window.event.enabled"] readonly attribute any event; // other browsing contexts