Bug 636905 - part 1: add a flag that tracks whether the user has interacted with a given document, r?smaug
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1527,17 +1527,18 @@ nsIDocument::nsIDocument()
// &&-ed in, this is safe.
mAllowDNSPrefetch(true),
mIsBeingUsedAsImage(false),
mHasLinksToUpdate(false),
mFontFaceSetDirty(true),
mGetUserFontSetCalled(false),
mPostedFlushUserFontSet(false),
mPartID(0),
- mDidFireDOMContentLoaded(true)
+ mDidFireDOMContentLoaded(true),
+ mUserHasInteracted(false)
{
SetInDocument();
PR_INIT_CLIST(&mDOMMediaQueryLists);
}
// NOTE! nsDocument::operator new() zeroes out all members, so don't
// bother initializing members to 0.
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2597,16 +2597,26 @@ public:
void SetDocumentAndPageUseCounter(mozilla::UseCounter aUseCounter)
{
SetDocumentUseCounter(aUseCounter);
SetPageUseCounter(aUseCounter);
}
void PropagateUseCounters(nsIDocument* aParentDocument);
+ void SetUserHasInteracted(bool aUserHasInteracted)
+ {
+ mUserHasInteracted = aUserHasInteracted;
+ }
+
+ bool UserHasInteracted()
+ {
+ return mUserHasInteracted;
+ }
+
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
return mUseCounters[aUseCounter];
}
void SetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
{
@@ -3002,16 +3012,19 @@ protected:
// Flags for use counters used directly by this document.
std::bitset<mozilla::eUseCounter_Count> mUseCounters;
// Flags for use counters used by any child documents of this document.
std::bitset<mozilla::eUseCounter_Count> mChildDocumentUseCounters;
// Flags for whether we've notified our top-level "page" of a use counter
// for this child document.
std::bitset<mozilla::eUseCounter_Count> mNotifiedPageForUseCounter;
+
+ // Whether the user has interacted with the document or not:
+ bool mUserHasInteracted;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
/**
* mozAutoSubtreeModified batches DOM mutations so that a DOMSubtreeModified
* event is dispatched, if necessary, when the outermost mozAutoSubtreeModified
* object is deleted.
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -498,26 +498,42 @@ EventStateManager::PreHandleEvent(nsPres
// Do not take account eMouseEnterIntoWidget/ExitFromWidget so that loading
// a page when user is not active doesn't change the state to active.
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
if (aEvent->mFlags.mIsTrusted &&
((mouseEvent && mouseEvent->IsReal() &&
mouseEvent->mMessage != eMouseEnterIntoWidget &&
mouseEvent->mMessage != eMouseExitFromWidget) ||
aEvent->mClass == eWheelEventClass ||
+ aEvent->mClass == ePointerEventClass ||
+ aEvent->mClass == eTouchEventClass ||
aEvent->mClass == eKeyboardEventClass)) {
if (gMouseOrKeyboardEventCounter == 0) {
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (obs) {
obs->NotifyObservers(nullptr, "user-interaction-active", nullptr);
UpdateUserActivityTimer();
}
}
++gMouseOrKeyboardEventCounter;
+
+
+ nsCOMPtr<nsINode> node = do_QueryInterface(aTargetContent);
+ if (node &&
+ (aEvent->mMessage == eKeyUp || aEvent->mMessage == eMouseUp ||
+ aEvent->mMessage == eWheel || aEvent->mMessage == eTouchEnd ||
+ aEvent->mMessage == ePointerUp)) {
+ nsIDocument* doc = node->OwnerDoc();
+ while (doc && !doc->UserHasInteracted()) {
+ doc->SetUserHasInteracted(true);
+ doc = nsContentUtils::IsChildOfSameType(doc) ?
+ doc->GetParentDocument() : nullptr;
+ }
+ }
}
WheelTransaction::OnEvent(aEvent);
// Focus events don't necessarily need a frame.
if (!mCurrentTarget && !aTargetContent) {
NS_ERROR("mCurrentTarget and aTargetContent are null");
return NS_ERROR_NULL_POINTER;
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -387,15 +387,21 @@ partial interface Document {
/**
* Removes the element inserted into the CanvasFrame given an AnonymousContent
* instance.
*/
[ChromeOnly, Throws]
void removeAnonymousContent(AnonymousContent aContent);
};
+// 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;
+};
+
Document implements XPathEvaluator;
Document implements GlobalEventHandlers;
Document implements TouchEventHandlers;
Document implements ParentNode;
Document implements OnErrorEventHandlerForNodes;
Document implements GeometryUtils;
Document implements FontFaceSource;