Bug 1200980 part.2 QueryContentEvent should be handled via IMEContentObserver if there is an instance of it r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 08 Sep 2015 12:54:14 +0900
changeset 293865 92127319836ac2c4704c92a40e9d4967fcac93ae
parent 293864 363401fd972c08d2321022704d16f9f05442bc5f
child 293866 62a79bc9cf9eb720a0f9cadf797a0186a54c253b
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1200980
milestone43.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 1200980 part.2 QueryContentEvent should be handled via IMEContentObserver if there is an instance of it r=smaug
dom/events/ContentEventHandler.cpp
dom/events/ContentEventHandler.h
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
dom/events/IMEContentObserver.cpp
dom/events/IMEContentObserver.h
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -787,16 +787,44 @@ ContentEventHandler::GetLineBreakType(Wi
 
 /* static */ LineBreakType
 ContentEventHandler::GetLineBreakType(bool aUseNativeLineBreak)
 {
   return aUseNativeLineBreak ?
     LINE_BREAK_TYPE_NATIVE : LINE_BREAK_TYPE_XP;
 }
 
+nsresult
+ContentEventHandler::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
+{
+  switch (aEvent->mMessage) {
+    case NS_QUERY_SELECTED_TEXT:
+      return OnQuerySelectedText(aEvent);
+    case NS_QUERY_TEXT_CONTENT:
+      return OnQueryTextContent(aEvent);
+    case NS_QUERY_CARET_RECT:
+      return OnQueryCaretRect(aEvent);
+    case NS_QUERY_TEXT_RECT:
+      return OnQueryTextRect(aEvent);
+    case NS_QUERY_EDITOR_RECT:
+      return OnQueryEditorRect(aEvent);
+    case NS_QUERY_CONTENT_STATE:
+      return OnQueryContentState(aEvent);
+    case NS_QUERY_SELECTION_AS_TRANSFERABLE:
+      return OnQuerySelectionAsTransferable(aEvent);
+    case NS_QUERY_CHARACTER_AT_POINT:
+      return OnQueryCharacterAtPoint(aEvent);
+    case NS_QUERY_DOM_WIDGET_HITTEST:
+      return OnQueryDOMWidgetHittest(aEvent);
+    default:
+      return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  return NS_OK;
+}
+
 // Similar to nsFrameSelection::GetFrameForNodeOffset,
 // but this is more flexible for OnQueryTextRect to use
 static nsresult GetFrameForTextRect(nsINode* aNode,
                                     int32_t aNodeOffset,
                                     bool aHint,
                                     nsIFrame** aReturnFrame)
 {
   NS_ENSURE_TRUE(aNode && aNode->IsNodeOfType(nsINode::eCONTENT),
--- a/dom/events/ContentEventHandler.h
+++ b/dom/events/ContentEventHandler.h
@@ -34,16 +34,19 @@ enum LineBreakType
 
 class MOZ_STACK_CLASS ContentEventHandler
 {
 public:
   typedef dom::Selection Selection;
 
   explicit ContentEventHandler(nsPresContext* aPresContext);
 
+  // Handle aEvent in the current process.
+  nsresult HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
+
   // NS_QUERY_SELECTED_TEXT event handler
   nsresult OnQuerySelectedText(WidgetQueryContentEvent* aEvent);
   // NS_QUERY_TEXT_CONTENT event handler
   nsresult OnQueryTextContent(WidgetQueryContentEvent* aEvent);
   // NS_QUERY_CARET_RECT event handler
   nsresult OnQueryCaretRect(WidgetQueryContentEvent* aEvent);
   // NS_QUERY_TEXT_RECT event handler
   nsresult OnQueryTextRect(WidgetQueryContentEvent* aEvent);
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -537,16 +537,21 @@ EventStateManager::PreHandleEvent(nsPres
     sLastScreenPoint =
       UIEvent::CalculateScreenPoint(aPresContext, aEvent);
     sLastClientPoint =
       UIEvent::CalculateClientPoint(aPresContext, aEvent, nullptr);
   }
 
   *aStatus = nsEventStatus_eIgnore;
 
+  if (aEvent->mClass == eQueryContentEventClass) {
+    HandleQueryContentEvent(aEvent->AsQueryContentEvent());
+    return NS_OK;
+  }
+
   switch (aEvent->mMessage) {
   case eContextMenu:
     if (sIsPointerLocked) {
       return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
     break;
   case eMouseDown: {
     switch (mouseEvent->button) {
@@ -733,83 +738,16 @@ EventStateManager::PreHandleEvent(nsPres
       // Init lineOrPageDelta values for line scroll events for some devices
       // on some platforms which might dispatch wheel events which don't have
       // lineOrPageDelta values.  And also, if delta values are customized by
       // prefs, this recomputes them.
       DeltaAccumulator::GetInstance()->
         InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
     }
     break;
-  case NS_QUERY_SELECTED_TEXT:
-    DoQuerySelectedText(aEvent->AsQueryContentEvent());
-    break;
-  case NS_QUERY_TEXT_CONTENT:
-    {
-      if (RemoteQueryContentEvent(aEvent)) {
-        break;
-      }
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryTextContent(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_CARET_RECT:
-    {
-      if (RemoteQueryContentEvent(aEvent)) {
-        break;
-      }
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryCaretRect(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_TEXT_RECT:
-    {
-      if (RemoteQueryContentEvent(aEvent)) {
-        break;
-      }
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryTextRect(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_EDITOR_RECT:
-    {
-      if (RemoteQueryContentEvent(aEvent)) {
-        break;
-      }
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryEditorRect(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_CONTENT_STATE:
-    {
-      // XXX remote event
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryContentState(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_SELECTION_AS_TRANSFERABLE:
-    {
-      // XXX remote event
-      ContentEventHandler handler(mPresContext);
-      handler.OnQuerySelectionAsTransferable(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_CHARACTER_AT_POINT:
-    {
-      // XXX remote event
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryCharacterAtPoint(aEvent->AsQueryContentEvent());
-    }
-    break;
-  case NS_QUERY_DOM_WIDGET_HITTEST:
-    {
-      // XXX remote event
-      ContentEventHandler handler(mPresContext);
-      handler.OnQueryDOMWidgetHittest(aEvent->AsQueryContentEvent());
-    }
-    break;
   case NS_SELECTION_SET:
     IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
                                           aEvent->AsSelectionEvent());
     break;
   case NS_CONTENT_COMMAND_CUT:
   case NS_CONTENT_COMMAND_COPY:
   case NS_CONTENT_COMMAND_PASTE:
   case NS_CONTENT_COMMAND_DELETE:
@@ -827,27 +765,63 @@ EventStateManager::PreHandleEvent(nsPres
     break;
   case NS_COMPOSITION_START:
     if (aEvent->mFlags.mIsTrusted) {
       // If the event is trusted event, set the selected text to data of
       // composition event.
       WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent();
       WidgetQueryContentEvent selectedText(true, NS_QUERY_SELECTED_TEXT,
                                            compositionEvent->widget);
-      DoQuerySelectedText(&selectedText);
+      HandleQueryContentEvent(&selectedText);
       NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text");
       compositionEvent->mData = selectedText.mReply.mString;
     }
     break;
   default:
     break;
   }
   return NS_OK;
 }
 
+void
+EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
+{
+  switch (aEvent->mMessage) {
+    case NS_QUERY_SELECTED_TEXT:
+    case NS_QUERY_TEXT_CONTENT:
+    case NS_QUERY_CARET_RECT:
+    case NS_QUERY_TEXT_RECT:
+    case NS_QUERY_EDITOR_RECT:
+      if (!IsTargetCrossProcess(aEvent)) {
+        break;
+      }
+      // Will not be handled locally, remote the event
+      GetCrossProcessTarget()->HandleQueryContentEvent(*aEvent);
+      return;
+    // Following events have not been supported in e10s mode yet.
+    case NS_QUERY_CONTENT_STATE:
+    case NS_QUERY_SELECTION_AS_TRANSFERABLE:
+    case NS_QUERY_CHARACTER_AT_POINT:
+    case NS_QUERY_DOM_WIDGET_HITTEST:
+      break;
+    default:
+      return;
+  }
+
+  // If there is an IMEContentObserver, we need to handle QueryContentEvent
+  // with it.
+  if (mIMEContentObserver) {
+    mIMEContentObserver->HandleQueryContentEvent(aEvent);
+    return;
+  }
+
+  ContentEventHandler handler(mPresContext);
+  handler.HandleQueryContentEvent(aEvent);
+}
+
 // static
 int32_t
 EventStateManager::GetAccessModifierMaskFor(nsISupports* aDocShell)
 {
   nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(aDocShell));
   if (!treeItem)
     return -1; // invalid modifier
 
@@ -3363,28 +3337,16 @@ EventStateManager::PostHandleEvent(nsPre
 
   //Reset target frame to null to avoid mistargeting after reentrant event
   mCurrentTarget = nullptr;
   mCurrentTargetContent = nullptr;
 
   return ret;
 }
 
-bool
-EventStateManager::RemoteQueryContentEvent(WidgetEvent* aEvent)
-{
-  WidgetQueryContentEvent* queryEvent = aEvent->AsQueryContentEvent();
-  if (!IsTargetCrossProcess(queryEvent)) {
-    return false;
-  }
-  // Will not be handled locally, remote the event
-  GetCrossProcessTarget()->HandleQueryContentEvent(*queryEvent);
-  return true;
-}
-
 TabParent*
 EventStateManager::GetCrossProcessTarget()
 {
   return IMEStateManager::GetActiveTabParent();
 }
 
 bool
 EventStateManager::IsTargetCrossProcess(WidgetGUIEvent* aEvent)
@@ -5185,26 +5147,16 @@ EventStateManager::DoContentCommandScrol
   }
 
   // The caller may want synchronous scrolling.
   sf->ScrollBy(pt, scrollUnit, nsIScrollableFrame::INSTANT);
   return NS_OK;
 }
 
 void
-EventStateManager::DoQuerySelectedText(WidgetQueryContentEvent* aEvent)
-{
-  if (RemoteQueryContentEvent(aEvent)) {
-    return;
-  }
-  ContentEventHandler handler(mPresContext);
-  handler.OnQuerySelectedText(aEvent);
-}
-
-void
 EventStateManager::SetActiveManager(EventStateManager* aNewESM,
                                     nsIContent* aContent)
 {
   if (sActiveESM && aNewESM != sActiveESM) {
     sActiveESM->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE);
   }
   sActiveESM = aNewESM;
   if (sActiveESM && aContent) {
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -804,30 +804,29 @@ protected:
    * BeginTrackingDragGesture). aEvent->widget must be
    * mCurrentTarget->GetNearestWidget().
    */
   void FillInEventFromGestureDown(WidgetMouseEvent* aEvent);
 
   nsresult DoContentCommandEvent(WidgetContentCommandEvent* aEvent);
   nsresult DoContentCommandScrollEvent(WidgetContentCommandEvent* aEvent);
 
-  void DoQuerySelectedText(WidgetQueryContentEvent* aEvent);
-
-  bool RemoteQueryContentEvent(WidgetEvent* aEvent);
   dom::TabParent *GetCrossProcessTarget();
   bool IsTargetCrossProcess(WidgetGUIEvent* aEvent);
 
   bool DispatchCrossProcessEvent(WidgetEvent* aEvent,
                                  nsFrameLoader* aRemote,
                                  nsEventStatus *aStatus);
   bool HandleCrossProcessEvent(WidgetEvent* aEvent,
                                nsEventStatus* aStatus);
 
   void ReleaseCurrentIMEContentObserver();
 
+  void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
+
 private:
   static inline void DoStateChange(dom::Element* aElement,
                                    EventStates aState, bool aAddState);
   static inline void DoStateChange(nsIContent* aContent, EventStates aState,
                                    bool aAddState);
   static void UpdateAncestorState(nsIContent* aStartNode,
                                   nsIContent* aStopBefore,
                                   EventStates aState,
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -42,16 +42,43 @@ using namespace widget;
 PRLogModuleInfo* sIMECOLog = nullptr;
 
 static const char*
 ToChar(bool aBool)
 {
   return aBool ? "true" : "false";
 }
 
+static const char*
+ToChar(EventMessage aEventMessage)
+{
+  switch (aEventMessage) {
+    case NS_QUERY_SELECTED_TEXT:
+      return "NS_QUERY_SELECTED_TEXT";
+    case NS_QUERY_TEXT_CONTENT:
+      return "NS_QUERY_TEXT_CONTENT";
+    case NS_QUERY_CARET_RECT:
+      return "NS_QUERY_CARET_RECT";
+    case NS_QUERY_TEXT_RECT:
+      return "NS_QUERY_TEXT_RECT";
+    case NS_QUERY_EDITOR_RECT:
+      return "NS_QUERY_EDITOR_RECT";
+    case NS_QUERY_CONTENT_STATE:
+      return "NS_QUERY_CONTENT_STATE";
+    case NS_QUERY_SELECTION_AS_TRANSFERABLE:
+      return "NS_QUERY_SELECTION_AS_TRANSFERABLE";
+    case NS_QUERY_CHARACTER_AT_POINT:
+      return "NS_QUERY_CHARACTER_AT_POINT";
+    case NS_QUERY_DOM_WIDGET_HITTEST:
+      return "NS_QUERY_DOM_WIDGET_HITTEST";
+    default:
+      return "Unsupprted message";
+  }
+}
+
 class WritingModeToString final : public nsAutoCString
 {
 public:
   explicit WritingModeToString(const WritingMode& aWritingMode)
   {
     if (!aWritingMode.IsVertical()) {
       AssignLiteral("Horizontal");
       return;
@@ -525,16 +552,27 @@ IMEContentObserver::Reflow(DOMHighResTim
 NS_IMETHODIMP
 IMEContentObserver::ReflowInterruptible(DOMHighResTimeStamp aStart,
                                         DOMHighResTimeStamp aEnd)
 {
   MaybeNotifyIMEOfPositionChange();
   return NS_OK;
 }
 
+nsresult
+IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
+{
+  MOZ_LOG(sIMECOLog, LogLevel::Debug,
+    ("IMECO: 0x%p IMEContentObserver::HandleQueryContentEvent(aEvent={ "
+     "mMessage=%s })", this, ToChar(aEvent->mMessage)));
+
+  ContentEventHandler handler(GetPresContext());
+  return handler.HandleQueryContentEvent(aEvent);
+}
+
 bool
 IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
                                        WidgetMouseEvent* aMouseEvent)
 {
   if (!mUpdatePreference.WantMouseButtonEventOnChar()) {
     return false;
   }
   if (!aMouseEvent->mFlags.mIsTrusted ||
--- a/dom/events/IMEContentObserver.h
+++ b/dom/events/IMEContentObserver.h
@@ -61,16 +61,18 @@ public:
   NS_DECL_NSIREFLOWOBSERVER
 
   // nsIScrollObserver
   virtual void ScrollPositionChanged() override;
 
   bool OnMouseButtonEvent(nsPresContext* aPresContext,
                           WidgetMouseEvent* aMouseEvent);
 
+  nsresult HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
+
   void Init(nsIWidget* aWidget, nsPresContext* aPresContext,
             nsIContent* aContent, nsIEditor* aEditor);
   void Destroy();
   /**
    * IMEContentObserver is stored by EventStateManager during observing.
    * DisconnectFromEventStateManager() is called when EventStateManager stops
    * storing the instance.
    */