Bug 1428722 - part1 : always activate the top level frame.
For top level frame, it should also be activated when user activate its child frame.
eg. A (youtube.com) -> B (ad.com), when user activate B frame, the A frame would also be activated.
MozReview-Commit-ID: BP7eGKiqYJe
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -13271,16 +13271,32 @@ void
nsIDocument::SetUserHasInteracted(bool aUserHasInteracted)
{
MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug,
("Document %p has been interacted by user.", this));
mUserHasInteracted = aUserHasInteracted;
}
void
+nsIDocument::MaybeNotifyUserActivation(nsIPrincipal* aPrincipal)
+{
+ bool isEqual = false;
+ nsresult rv = aPrincipal->Equals(NodePrincipal(), &isEqual);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
+
+ // If a child frame is actived, it would always activate the top frame and its
+ // parent frames which has same priciple.
+ if (isEqual || IsTopLevelContentDocument()) {
+ NotifyUserActivation();
+ }
+}
+
+void
nsIDocument::NotifyUserActivation()
{
if (mUserHasActivatedInteraction) {
return;
}
MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug,
("Document %p has been activated by user.", this));
@@ -13302,38 +13318,37 @@ nsIDocument::HasBeenUserActivated()
return mUserHasActivatedInteraction;
}
nsIDocument*
nsIDocument::GetFirstParentDocumentWithSamePrincipal(nsIPrincipal* aPrincipal)
{
MOZ_ASSERT(aPrincipal);
- nsIDocument* parent = GetSameTypeParentDocument(this);
+ nsIDocument* parent = GetSameTypeParentDocument();
while (parent) {
bool isEqual = false;
nsresult rv = aPrincipal->Equals(parent->NodePrincipal(), &isEqual);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
if (isEqual) {
return parent;
}
- parent = GetSameTypeParentDocument(parent);
+ parent = parent->GetSameTypeParentDocument();
}
MOZ_ASSERT(!parent);
return nullptr;
}
nsIDocument*
-nsIDocument::GetSameTypeParentDocument(const nsIDocument* aDoc)
-{
- MOZ_ASSERT(aDoc);
- nsCOMPtr<nsIDocShellTreeItem> current = aDoc->GetDocShell();
+nsIDocument::GetSameTypeParentDocument()
+{
+ nsCOMPtr<nsIDocShellTreeItem> current = GetDocShell();
if (!current) {
return nullptr;
}
nsCOMPtr<nsIDocShellTreeItem> parent;
current->GetSameTypeParent(getter_AddRefs(parent));
if (!parent) {
return nullptr;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3072,16 +3072,21 @@ public:
}
// This would be called when document get activated by specific user gestures.
void NotifyUserActivation();
// Return true if document has interacted by specific user gestures.
bool HasBeenUserActivated();
+ void MaybeNotifyUserActivation(nsIPrincipal* aPrincipal);
+
+ // Return the same type parent docuement if exists, or return null.
+ nsIDocument* GetSameTypeParentDocument();
+
// Return the first parent document with same pricipal, return nullptr if we
// can't find it.
nsIDocument* GetFirstParentDocumentWithSamePrincipal(nsIPrincipal* aPrincipal);
bool HasScriptsBlockedBySandbox();
bool InlineScriptAllowedByCSP();
@@ -3266,19 +3271,16 @@ protected:
// mFrameRequestCallbacksScheduled. aOldShell should only be passed when
// mPresShell is becoming null; in that case it will be used to get hold of
// the relevant refresh driver.
void UpdateFrameRequestCallbackSchedulingState(nsIPresShell* aOldShell = nullptr);
// Helper for GetScrollingElement/IsScrollingElement.
bool IsPotentiallyScrollable(mozilla::dom::HTMLBodyElement* aBody);
- // Return the same type parent docuement if exists, or return null.
- nsIDocument* GetSameTypeParentDocument(const nsIDocument* aDoc);
-
// Helpers for GetElementsByName.
static bool MatchNameAttribute(mozilla::dom::Element* aElement,
int32_t aNamespaceID,
nsAtom* aAtom, void* aData);
static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
nsCString mReferrer;
nsString mLastModified;
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -920,21 +920,20 @@ EventStateManager::NotifyTargetUserActiv
MOZ_ASSERT(aEvent->mMessage == eKeyUp ||
aEvent->mMessage == eMouseUp ||
aEvent->mMessage == eTouchEnd);
doc->NotifyUserActivation();
// Activate parent document which has same principle on the parent chain.
nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
- nsCOMPtr<nsIDocument> parent =
- doc->GetFirstParentDocumentWithSamePrincipal(principal);
+ nsCOMPtr<nsIDocument> parent = doc->GetSameTypeParentDocument();
while (parent) {
- parent->NotifyUserActivation();
- parent = parent->GetFirstParentDocumentWithSamePrincipal(principal);
+ parent->MaybeNotifyUserActivation(principal);
+ parent = parent->GetSameTypeParentDocument();
}
}
void
EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
{
switch (aEvent->mMessage) {
case eQuerySelectedText: