Bug 806996 part.5 nsEditor::PostCreate() should call nsIMEStateManager::UpdateIMEState() rather than nsIMEStateManager::OnChangeFocus() when it already has focus r=ehsan
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 09 Nov 2012 17:40:39 +0900
changeset 112795 73a92a915ce3597d7be08e7b748d32fb34f61825
parent 112794 c6e3a6eeb3c1d80fcc8faa4ca410e5bb3ac6c259
child 112796 92701702794263c5fec380e48099eba7294c5fb7
push id23838
push usereakhgari@mozilla.com
push dateFri, 09 Nov 2012 15:21:51 +0000
treeherdermozilla-central@c39596b46863 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs806996
milestone19.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 806996 part.5 nsEditor::PostCreate() should call nsIMEStateManager::UpdateIMEState() rather than nsIMEStateManager::OnChangeFocus() when it already has focus r=ehsan
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditor.h
editor/libeditor/base/nsEditorEventListener.cpp
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -304,35 +304,33 @@ nsEditor::PostCreate()
                        SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
                        false);
     }
   }
 
   // update nsTextStateManager and caret if we have focus
   nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
   if (focusedContent) {
-    nsCOMPtr<nsIPresShell> ps = GetPresShell();
-    NS_ASSERTION(ps, "no pres shell even though we have focus");
-    NS_ENSURE_TRUE(ps, NS_ERROR_UNEXPECTED);
-    nsPresContext* pc = ps->GetPresContext(); 
-
-    nsIMEStateManager::OnChangeFocus(pc, focusedContent,
-                                     InputContextAction::CAUSE_UNKNOWN);
-
     nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(focusedContent);
     if (target) {
       InitializeSelection(target);
     }
 
     // If the text control gets reframed during focus, Focus() would not be
     // called, so take a chance here to see if we need to spell check the text
     // control.
     nsEditorEventListener* listener =
       reinterpret_cast<nsEditorEventListener*> (mEventListener.get());
     listener->SpellCheckIfNeeded();
+
+    IMEState newState;
+    rv = GetPreferredIMEState(&newState);
+    NS_ENSURE_SUCCESS(rv, NS_OK);
+    nsCOMPtr<nsIContent> content = GetFocusedContentForIME();
+    nsIMEStateManager::UpdateIMEState(newState, content);
   }
   return NS_OK;
 }
 
 /* virtual */
 void
 nsEditor::CreateEventListeners()
 {
@@ -479,26 +477,33 @@ nsEditor::SetFlags(uint32_t aFlags)
   }
 
   // The flag change may cause the spellchecker state change
   if (CanEnableSpellCheck() != spellcheckerWasEnabled) {
     nsresult rv = SyncRealTimeSpell();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  // If this is called from PostCreate(), it will update the IME state if it's
+  // necessary.
+  if (!mDidPostCreate) {
+    return NS_OK;
+  }
+
   // Might be changing editable state, so, we need to reset current IME state
   // if we're focused and the flag change causes IME state change.
   nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
   if (focusedContent) {
     IMEState newState;
     nsresult rv = GetPreferredIMEState(&newState);
     if (NS_SUCCEEDED(rv)) {
       // NOTE: When the enabled state isn't going to be modified, this method
       // is going to do nothing.
-      nsIMEStateManager::UpdateIMEState(newState, focusedContent);
+      nsCOMPtr<nsIContent> content = GetFocusedContentForIME();
+      nsIMEStateManager::UpdateIMEState(newState, content);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEditor::GetIsSelectionEditable(bool *aIsSelectionEditable)
@@ -5212,16 +5217,22 @@ nsEditor::GetFocusedContent()
 
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   NS_ENSURE_TRUE(fm, nullptr);
 
   nsCOMPtr<nsIContent> content = fm->GetFocusedContent();
   return SameCOMIdentity(content, piTarget) ? content.forget() : nullptr;
 }
 
+already_AddRefed<nsIContent>
+nsEditor::GetFocusedContentForIME()
+{
+  return GetFocusedContent();
+}
+
 bool
 nsEditor::IsActiveInDOMWindow()
 {
   nsCOMPtr<nsIDOMEventTarget> piTarget = GetDOMEventTarget();
   if (!piTarget) {
     return false;
   }
 
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -737,16 +737,20 @@ public:
   }
 
   // Get the input event target. This might return null.
   virtual already_AddRefed<nsIContent> GetInputEventTargetContent() = 0;
 
   // Get the focused content, if we're focused.  Returns null otherwise.
   virtual already_AddRefed<nsIContent> GetFocusedContent();
 
+  // Get the focused content for the argument of some nsIMEStateManager's
+  // methods.
+  virtual already_AddRefed<nsIContent> GetFocusedContentForIME();
+
   // Whether the editor is active on the DOM window.  Note that when this
   // returns true but GetFocusedContent() returns null, it means that this editor was
   // focused when the DOM window was active.
   virtual bool IsActiveInDOMWindow();
 
   // Whether the aEvent should be handled by this editor or not.  When this
   // returns FALSE, The aEvent shouldn't be handled on this editor,
   // i.e., The aEvent should be handled by another inner editor or ancestor
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -897,24 +897,20 @@ nsEditorEventListener::Focus(nsIDOMEvent
       fm->GetFocusedElement(getter_AddRefs(element));
       if (!SameCOMIdentity(element, target))
         return NS_OK;
     }
   }
 
   mEditor->OnFocus(target);
 
-  nsCOMPtr<nsIContent> focusedContent = mEditor->GetFocusedContent();
-  NS_ENSURE_TRUE(focusedContent, NS_OK);
-  nsIDocument* currentDoc = focusedContent->GetCurrentDoc();
-  NS_ENSURE_TRUE(currentDoc, NS_OK);
   nsCOMPtr<nsIPresShell> ps = GetPresShell();
   NS_ENSURE_TRUE(ps, NS_OK);
-  nsIMEStateManager::OnFocusInEditor(ps->GetPresContext(),
-    currentDoc->HasFlag(NODE_IS_EDITABLE) ? nullptr : focusedContent);
+  nsCOMPtr<nsIContent> focusedContent = mEditor->GetFocusedContentForIME();
+  nsIMEStateManager::OnFocusInEditor(ps->GetPresContext(), focusedContent);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEditorEventListener::Blur(nsIDOMEvent* aEvent)
 {
   NS_ENSURE_TRUE(mEditor, NS_ERROR_NOT_AVAILABLE);
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -5159,16 +5159,29 @@ nsHTMLEditor::GetFocusedContent()
   if (!focusedContent->HasFlag(NODE_IS_EDITABLE) ||
       focusedContent->HasIndependentSelection()) {
     return nullptr;
   }
   // If our window is focused, we're focused.
   return OurWindowHasFocus() ? focusedContent.forget() : nullptr;
 }
 
+already_AddRefed<nsIContent>
+nsHTMLEditor::GetFocusedContentForIME()
+{
+  nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
+  if (!focusedContent) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
+  NS_ENSURE_TRUE(doc, nullptr);
+  return doc->HasFlag(NODE_IS_EDITABLE) ? nullptr : focusedContent.forget();
+}
+
 bool
 nsHTMLEditor::IsActiveInDOMWindow()
 {
   NS_ENSURE_TRUE(mDocWeak, false);
 
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   NS_ENSURE_TRUE(fm, false);
 
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -100,16 +100,17 @@ public:
 
   bool GetReturnInParagraphCreatesNewParagraph();
 
   /* ------------ nsPlaintextEditor overrides -------------- */
   NS_IMETHOD GetIsDocumentEditable(bool *aIsDocumentEditable);
   NS_IMETHOD BeginningOfDocument();
   virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
   virtual already_AddRefed<nsIContent> GetFocusedContent();
+  virtual already_AddRefed<nsIContent> GetFocusedContentForIME();
   virtual bool IsActiveInDOMWindow();
   virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget();
   virtual mozilla::dom::Element* GetEditorRoot() MOZ_OVERRIDE;
   virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
   virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
   virtual already_AddRefed<nsIContent> GetInputEventTargetContent();
   virtual bool IsEditable(nsIContent *aNode);
   using nsEditor::IsEditable;