Bug 345428 - No spellcheck on focus out, second try, r=Olli.Pettay, r=brettw, a=dsicore
authormartijn.martijn@gmail.com
Tue, 25 Sep 2007 04:20:43 -0700
changeset 6296 4e57e60122723c82e10ab8b59be560373e1ce943
parent 6295 697b5180ac117a179c8a0c92ed8d9eca0bd26190
child 6297 2806575ac6e12d1106c6c43b3b01122e0390e681
push idunknown
push userunknown
push dateunknown
reviewersOlli.Pettay, brettw, dsicore
bugs345428
milestone1.9a9pre
Bug 345428 - No spellcheck on focus out, second try, r=Olli.Pettay, r=brettw, a=dsicore
extensions/spellcheck/src/Makefile.in
extensions/spellcheck/src/mozInlineSpellChecker.cpp
extensions/spellcheck/src/mozInlineSpellChecker.h
--- a/extensions/spellcheck/src/Makefile.in
+++ b/extensions/spellcheck/src/Makefile.in
@@ -49,16 +49,17 @@ SHORT_LIBNAME   = spellchk
 EXPORT_LIBRARY  = 1
 IS_COMPONENT	= 1
 LIBXUL_LIBRARY  = 1
 
 REQUIRES	= xpcom \
 		  string \
 		  editor \
 		  content \
+		  gfx \
 		  layout \
 		  dom \
 		  necko \
 		  widget \
 		  pref \
 		  txtsvc \
 		  uconv \
 		  unicharutil \
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -91,16 +91,18 @@
 #include "nsISelectionController.h"
 #include "nsIServiceManager.h"
 #include "nsITextServicesFilter.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIContent.h"
 #include "nsIEventStateManager.h"
+#include "nsIEventListenerManager.h"
+#include "nsGUIEvent.h"
 
 // Set to spew messages to the console about what is happening.
 //#define DEBUG_INLINESPELL
 
 // the number of milliseconds that we will take at once to do spellchecking
 #define INLINESPELL_CHECK_TIMEOUT 50
 
 // The number of words to check before we look at the time to see if
@@ -499,16 +501,17 @@ public:
     return NS_OK;
   }
 };
 
 
 NS_INTERFACE_MAP_BEGIN(mozInlineSpellChecker)
 NS_INTERFACE_MAP_ENTRY(nsIInlineSpellChecker)
 NS_INTERFACE_MAP_ENTRY(nsIEditActionListener)
+NS_INTERFACE_MAP_ENTRY(nsIDOMFocusListener)
 NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMKeyListener)
 NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMKeyListener)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(mozInlineSpellChecker)
@@ -619,20 +622,29 @@ mozInlineSpellChecker::RegisterEventList
 {
   nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
   NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER);
 
   editor->AddEditActionListener(this);
 
   nsCOMPtr<nsIDOMDocument> doc;
   nsresult rv = editor->GetDocument(getter_AddRefs(doc));
-  NS_ENSURE_SUCCESS(rv, rv); 
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsPIDOMEventTarget> piTarget = do_QueryInterface(doc, &rv);
-  NS_ENSURE_SUCCESS(rv, rv); 
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIEventListenerManager> elmP;
+  piTarget->GetListenerManager(PR_TRUE, getter_AddRefs(elmP));
+  if (elmP) {
+    // Focus event doesn't bubble so adding the listener to capturing phase
+    elmP->AddEventListenerByIID(static_cast<nsIDOMFocusListener *>(this),
+                                NS_GET_IID(nsIDOMFocusListener),
+                                NS_EVENT_FLAG_CAPTURE);
+  }
 
   piTarget->AddEventListenerByIID(static_cast<nsIDOMMouseListener*>(this),
                                   NS_GET_IID(nsIDOMMouseListener));
   piTarget->AddEventListenerByIID(static_cast<nsIDOMKeyListener*>(this),
                                   NS_GET_IID(nsIDOMKeyListener));
 
   return NS_OK;
 }
@@ -649,16 +661,24 @@ mozInlineSpellChecker::UnregisterEventLi
 
   nsCOMPtr<nsIDOMDocument> doc;
   editor->GetDocument(getter_AddRefs(doc));
   NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER);
   
   nsCOMPtr<nsPIDOMEventTarget> piTarget = do_QueryInterface(doc);
   NS_ENSURE_TRUE(piTarget, NS_ERROR_NULL_POINTER);
 
