From cb52b8db6359a9b9c726810d48826b67c6c5993d Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Thu, 11 Jan 2018 17:26:30 +0800 Subject: [PATCH] Bug 1428722 - part2 : move all user-activation implementation details to nsDocument. r=smaug In order to write tests, I would like to create an method that allows chorome js can directly set the user-activation flag. Therefore, I need to move all these details into nsDocument, then we could easily simulate the user activation. MozReview-Commit-ID: 5JrCoQc0vF7 --HG-- extra : rebase_source : 256ff2993ef754dc51409e7e444b868a3302bd65 --- dom/base/nsDocument.cpp | 19 ++++++++++++++++--- dom/base/nsIDocument.h | 23 +++++++++++++---------- dom/events/EventStateManager.cpp | 8 -------- dom/webidl/Document.webidl | 7 +++++++ 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 1cad2b659ee5..56765a519f7a 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -13188,7 +13188,20 @@ nsIDocument::SetUserHasInteracted(bool aUserHasInteracted) } void -nsIDocument::MaybeNotifyUserActivation(nsIPrincipal* aPrincipal) +nsIDocument::NotifyUserActivation() +{ + ActivateByUserGesture(); + // Activate parent document which has same principle on the parent chain. + nsCOMPtr principal = NodePrincipal(); + nsCOMPtr parent = GetSameTypeParentDocument(); + while (parent) { + parent->MaybeActivateByUserGesture(principal); + parent = parent->GetSameTypeParentDocument(); + } +} + +void +nsIDocument::MaybeActivateByUserGesture(nsIPrincipal* aPrincipal) { bool isEqual = false; nsresult rv = aPrincipal->Equals(NodePrincipal(), &isEqual); @@ -13199,12 +13212,12 @@ nsIDocument::MaybeNotifyUserActivation(nsIPrincipal* aPrincipal) // 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(); + ActivateByUserGesture(); } } void -nsIDocument::NotifyUserActivation() +nsIDocument::ActivateByUserGesture() { if (mUserHasActivatedInteraction) { return; diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index f648974ae341..ce3c8afd8a9d 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -3071,21 +3071,13 @@ public: return mUserHasInteracted; } - // This would be called when document get activated by specific user gestures. + // This would be called when document get activated by specific user gestures + // and propagate the user activation flag to its parent. 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(); @@ -3275,6 +3267,17 @@ protected: // Helper for GetScrollingElement/IsScrollingElement. bool IsPotentiallyScrollable(mozilla::dom::HTMLBodyElement* aBody); + // 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); + + // Activate the flag 'mUserHasActivatedInteraction' by specific user gestures. + void ActivateByUserGesture(); + void MaybeActivateByUserGesture(nsIPrincipal* aPrincipal); + // Helpers for GetElementsByName. static bool MatchNameAttribute(mozilla::dom::Element* aElement, int32_t aNamespaceID, diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index bca3d57e8663..66b686dcf302 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -922,14 +922,6 @@ EventStateManager::NotifyTargetUserActivation(WidgetEvent* aEvent, aEvent->mMessage == eMouseUp || aEvent->mMessage == eTouchEnd); doc->NotifyUserActivation(); - - // Activate parent document which has same principle on the parent chain. - nsCOMPtr principal = doc->NodePrincipal(); - nsCOMPtr parent = doc->GetSameTypeParentDocument(); - while (parent) { - parent->MaybeNotifyUserActivation(principal); - parent = parent->GetSameTypeParentDocument(); - } } void diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl index 8d2a7ac085db..40422518f530 100644 --- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -445,6 +445,13 @@ partial interface Document { [ChromeOnly] readonly attribute boolean userHasInteracted; }; +// Extension to give chrome JS the ability to simulate activate the docuement +// by user gesture. +partial interface Document { + [ChromeOnly] + void notifyUserActivation(); +}; + // Extension to give chrome and XBL JS the ability to determine whether // the document is sandboxed without permission to run scripts // and whether inline scripts are blocked by the document's CSP.