Fix for bugzilla 91131(Cannot spellcheck selection)
First pass implementation of spellcheck selection feature: editor/composer/src/nsEditorSpellCheck.cpp editor/idl/nsIEditorSpellCheck.idl editor/txtsvc/public/nsITextServicesDocument.h editor/txtsvc/src/Makefile.in editor/txtsvc/src/nsTextServicesDocument.cpp editor/txtsvc/src/nsTextServicesDocument.h editor/ui/composer/content/ComposerCommands.js editor/ui/dialogs/content/EdSpellCheck.js mailnews/compose/resources/content/MsgComposeCommands.js r=jfrancis@netscape.com,brade@netscape.com sr=sfraser@netscape.com git-svn-id: svn://10.0.0.236/trunk@141315 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
a74566cb5d
commit
733361e518
@ -43,6 +43,9 @@
|
||||
#include "nsTextServicesCID.h"
|
||||
#include "nsITextServicesDocument.h"
|
||||
#include "nsISpellChecker.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsXPIDLString.h"
|
||||
@ -73,7 +76,7 @@ nsEditorSpellCheck::~nsEditorSpellCheck()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditorSpellCheck::InitSpellChecker(nsIEditor* editor)
|
||||
nsEditorSpellCheck::InitSpellChecker(nsIEditor* aEditor, PRBool aEnableSelectionChecking)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -91,9 +94,57 @@ nsEditorSpellCheck::InitSpellChecker(nsIEditor* editor)
|
||||
tsDoc->SetFilter(mTxtSrvFilter);
|
||||
|
||||
// Pass the editor to the text services document
|
||||
rv = tsDoc->InitWithEditor(editor);
|
||||
rv = tsDoc->InitWithEditor(aEditor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aEnableSelectionChecking) {
|
||||
// Find out if the section is collapsed or not.
|
||||
// If it isn't, we want to spellcheck just the selection.
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
|
||||
rv = aEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||
|
||||
PRInt32 count = 0;
|
||||
|
||||
rv = selection->GetRangeCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (count > 0) {
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
|
||||
rv = selection->GetRangeAt(0, getter_AddRefs(range));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool collapsed = PR_FALSE;
|
||||
rv = range->GetCollapsed(&collapsed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!collapsed) {
|
||||
// We don't want to touch the range in the selection,
|
||||
// so create a new copy of it.
|
||||
|
||||
nsCOMPtr<nsIDOMRange> rangeBounds;
|
||||
rv = range->CloneRange(getter_AddRefs(rangeBounds));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(rangeBounds, NS_ERROR_FAILURE);
|
||||
|
||||
// Make sure the new range spans complete words.
|
||||
|
||||
rv = tsDoc->ExpandRangeToWordBoundaries(rangeBounds);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now tell the text services that you only want
|
||||
// to iterate over the text in this range.
|
||||
|
||||
rv = tsDoc->SetExtent(rangeBounds);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = nsComponentManager::CreateInstance(NS_SPELLCHECKER_CONTRACTID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISpellChecker),
|
||||
|
||||
@ -45,7 +45,7 @@ interface nsITextServicesFilter;
|
||||
interface nsIEditorSpellCheck : nsISupports
|
||||
{
|
||||
|
||||
void InitSpellChecker(in nsIEditor editor);
|
||||
void InitSpellChecker(in nsIEditor editor, in boolean enableSelectionChecking);
|
||||
wstring GetNextMisspelledWord();
|
||||
wstring GetSuggestedWord();
|
||||
boolean CheckCurrentWord(in wstring suggestedWord);
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIDOMDocument;
|
||||
class nsIDOMRange;
|
||||
class nsIPresShell;
|
||||
class nsIEditor;
|
||||
class nsString;
|
||||
@ -101,6 +102,36 @@ public:
|
||||
*/
|
||||
NS_IMETHOD InitWithEditor(nsIEditor *aEditor) = 0;
|
||||
|
||||
/**
|
||||
* Sets the range/extent over which the text services document
|
||||
* will iterate. Note that InitWithDocument() or InitWithEditor()
|
||||
* should have been called prior to calling this method. If this
|
||||
* method is never called, the text services defaults to iterating
|
||||
* over the entire document.
|
||||
*
|
||||
* @param aDOMRange is the range to use. aDOMRange must point to a
|
||||
* valid range object.
|
||||
*/
|
||||
NS_IMETHOD SetExtent(nsIDOMRange* aDOMRange) = 0;
|
||||
|
||||
/**
|
||||
* Gets the range that the text services document
|
||||
* is currently iterating over. If SetExtent() was never
|
||||
* called, this method will return a range that spans the
|
||||
* entire body of the document.
|
||||
*
|
||||
* @param aDOMRange will contain an AddRef'd pointer to the range.
|
||||
*/
|
||||
NS_IMETHOD GetExtent(nsIDOMRange** aDOMRange) = 0;
|
||||
|
||||
/**
|
||||
* Expands the end points of the range so that it spans complete words.
|
||||
* This call does not change any internal state of the text services document.
|
||||
*
|
||||
* @param aDOMRange the range to be expanded/adjusted.
|
||||
*/
|
||||
NS_IMETHOD ExpandRangeToWordBoundaries(nsIDOMRange *aRange) = 0;
|
||||
|
||||
/**
|
||||
* Sets the filter to be used while iterating over content.
|
||||
* @param aFilter filter to be used while iterating over content.
|
||||
|
||||
@ -40,6 +40,7 @@ REQUIRES = xpcom \
|
||||
dom \
|
||||
widget \
|
||||
unicharutil \
|
||||
lwbrk \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -53,6 +53,8 @@
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsITextServicesFilter.h"
|
||||
|
||||
class nsIWordBreaker;
|
||||
|
||||
/** implementation of a text services object.
|
||||
*
|
||||
*/
|
||||
@ -110,7 +112,9 @@ private:
|
||||
PRInt32 mSelEndIndex;
|
||||
PRInt32 mSelEndOffset;
|
||||
|
||||
nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
|
||||
nsCOMPtr<nsIDOMRange> mExtent;
|
||||
|
||||
nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
|
||||
|
||||
public:
|
||||
|
||||
@ -129,6 +133,9 @@ public:
|
||||
NS_IMETHOD InitWithDocument(nsIDOMDocument *aDOMDocument, nsIPresShell *aPresShell);
|
||||
NS_IMETHOD InitWithEditor(nsIEditor *aEditor);
|
||||
NS_IMETHOD GetDocument(nsIDOMDocument **aDoc);
|
||||
NS_IMETHOD SetExtent(nsIDOMRange* aDOMRange);
|
||||
NS_IMETHOD GetExtent(nsIDOMRange** aDOMRange);
|
||||
NS_IMETHOD ExpandRangeToWordBoundaries(nsIDOMRange *aRange);
|
||||
NS_IMETHOD SetFilter(nsITextServicesFilter *aFilter);
|
||||
NS_IMETHOD CanEdit(PRBool *aCanEdit);
|
||||
NS_IMETHOD GetCurrentTextBlock(nsString *aStr);
|
||||
@ -175,19 +182,24 @@ private:
|
||||
|
||||
nsresult AdjustContentIterator();
|
||||
|
||||
nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator);
|
||||
nsresult FirstTextNodeInPrevBlock(nsIContentIterator *aIterator);
|
||||
nsresult FirstTextNodeInNextBlock(nsIContentIterator *aIterator);
|
||||
static nsresult FirstTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
|
||||
static nsresult LastTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
|
||||
|
||||
static nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator);
|
||||
static nsresult FirstTextNodeInPrevBlock(nsIContentIterator *aIterator);
|
||||
static nsresult FirstTextNodeInNextBlock(nsIContentIterator *aIterator);
|
||||
|
||||
nsresult GetFirstTextNodeInPrevBlock(nsIContent **aContent);
|
||||
nsresult GetFirstTextNodeInNextBlock(nsIContent **aContent);
|
||||
|
||||
PRBool IsBlockNode(nsIContent *aContent);
|
||||
PRBool IsTextNode(nsIContent *aContent);
|
||||
PRBool IsTextNode(nsIDOMNode *aNode);
|
||||
PRBool DidSkip(nsIContentIterator* aFilteredIter);
|
||||
void ClearDidSkip(nsIContentIterator* aFilteredIter);
|
||||
static PRBool IsBlockNode(nsIContent *aContent);
|
||||
static PRBool IsTextNode(nsIContent *aContent);
|
||||
static PRBool IsTextNode(nsIDOMNode *aNode);
|
||||
|
||||
PRBool HasSameBlockNodeParent(nsIContent *aContent1, nsIContent *aContent2);
|
||||
static PRBool DidSkip(nsIContentIterator* aFilteredIter);
|
||||
static void ClearDidSkip(nsIContentIterator* aFilteredIter);
|
||||
|
||||
static PRBool HasSameBlockNodeParent(nsIContent *aContent1, nsIContent *aContent2);
|
||||
|
||||
nsresult SetSelectionInternal(PRInt32 aOffset, PRInt32 aLength, PRBool aDoUpdate);
|
||||
nsresult GetSelection(TSDBlockSelectionStatus *aSelStatus, PRInt32 *aSelOffset, PRInt32 *aSelLength);
|
||||
@ -197,12 +209,29 @@ private:
|
||||
PRBool SelectionIsCollapsed();
|
||||
PRBool SelectionIsValid();
|
||||
|
||||
static nsresult CreateOffsetTable(nsVoidArray *aOffsetTable,
|
||||
nsIContentIterator *aIterator,
|
||||
TSDIteratorStatus *aIteratorStatus,
|
||||
nsIDOMRange *aIterRange,
|
||||
nsString *aStr);
|
||||
static nsresult ClearOffsetTable(nsVoidArray *aOffsetTable);
|
||||
|
||||
static nsresult NodeHasOffsetEntry(nsVoidArray *aOffsetTable,
|
||||
nsIDOMNode *aNode,
|
||||
PRBool *aHasEntry,
|
||||
PRInt32 *aEntryIndex);
|
||||
|
||||
nsresult RemoveInvalidOffsetEntries();
|
||||
nsresult CreateOffsetTable(nsString *aStr=0);
|
||||
nsresult ClearOffsetTable();
|
||||
nsresult SplitOffsetEntry(PRInt32 aTableIndex, PRInt32 aOffsetIntoEntry);
|
||||
|
||||
nsresult NodeHasOffsetEntry(nsIDOMNode *aNode, PRBool *aHasEntry, PRInt32 *aEntryIndex);
|
||||
static nsresult GetWordBreaker(nsIWordBreaker **aWordBreaker);
|
||||
static nsresult FindWordBounds(nsVoidArray *offsetTable, nsString *blockStr,
|
||||
nsIWordBreaker *aWordBreaker,
|
||||
nsIDOMNode *aNode, PRInt32 aNodeOffset,
|
||||
nsIDOMNode **aWordStartNode,
|
||||
PRInt32 *aWordStartOffset,
|
||||
nsIDOMNode **aWordEndNode,
|
||||
PRInt32 *aWordEndOffset);
|
||||
|
||||
/* DEBUG */
|
||||
void PrintOffsetTable();
|
||||
|
||||
@ -2424,7 +2424,7 @@ var nsSpellingCommand =
|
||||
try {
|
||||
var skipBlockQuotes = (window.document.firstChild.getAttribute("windowtype") == "msgcompose");
|
||||
window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
|
||||
"chrome,close,titlebar,modal", false, skipBlockQuotes);
|
||||
"chrome,close,titlebar,modal", false, skipBlockQuotes, true);
|
||||
}
|
||||
catch(ex) {}
|
||||
window.content.focus();
|
||||
|
||||
@ -54,6 +54,7 @@ function Startup()
|
||||
var filterContractId;
|
||||
sendMailMessageMode = window.arguments[0];
|
||||
var skipBlockQuotes = window.arguments[1];
|
||||
var enableSelectionChecking = window.arguments[2];
|
||||
|
||||
if (skipBlockQuotes)
|
||||
filterContractId = "@mozilla.org/editor/txtsrvfiltermail;1";
|
||||
@ -61,7 +62,7 @@ function Startup()
|
||||
filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
|
||||
|
||||
gSpellChecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor());
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor(), enableSelectionChecking);
|
||||
|
||||
// XXX: We need to read in a pref here so we can set the
|
||||
// default language for the spellchecker!
|
||||
@ -424,7 +425,7 @@ function Recheck()
|
||||
var curLang = gSpellChecker.GetCurrentDictionary();
|
||||
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor());
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor(), false);
|
||||
gSpellChecker.SetCurrentDictionary(curLang);
|
||||
gMisspelledWord = gSpellChecker.GetNextMisspelledWord();
|
||||
SetWidgetsForMisspelledWord();
|
||||
|
||||
@ -1564,7 +1564,7 @@ function GenericSendMessage( msgType )
|
||||
window.cancelSendMessage = false;
|
||||
try {
|
||||
window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
|
||||
"chrome,close,titlebar,modal", true, true);
|
||||
"chrome,close,titlebar,modal", true, true, false);
|
||||
}
|
||||
catch(ex){}
|
||||
if(window.cancelSendMessage)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user