Bug 1428722 - part2 : move all user-activation implementation details to nsDocument. r=smaug
authorAlastor Wu <alwu@mozilla.com>
Thu, 11 Jan 2018 17:26:30 +0800
changeset 453543 adbad272045dee6f307751ae15037319b4e5d3bc
parent 453542 b9056b64d45b7dbf8dd7e6284e543ea1ada7502b
child 453544 6f9b763bb1c9f03be9ff0420a7b52261306bd227
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1428722
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
dom/base/nsDocument.cpp
dom/base/nsIDocument.h
dom/events/EventStateManager.cpp
dom/webidl/Document.webidl
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -13183,33 +13183,46 @@ 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)
+nsIDocument::NotifyUserActivation()
+{
+  ActivateByUserGesture();
+  // Activate parent document which has same principle on the parent chain.
+  nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
+  nsCOMPtr<nsIDocument> parent = GetSameTypeParentDocument();
+  while (parent) {
+    parent->MaybeActivateByUserGesture(principal);
+    parent = parent->GetSameTypeParentDocument();
+  }
+}
+
+void
+nsIDocument::MaybeActivateByUserGesture(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()
+    ActivateByUserGesture();
+  }
+}
+
+void
+nsIDocument::ActivateByUserGesture()
 {
   if (mUserHasActivatedInteraction) {
     return;
   }
 
   MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug,
           ("Document %p has been activated by user.", this));
   mUserHasActivatedInteraction = true;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3066,31 +3066,23 @@ public:
   }
 
   void SetUserHasInteracted(bool aUserHasInteracted);
   bool UserHasInteracted()
   {
     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();
 
   void ReportHasScrollLinkedEffect();
   bool HasScrollLinkedEffect() const
   {
     return mHasScrollLinkedEffect;
@@ -3270,16 +3262,27 @@ 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();
+
+  // 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,
                                  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
@@ -917,24 +917,16 @@ EventStateManager::NotifyTargetUserActiv
   if (!doc || doc->HasBeenUserActivated()) {
     return;
   }
 
   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->GetSameTypeParentDocument();
-  while (parent) {
-    parent->MaybeNotifyUserActivation(principal);
-    parent = parent->GetSameTypeParentDocument();
-  }
 }
 
 void
 EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
 {
   switch (aEvent->mMessage) {
     case eQuerySelectedText:
     case eQueryTextContent:
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -440,16 +440,23 @@ partial interface Document {
 };
 
 // Extension to give chrome JS the ability to determine whether
 // the user has interacted with the document or not.
 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.
 partial interface Document {
   [Func="IsChromeOrXBL"] readonly attribute boolean hasScriptsBlockedBySandbox;
   [Func="IsChromeOrXBL"] readonly attribute boolean inlineScriptAllowedByCSP;
 };