Bug 1177346 - Various tweaks and debugs draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 21 Nov 2016 10:56:00 -0800
changeset 443455 3259ea1716536d4f73a036c0a83bc8b95032b2b2
parent 442521 6382432b8cc42877d82b8318bd7fa09746f42f2c
child 538061 25944df455fdb69c51b880eb1f2b9553146462ee
push id37003
push userbmo:poirot.alex@gmail.com
push dateThu, 24 Nov 2016 14:25:35 +0000
bugs1177346
milestone53.0a1
Bug 1177346 - Various tweaks and debugs MozReview-Commit-ID: 6SNpRPdsLIm
docshell/base/nsDocShell.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsFocusManager.cpp
dom/base/nsIDocument.h
dom/events/EventDispatcher.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsPresShell.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8795,16 +8795,19 @@ nsDocShell::RestoreFromHistory()
     RefPtr<nsDocShell> parent = GetParentDocshell();
     if (parent) {
       nsCOMPtr<nsIDocument> d = parent->GetDocument();
       if (d) {
         if (d->EventHandlingSuppressed()) {
           document->SuppressEventHandling(nsIDocument::eEvents,
                                           d->EventHandlingSuppressed());
         }
+        if (d->EventHandlingOnlyChrome()) {
+          document->SetEventHandlingOnlyChrome(true);
+        }
 
         // Ick, it'd be nicer to not rewalk all of the subdocs here.
         if (d->AnimationsPaused()) {
           document->SuppressEventHandling(nsIDocument::eAnimationsOnly,
                                           d->AnimationsPaused());
         }
       }
     }
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9096,16 +9096,39 @@ nsIDocument::GetReadyState(nsAString& aR
   case READYSTATE_COMPLETE :
     aReadyState.AssignLiteral(u"complete");
     break;
   default:
     aReadyState.AssignLiteral(u"uninitialized");
   }
 }
 
+static bool
+SetEventHandlingOnlyChromeInDocument(nsIDocument* aDocument, void* aData)
+{
+  bool enable = *(bool*)aData;
+  printf("SetEventHandlingInDocument(%d)\n", enable);
+  aDocument->SetEventHandlingOnlyChrome(enable);
+  return true;
+}
+
+void
+nsDocument::SetEventHandlingOnlyChrome(bool aEnable)
+{
+  mEventsOnlyChrome = aEnable;
+  nsIDocument* doc = static_cast<nsIDocument *>(this);
+  printf("doc.SetEventHandlingOnlyChrome(%d) [%p]\n", aEnable, doc);
+  nsIURI *uri = nsIDocument::GetDocumentURI();
+  if (uri) {
+    printf(" >> this=%p, url='%s')\n",
+           (void*)this, uri->GetSpecOrDefault().get());
+  }
+  EnumerateSubDocuments(SetEventHandlingOnlyChromeInDocument, &aEnable);
+}
+
 namespace {
 
 struct SuppressArgs
 {
   nsIDocument::SuppressionType mWhat;
   uint32_t mIncrease;
 };
 
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -890,16 +890,18 @@ public:
   GetPendingAnimationTracker() final override
   {
     return mPendingAnimationTracker;
   }
 
   virtual mozilla::PendingAnimationTracker*
   GetOrCreatePendingAnimationTracker() override;
 
+  virtual void SetEventHandlingOnlyChrome(bool aEnable) override;
+
   virtual void SuppressEventHandling(SuppressionType aWhat,
                                      uint32_t aIncrease) override;
 
   virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
                                                     bool aFireEvents) override;
 
   void DecreaseEventSuppression() {
     MOZ_ASSERT(mEventsSuppressed);
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2002,16 +2002,19 @@ public:
   {
   }
 
   NS_IMETHOD Run() override
   {
     InternalFocusEvent event(true, mEventMessage);
     event.mFlags.mBubbles = false;
     event.mFlags.mCancelable = false;
+    if (mContext && mContext->Document() && mContext->Document()->EventHandlingOnlyChrome()) {
+      event.mFlags.mOnlyChromeDispatch = true;
+    }
     event.mFromRaise = mWindowRaised;
     event.mIsRefocus = mIsRefocus;
     event.mRelatedTarget = mRelatedTarget;
     return EventDispatcher::Dispatch(mTarget, mContext, &event);
   }
 
   nsCOMPtr<nsISupports>   mTarget;
   RefPtr<nsPresContext> mContext;
@@ -2045,16 +2048,28 @@ public:
         nullptr;
     // Blink does not check that focus is the same after blur, but WebKit does.
     // Opt to follow Blink's behavior (see bug 687787).
     if (mEventMessage == eFocusOut ||
         originalWindowFocus == mOriginalFocusedContent) {
       InternalFocusEvent event(true, mEventMessage);
       event.mFlags.mBubbles = true;
       event.mFlags.mCancelable = false;
+      if (mOriginalFocusedContent) {
+        nsCOMPtr<nsIDocument> doc = mOriginalFocusedContent->GetComposedDoc();
+        if (doc) {
+          if (doc->EventHandlingOnlyChrome()) {
+            event.mFlags.mOnlyChromeDispatch = true;
+          }
+          doc = doc->GetSubDocumentFor(mOriginalFocusedContent);
+          if (doc && doc->EventHandlingOnlyChrome()) {
+            event.mFlags.mOnlyChromeDispatch = true;
+          }
+        }
+      }
       event.mRelatedTarget = mRelatedTarget;
       return EventDispatcher::Dispatch(mTarget, mContext, &event);
     }
     return NS_OK;
   }
 
   nsCOMPtr<nsISupports>        mTarget;
   RefPtr<nsPresContext>        mContext;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2142,19 +2142,17 @@ public:
   enum SuppressionType {
     eAnimationsOnly = 0x1,
 
     // Note that suppressing events also suppresses animation frames, so
     // there's no need to split out events in its own bitmask.
     eEvents = 0x3,
   };
 