+  nsCOMPtr<nsIEventListenerManager> elmP;
+  piTarget->GetListenerManager(PR_TRUE, getter_AddRefs(elmP));
+  if (elmP) {
+    elmP->RemoveEventListenerByIID(static_cast<nsIDOMFocusListener *>(this),
+                                   NS_GET_IID(nsIDOMFocusListener),
+                                   NS_EVENT_FLAG_CAPTURE);
+  }
+
   piTarget->RemoveEventListenerByIID(static_cast<nsIDOMMouseListener*>(this),
                                      NS_GET_IID(nsIDOMMouseListener));
   piTarget->RemoveEventListenerByIID(static_cast<nsIDOMKeyListener*>(this),
                                      NS_GET_IID(nsIDOMKeyListener));
   
   return NS_OK;
 }
 
@@ -1646,16 +1666,28 @@ mozInlineSpellChecker::HandleNavigationE
   return NS_OK;
 }
 
 NS_IMETHODIMP mozInlineSpellChecker::HandleEvent(nsIDOMEvent* aEvent)
 {
   return NS_OK;
 }
 
+NS_IMETHODIMP mozInlineSpellChecker::Focus(nsIDOMEvent* aEvent)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP mozInlineSpellChecker::Blur(nsIDOMEvent* aEvent)
+{
+  // force spellcheck on blur, for instance when tabbing out of a textbox
+  HandleNavigationEvent(aEvent, PR_TRUE);
+  return NS_OK;
+}
+
 NS_IMETHODIMP mozInlineSpellChecker::MouseClick(nsIDOMEvent *aMouseEvent)
 {
   nsCOMPtr<nsIDOMMouseEvent>mouseEvent = do_QueryInterface(aMouseEvent);
   NS_ENSURE_TRUE(mouseEvent, NS_OK);
 
   // ignore any errors from HandleNavigationEvent as we don't want to prevent 
   // anyone else from seeing this event.
   PRUint16 button;
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -43,16 +43,17 @@
 #include "nsIDOMRange.h"
 #include "nsIEditorSpellCheck.h"
 #include "nsIEditActionListener.h"
 #include "nsIInlineSpellChecker.h"
 #include "nsITextServicesDocument.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsWeakReference.h"
 #include "nsIEditor.h"
+#include "nsIDOMFocusListener.h"
 #include "nsIDOMMouseListener.h"
 #include "nsIDOMKeyListener.h"
 #include "nsWeakReference.h"
 #include "mozISpellI18NUtil.h"
 
 class nsIDOMDocumentRange;
 class nsIDOMMouseEventListener;
 class mozInlineSpellWordUtil;
@@ -133,17 +134,17 @@ protected:
   nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
 
   nsresult GetDocumentRange(nsIDOMDocumentRange** aDocRange);
   nsresult PositionToCollapsedRange(nsIDOMDocumentRange* aDocRange,
                                     nsIDOMNode* aNode, PRInt32 aOffset,
                                     nsIDOMRange** aRange);
 };
 
-class mozInlineSpellChecker : public nsIInlineSpellChecker, nsIEditActionListener, nsIDOMMouseListener, nsIDOMKeyListener,
+class mozInlineSpellChecker : public nsIInlineSpellChecker, nsIEditActionListener, nsIDOMFocusListener, nsIDOMMouseListener, nsIDOMKeyListener,
                                      nsSupportsWeakReference
 {
 private:
   friend class mozInlineSpellStatus;
 
   // Access with CanEnableInlineSpellChecking
   enum SpellCheckingState { SpellCheck_Uninitialized = -1,
                             SpellCheck_NotAvailable = 0,
@@ -219,16 +220,21 @@ public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIEDITACTIONLISTENER
   NS_DECL_NSIINLINESPELLCHECKER
 
   // returns true if it looks likely that we can enable real-time spell checking
   static PRBool CanEnableInlineSpellChecking();
 
+  /*BEGIN implementations of focus event handler interface*/
+  NS_IMETHOD Focus(nsIDOMEvent* aEvent);
+  NS_IMETHOD Blur(nsIDOMEvent* aEvent);
+  /*END implementations of focus event handler interface*/
+
   /*BEGIN implementations of mouseevent handler interface*/
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
   NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent);