Bug 1388269 - part3: spellchecker should use TextEditor instead of nsIEditor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 14 Aug 2017 13:48:00 +0900
changeset 646321 a66f8e5dc623a18225da475c71f0779dfefee11b
parent 646320 1a3d91eb4ef27d9dfdc16297f2a2292e52f47add
child 646322 f1b49944d1e15049377802a4c67a46174eb9333d
push id74070
push usermasayuki@d-toybox.com
push dateTue, 15 Aug 2017 04:00:57 +0000
reviewersm_kato
bugs1388269
milestone57.0a1
Bug 1388269 - part3: spellchecker should use TextEditor instead of nsIEditor r?m_kato MozReview-Commit-ID: 37npmisPqR2
extensions/spellcheck/src/mozInlineSpellChecker.cpp
extensions/spellcheck/src/mozInlineSpellChecker.h
extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
extensions/spellcheck/src/mozInlineSpellWordUtil.h
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -824,41 +824,42 @@ mozInlineSpellChecker::EditorSpellCheckI
   return SpellCheckRange(nullptr);
 }
 
 // Changes the number of pending spell checks by the given delta.  If the number
 // becomes zero or nonzero, observers are notified.  See NotifyObservers for
 // info on the aEditor parameter.
 void
 mozInlineSpellChecker::ChangeNumPendingSpellChecks(int32_t aDelta,
-                                                   nsIEditor* aEditor)
+                                                   TextEditor* aTextEditor)
 {
   int8_t oldNumPending = mNumPendingSpellChecks;
   mNumPendingSpellChecks += aDelta;
   NS_ASSERTION(mNumPendingSpellChecks >= 0,
                "Unbalanced ChangeNumPendingSpellChecks calls!");
   if (oldNumPending == 0 && mNumPendingSpellChecks > 0) {
-    NotifyObservers(INLINESPELL_STARTED_TOPIC, aEditor);
+    NotifyObservers(INLINESPELL_STARTED_TOPIC, aTextEditor);
   } else if (oldNumPending > 0 && mNumPendingSpellChecks == 0) {
-    NotifyObservers(INLINESPELL_ENDED_TOPIC, aEditor);
+    NotifyObservers(INLINESPELL_ENDED_TOPIC, aTextEditor);
   }
 }
 
 // Broadcasts the given topic to observers.  aEditor is passed to observers if
 // nonnull; otherwise mTextEditor is passed.
 void
-mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor)
+mozInlineSpellChecker::NotifyObservers(const char* aTopic,
+                                       TextEditor* aTextEditor)
 {
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (!os)
     return;
   // XXX Do we need to grab the editor here?  If it's necessary, each observer
   //     should do it instead.
   RefPtr<TextEditor> textEditor =
-    aEditor ? aEditor->AsTextEditor() : mTextEditor.get();
+    aTextEditor ? aTextEditor : mTextEditor.get();
   os->NotifyObservers(static_cast<nsIEditor*>(textEditor.get()),
                       aTopic, nullptr);
 }
 
 // mozInlineSpellChecker::SpellCheckAfterEditorChange
 //
 //    Called by the editor when nearly anything happens to change the content.
 //
@@ -1241,28 +1242,26 @@ mozInlineSpellChecker::SpellCheckBetween
 
 // mozInlineSpellChecker::ShouldSpellCheckNode
 //
 //    There are certain conditions when we don't want to spell check a node. In
 //    particular quotations, moz signatures, etc. This routine returns false
 //    for these cases.
 
 bool
-mozInlineSpellChecker::ShouldSpellCheckNode(nsIEditor* aEditor,
+mozInlineSpellChecker::ShouldSpellCheckNode(TextEditor* aTextEditor,
                                             nsINode *aNode)
 {
   MOZ_ASSERT(aNode);
   if (!aNode->IsContent())
     return false;
 
   nsIContent *content = aNode->AsContent();
 
-  uint32_t flags;
-  aEditor->GetFlags(&flags);
-  if (flags & nsIPlaintextEditor::eEditorMailMask) {
+  if (aTextEditor->IsMailEditor()) {
     nsIContent *parent = content->GetParent();
     while (parent) {
       if (parent->IsHTMLElement(nsGkAtoms::blockquote) &&
           parent->AttrValueIs(kNameSpaceID_None,
                               nsGkAtoms::type,
                               nsGkAtoms::cite,
                               eIgnoreCase)) {
         return false;
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -203,17 +203,17 @@ public:
   nsresult SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
                                   int32_t aStartOffset,
                                   nsIDOMNode *aEndNode,
                                   int32_t aEndOffset);
 
   // examines the dom node in question and returns true if the inline spell
   // checker should skip the node (i.e. the text is inside of a block quote
   // or an e-mail signature...)
-  bool ShouldSpellCheckNode(nsIEditor* aEditor, nsINode *aNode);
+  bool ShouldSpellCheckNode(mozilla::TextEditor* aTextEditor, nsINode *aNode);
 
   nsresult SpellCheckAfterChange(nsIDOMNode* aCursorNode, int32_t aCursorOffset,
                                  nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
                                  nsISelection* aSpellCheckSelection);
 
   // spell check the text contained within aRange, potentially scheduling
   // another check in the future if the time threshold is reached
   nsresult ScheduleSpellCheck(mozilla::UniquePtr<mozInlineSpellStatus>&& aStatus);
@@ -257,13 +257,13 @@ protected:
 
   // called when async nsIEditorSpellCheck methods complete
   nsresult EditorSpellCheckInited();
   nsresult CurrentDictionaryUpdated();
 
   // track the number of pending spell checks and async operations that may lead
   // to spell checks, notifying observers accordingly
   void ChangeNumPendingSpellChecks(int32_t aDelta,
-                                   nsIEditor* aEditor = nullptr);
-  void NotifyObservers(const char* aTopic, nsIEditor* aEditor);
+                                   mozilla::TextEditor* aTextEditor = nullptr);
+  void NotifyObservers(const char* aTopic, mozilla::TextEditor* aTextEditor);
 };
 
 #endif /* __mozinlinespellchecker_h__ */
--- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
@@ -1,32 +1,35 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozInlineSpellWordUtil.h"
+
+#include "mozilla/BinarySearch.h"
+#include "mozilla/TextEditor.h"
+#include "mozilla/dom/Element.h"
+
 #include "nsDebug.h"
 #include "nsIAtom.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIDOMNode.h"
 #include "nsUnicodeProperties.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIContent.h"
 #include "nsTextFragment.h"
-#include "mozilla/dom/Element.h"
 #include "nsRange.h"
 #include "nsContentUtils.h"
 #include "nsIFrame.h"
 #include <algorithm>
-#include "mozilla/BinarySearch.h"
 
 using namespace mozilla;
 
 // IsIgnorableCharacter
 //
 //    These characters are ones that we should ignore in input.
 
 inline bool IsIgnorableCharacter(char16_t ch)
@@ -45,39 +48,34 @@ inline bool IsConditionalPunctuation(cha
   return (ch == '\'' ||
           ch == 0x2019 || // RIGHT SINGLE QUOTATION MARK
           ch == 0x00B7); // MIDDLE DOT
 }
 
 // mozInlineSpellWordUtil::Init
 
 nsresult
-mozInlineSpellWordUtil::Init(nsIEditor* aEditor)
+mozInlineSpellWordUtil::Init(TextEditor* aTextEditor)
 {
-  if (NS_WARN_IF(!aEditor)) {
+  if (NS_WARN_IF(!aTextEditor)) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  nsresult rv = aEditor->GetDocument(getter_AddRefs(domDoc));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(domDoc, NS_ERROR_NULL_POINTER);
-
-  mDOMDocument = domDoc;
-  mDocument = do_QueryInterface(domDoc);
+  mDocument = aTextEditor->GetDocument();
+  if (NS_WARN_IF(!mDocument)) {
+    return NS_ERROR_FAILURE;
+  }
+  mDOMDocument = do_QueryInterface(mDocument);
 
   // Find the root node for the editor. For contenteditable we'll need something
   // cleverer here.
-  nsCOMPtr<nsIDOMElement> rootElt;
-  rv = aEditor->GetRootElement(getter_AddRefs(rootElt));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsINode> rootNode = do_QueryInterface(rootElt);
-  mRootNode = rootNode;
-  NS_ASSERTION(mRootNode, "GetRootElement returned null *and* claimed to suceed!");
+  mRootNode = aTextEditor->GetRoot();
+  if (NS_WARN_IF(!mRootNode)) {
+    return NS_ERROR_FAILURE;
+  }
   return NS_OK;
 }
 
 static inline bool
 IsSpellCheckingTextNode(nsINode* aNode)
 {
   nsIContent *parent = aNode->GetParent();
   if (parent && parent->IsAnyOfHTMLElements(nsGkAtoms::script, nsGkAtoms::style))
--- a/extensions/spellcheck/src/mozInlineSpellWordUtil.h
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.h
@@ -10,19 +10,22 @@
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
 #include "nsString.h"
 #include "nsTArray.h"
 
 //#define DEBUG_SPELLCHECK
 
 class nsRange;
-class nsIEditor;
 class nsINode;
 
+namespace mozilla {
+class TextEditor;
+} // namespace mozilla
+
 /**
  *    This class extracts text from the DOM and builds it into a single string.
  *    The string includes whitespace breaks whereever non-inline elements begin
  *    and end. This string is broken into "real words", following somewhat
  *    complex rules; for example substrings that look like URLs or
  *    email addresses are treated as single words, but otherwise many kinds of
  *    punctuation are treated as word separators. GetNextWord provides a way
  *    to iterate over these "real words".
@@ -57,17 +60,17 @@ public:
     }
   };
 
   mozInlineSpellWordUtil()
     : mRootNode(nullptr),
       mSoftBegin(nullptr, 0), mSoftEnd(nullptr, 0),
       mNextWordIndex(-1), mSoftTextValid(false) {}
 
-  nsresult Init(nsIEditor* aEditor);
+  nsresult Init(mozilla::TextEditor* aTextEditor);
 
   nsresult SetEnd(nsINode* aEndNode, int32_t aEndOffset);
 
   // sets the current position, this should be inside the range. If we are in
   // the middle of a word, we'll move to its start.
   nsresult SetPosition(nsINode* aNode, int32_t aOffset);
 
   // Given a point inside or immediately following a word, this returns the