-  virtual void SetEventHandlingOnlyChrome(bool aEnable) {
-    mEventsOnlyChrome = aEnable;
-  };
+  virtual void SetEventHandlingOnlyChrome(bool aEnable) = 0;
   uint32_t EventHandlingOnlyChrome() const { return mEventsOnlyChrome; }
 
   /**
    * Prevents user initiated events from being dispatched to the document and
    * subdocuments.
    */
   virtual void SuppressEventHandling(SuppressionType aWhat,
                                      uint32_t aIncrease = 1) = 0;
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -636,28 +636,57 @@ EventDispatcher::Dispatch(nsISupports* a
       NS_ENSURE_STATE(newTarget);
 
       aEvent->mOriginalTarget = target;
       target = newTarget;
       retargeted = true;
     }
   }
 
-  if (aEvent->mFlags.mOnlyChromeDispatch) {
+  nsCOMPtr<nsIDocument> doc;
+  nsIURI *uri;
+  if (target) {
+    doc = do_QueryInterface(target);
+    if (!doc) {
+      nsCOMPtr<nsINode> node = do_QueryInterface(target);
+      if (node) {
+        doc = node->OwnerDoc();
+      } else {
+        /*
+        nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(target);
+        if (window) {
+          doc = window->GetExtantDoc();
+        }
+        */
+      }
+    }
+    if (doc) {
+      uri = doc->GetDocumentURI();
+    }
+  }
+  printf("Dispatch class:%d (onlyChrome, flag:%d, pres:%d, target:%d) uri:%s\n", aEvent->mClass, aEvent->mFlags.mOnlyChromeDispatch,
+    aPresContext && aPresContext->Document() ? aPresContext->Document()->EventHandlingOnlyChrome() : -1,
+    doc ? doc->EventHandlingOnlyChrome() : -1,
+    uri ? uri->GetSpecOrDefault().get() : "?");
+
+  if (aEvent->mFlags.mOnlyChromeDispatch ||
+      (aPresContext && aPresContext->Document() && aPresContext->Document()->EventHandlingOnlyChrome()) ||
+      (doc && doc->EventHandlingOnlyChrome())) {
     nsCOMPtr<nsIDocument> doc;
     if (!IsEventTargetChrome(target, getter_AddRefs(doc)) && doc) {
       nsPIDOMWindowInner* win = doc->GetInnerWindow();
       // If we can't dispatch the event to chrome, do nothing.
       EventTarget* piTarget = win ? win->GetParentTarget() : nullptr;
       if (!piTarget) {
         return NS_OK;
       }
 
       // Set the target to be the original dispatch target,
       aEvent->mTarget = target;
+      printf("Dispatch retarget to chromeeventhandler\n");
       // but use chrome event handler or TabChildGlobal for event target chain.
       target = piTarget;
     } else if (NS_WARN_IF(!doc)) {
       return NS_ERROR_UNEXPECTED;
     }
   }
 
 #ifdef DEBUG
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -603,16 +603,21 @@ nsDocumentViewer::SyncParentSubDocMap()
   }
 
   if (mDocument &&
       parent_doc->GetSubDocumentFor(element) != mDocument &&
       parent_doc->EventHandlingSuppressed()) {
     mDocument->SuppressEventHandling(nsIDocument::eEvents,
                                      parent_doc->EventHandlingSuppressed());
   }
+  if (mDocument &&
+      parent_doc->GetSubDocumentFor(element) != mDocument &&
+      parent_doc->EventHandlingOnlyChrome()) {
+    mDocument->SetEventHandlingOnlyChrome(true);
+  }
   return parent_doc->SetSubDocumentFor(element, mDocument);
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::SetContainer(nsIDocShell* aContainer)
 {
   mContainer = static_cast<nsDocShell*>(aContainer);
   if (mPresContext) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -7360,16 +7360,22 @@ PresShell::HandleEvent(nsIFrame* aFrame,
   } else if (aEvent->AsKeyboardEvent()) {
     type = SourceEventType::Key;
   }
   AutoSourceEvent taskTracerEvent(type);
 #endif
 
   NS_ASSERTION(aFrame, "aFrame should be not null");
 
+  printf("HandleEvent1(%d)\n", mDocument->EventHandlingOnlyChrome());
+
+  if (mDocument->EventHandlingOnlyChrome()) {
+    aEvent->mFlags.mOnlyChromeDispatch = true;
+  }
+
   if (sPointerEventEnabled) {
     nsWeakFrame weakFrame(aFrame);
     nsCOMPtr<nsIContent> targetContent;
     DispatchPointerFromMouseOrTouch(this, aFrame, aEvent, aDontRetargetEvents,
                                     aEventStatus,
                                     getter_AddRefs(targetContent));
     if (!weakFrame.IsAlive()) {
       if (targetContent) {
@@ -7496,16 +7502,23 @@ PresShell::HandleEvent(nsIFrame* aFrame,
           return NS_OK;
 
         nsCOMPtr<nsIPresShell> shell = frame->PresContext()->GetPresShell();
         return shell->HandleEvent(frame, aEvent, true, aEventStatus);
       }
     }
   }
 
+  // Force dispatching only to chrome handler events when document is flaged to
+  // do so. Typically when the js debugger is paused.
+  printf("HandleEvent2(%d)\n", mDocument->EventHandlingOnlyChrome());
+  if (mDocument->EventHandlingOnlyChrome()) {
+    aEvent->mFlags.mOnlyChromeDispatch = true;
+  }
+
   if (aEvent->mClass == eKeyboardEventClass &&
       mDocument && mDocument->EventHandlingSuppressed()) {
     if (aEvent->mMessage == eKeyDown) {
       mNoDelayedKeyEvents = true;
     } else if (!mNoDelayedKeyEvents) {
       DelayedEvent* event = new DelayedKeyEvent(aEvent->AsKeyboardEvent());
       if (!mDelayedEvents.AppendElement(event)) {
         delete event;
@@ -7793,18 +7806,18 @@ PresShell::HandleEvent(nsIFrame* aFrame,
                                                   pointerEvent->mIsPrimary);
           }
         }
       }
     }
 
     // Force dispatching only to chrome handler events using coordinates.
     // Typically when the js debugger is paused.
-    if (mDocument->EventHandlingOnlyChrome() ||
-        (frame && frame->PresContext()->Document()->EventHandlingOnlyChrome())) {
+    printf("HandleEvent3(%d)\n", frame->PresContext()->Document()->EventHandlingOnlyChrome());
+    if (frame && frame->PresContext()->Document()->EventHandlingOnlyChrome()) {
       aEvent->mFlags.mOnlyChromeDispatch = true;
     }
 
     // Suppress mouse event if it's being targeted at an element inside
     // a document which needs events suppressed
     if (aEvent->mClass == eMouseEventClass &&
         frame->PresContext()->Document()->EventHandlingSuppressed()) {
       if (aEvent->mMessage == eMouseDown) {
@@ -7928,22 +7941,16 @@ PresShell::HandleEvent(nsIFrame* aFrame,
       }
     }
 
     return rv;
   }
 
   nsresult rv = NS_OK;
 
-  // Force dispatching only to chrome handler events when document is flaged to
-  // do so. Typically when the js debugger is paused.
-  if (mDocument->EventHandlingOnlyChrome()) {
-    aEvent->mFlags.mOnlyChromeDispatch = true;
-  }
-
   if (frame) {
     PushCurrentEventInfo(nullptr, nullptr);
 
     // key and IME related events go to the focused frame in this DOM window.
     if (aEvent->IsTargetedAtFocusedContent()) {
       mCurrentEventContent = nullptr;
 
       nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow();
@@ -9922,28 +9929,30 @@ PresShell::DelayedMouseEvent::DelayedMou
 {
   WidgetMouseEvent* mouseEvent =
     new WidgetMouseEvent(aEvent->IsTrusted(),
                          aEvent->mMessage,
                          aEvent->mWidget,
                          aEvent->mReason,
                          aEvent->mContextMenuTrigger);
   mouseEvent->AssignMouseEventData(*aEvent, false);
+  mouseEvent->mFlags.mOnlyChromeDispatch = aEvent->mFlags.mOnlyChromeDispatch;
   mEvent = mouseEvent;
 }
 
 PresShell::DelayedKeyEvent::DelayedKeyEvent(WidgetKeyboardEvent* aEvent) :
   DelayedInputEvent()
 {
   WidgetKeyboardEvent* keyEvent =
     new WidgetKeyboardEvent(aEvent->IsTrusted(),
                             aEvent->mMessage,
                             aEvent->mWidget);
   keyEvent->AssignKeyEventData(*aEvent, false);
   keyEvent->mFlags.mIsSynthesizedForTests = aEvent->mFlags.mIsSynthesizedForTests;
+  keyEvent->mFlags.mOnlyChromeDispatch = aEvent->mFlags.mOnlyChromeDispatch;
   mEvent = keyEvent;
 }
 
 // Start of DEBUG only code
 
 #ifdef DEBUG
 
 static void