зеркало из https://github.com/mozilla/pjs.git
Bug 302050: inline spellchecking for textboxes backend. r=bryner sr=bzbarsky
This commit is contained in:
Родитель
d5494068f9
Коммит
97c9c6513a
|
@ -286,7 +286,9 @@ XULPopupListenerImpl::PreLaunchPopup(nsIDOMEvent* aMouseEvent)
|
|||
}
|
||||
|
||||
// Store clicked-on node in xul document for context menus and menu popups.
|
||||
// CLEAR THE POPUP EVENT BEFORE THIS FUNCTION EXITS
|
||||
xulDocument->SetPopupNode( targetNode );
|
||||
xulDocument->SetPopupEvent( aMouseEvent );
|
||||
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aMouseEvent));
|
||||
|
||||
|
@ -322,6 +324,7 @@ XULPopupListenerImpl::PreLaunchPopup(nsIDOMEvent* aMouseEvent)
|
|||
aMouseEvent->PreventDefault();
|
||||
break;
|
||||
}
|
||||
xulDocument->SetPopupEvent(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1622,6 +1622,34 @@ nsXULDocument::SetPopupNode(nsIDOMNode* aNode)
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::GetPopupEvent(nsIDOMEvent** aEvent)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFocusController> focusController;
|
||||
GetFocusController(getter_AddRefs(focusController));
|
||||
NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE);
|
||||
|
||||
rv = focusController->GetPopupEvent(aEvent);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::SetPopupEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFocusController> focusController;
|
||||
GetFocusController(getter_AddRefs(focusController));
|
||||
NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE);
|
||||
|
||||
rv = focusController->SetPopupEvent(aEvent);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::GetTooltipNode(nsIDOMNode** aNode)
|
||||
{
|
||||
|
|
|
@ -52,9 +52,9 @@ class nsIController;
|
|||
class nsIControllers;
|
||||
class nsAString;
|
||||
|
||||
// {AC71F479-17E1-4ee0-8EFD-0ECF2AA2F827}
|
||||
// {f9004db3-5272-4a8c-8b19-70a4adb8f8b6}
|
||||
#define NS_IFOCUSCONTROLLER_IID \
|
||||
{ 0xac71f479, 0x17e1, 0x4ee0, { 0x8e, 0xfd, 0xe, 0xcf, 0x2a, 0xa2, 0xf8, 0x27 } }
|
||||
{ 0xf9004db3, 0x5272, 0x4a8c, { 0x8b, 0x19, 0x70, 0xa4, 0xad, 0xb8, 0xf8, 0xb6 } }
|
||||
|
||||
class nsIFocusController : public nsISupports {
|
||||
public:
|
||||
|
@ -78,6 +78,9 @@ public:
|
|||
NS_IMETHOD GetPopupNode(nsIDOMNode** aNode)=0;
|
||||
NS_IMETHOD SetPopupNode(nsIDOMNode* aNode)=0;
|
||||
|
||||
NS_IMETHOD GetPopupEvent(nsIDOMEvent** aEvent)=0;
|
||||
NS_IMETHOD SetPopupEvent(nsIDOMEvent* aEvent)=0;
|
||||
|
||||
NS_IMETHOD GetControllerForCommand(const char * aCommand, nsIController** aResult)=0;
|
||||
NS_IMETHOD GetControllers(nsIControllers** aResult)=0;
|
||||
|
||||
|
|
|
@ -42,10 +42,17 @@
|
|||
interface nsIDOMXULCommandDispatcher;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(e64bb081-13ba-430e-ab70-73a9f1d3de58)]
|
||||
[scriptable, uuid(868685b1-f4bc-4080-9c44-ecd5a3f1bac8)]
|
||||
interface nsIDOMXULDocument : nsISupports
|
||||
{
|
||||
attribute nsIDOMNode popupNode;
|
||||
|
||||
/**
|
||||
* The event that triggered the popup. This is only valid during
|
||||
* the popup showing event.
|
||||
*/
|
||||
attribute nsIDOMEvent popupEvent;
|
||||
|
||||
attribute nsIDOMNode tooltipNode;
|
||||
|
||||
readonly attribute nsIDOMXULCommandDispatcher commandDispatcher;
|
||||
|
|
|
@ -591,4 +591,19 @@ nsFocusController::SetPopupNode(nsIDOMNode* aNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusController::GetPopupEvent(nsIDOMEvent** aEvent)
|
||||
{
|
||||
*aEvent = mPopupEvent;
|
||||
NS_IF_ADDREF(*aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusController::SetPopupEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
mPopupEvent = aEvent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -86,6 +86,9 @@ public:
|
|||
NS_IMETHOD GetPopupNode(nsIDOMNode** aNode);
|
||||
NS_IMETHOD SetPopupNode(nsIDOMNode* aNode);
|
||||
|
||||
NS_IMETHOD GetPopupEvent(nsIDOMEvent** aEvent);
|
||||
NS_IMETHOD SetPopupEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
NS_IMETHOD GetControllerForCommand(const char *aCommand, nsIController** aResult);
|
||||
NS_IMETHOD GetControllers(nsIControllers** aResult);
|
||||
|
||||
|
@ -115,6 +118,7 @@ protected:
|
|||
nsCOMPtr<nsPIDOMWindow> mCurrentWindow; // [OWNER]
|
||||
nsCOMPtr<nsPIDOMWindow> mPreviousWindow; // [OWNER]
|
||||
nsCOMPtr<nsIDOMNode> mPopupNode; // [OWNER]
|
||||
nsCOMPtr<nsIDOMEvent> mPopupEvent;
|
||||
|
||||
PRUint32 mSuppressFocus;
|
||||
PRPackedBool mSuppressFocusScroll;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Akkana Peck <akkana@netscape.com>
|
||||
* Charley Manske <cmanske@netscape.com>
|
||||
* Neil Deakin <neil@mozdevgroup.com>
|
||||
* Brett Wilson <brettw@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -73,6 +74,30 @@ nsEditorSpellCheck::~nsEditorSpellCheck()
|
|||
mSpellChecker = nsnull;
|
||||
}
|
||||
|
||||
// The problem is that if the spell checker does not exist, we can not tell
|
||||
// which dictionaries are installed. This function works around the problem,
|
||||
// allowing callers to ask if we can spell check without actually doing so (and
|
||||
// enabling or disabling UI as necessary). This just creates a spellcheck
|
||||
// object if needed and asks it for the dictionary list.
|
||||
NS_IMETHODIMP
|
||||
nsEditorSpellCheck::CanSpellCheck(PRBool* _retval)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISpellChecker> spellChecker;
|
||||
if (! mSpellChecker) {
|
||||
spellChecker = do_CreateInstance(NS_SPELLCHECKER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
spellChecker = mSpellChecker;
|
||||
}
|
||||
nsStringArray dictList;
|
||||
rv = spellChecker->GetDictionaryList(&dictList);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = (dictList.Count() > 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditorSpellCheck::InitSpellChecker(nsIEditor* aEditor, PRBool aEnableSelectionChecking)
|
||||
{
|
||||
|
@ -199,7 +224,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::GetNextMisspelledWord(PRUnichar **aNextMisspelledWord)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsAutoString nextMisspelledWord;
|
||||
|
||||
|
@ -233,7 +258,7 @@ nsEditorSpellCheck::CheckCurrentWord(const PRUnichar *aSuggestedWord,
|
|||
PRBool *aIsMisspelled)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
DeleteSuggestedWordList();
|
||||
return mSpellChecker->CheckWord(nsDependentString(aSuggestedWord),
|
||||
|
@ -245,7 +270,7 @@ nsEditorSpellCheck::CheckCurrentWordNoSuggest(const PRUnichar *aSuggestedWord,
|
|||
PRBool *aIsMisspelled)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return mSpellChecker->CheckWord(nsDependentString(aSuggestedWord),
|
||||
aIsMisspelled, nsnull);
|
||||
|
@ -257,7 +282,7 @@ nsEditorSpellCheck::ReplaceWord(const PRUnichar *aMisspelledWord,
|
|||
PRBool allOccurrences)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return mSpellChecker->Replace(nsDependentString(aMisspelledWord),
|
||||
nsDependentString(aReplaceWord), allOccurrences);
|
||||
|
@ -267,7 +292,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::IgnoreWordAllOccurrences(const PRUnichar *aWord)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return mSpellChecker->IgnoreAll(nsDependentString(aWord));
|
||||
}
|
||||
|
@ -276,7 +301,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::GetPersonalDictionary()
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// We can spell check with any editor type
|
||||
mDictionaryList.Clear();
|
||||
|
@ -305,7 +330,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::AddWordToDictionary(const PRUnichar *aWord)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return mSpellChecker->AddWordToPersonalDictionary(nsDependentString(aWord));
|
||||
}
|
||||
|
@ -314,7 +339,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::RemoveWordFromDictionary(const PRUnichar *aWord)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return mSpellChecker->RemoveWordFromPersonalDictionary(nsDependentString(aWord));
|
||||
}
|
||||
|
@ -323,7 +348,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::GetDictionaryList(PRUnichar ***aDictionaryList, PRUint32 *aCount)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aDictionaryList || !aCount)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -382,7 +407,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::GetCurrentDictionary(PRUnichar **aDictionary)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aDictionary)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -402,7 +427,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::SetCurrentDictionary(const PRUnichar *aDictionary)
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aDictionary)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -414,7 +439,7 @@ NS_IMETHODIMP
|
|||
nsEditorSpellCheck::UninitSpellChecker()
|
||||
{
|
||||
if (!mSpellChecker)
|
||||
return NS_NOINTERFACE;
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Save the last used dictionary to the user's preferences.
|
||||
nsresult rv;
|
||||
|
|
|
@ -69,6 +69,8 @@ protected:
|
|||
nsStringArray mSuggestedWordList;
|
||||
PRInt32 mSuggestedWordIndex;
|
||||
|
||||
// these are the words in the current personal dictionary,
|
||||
// GetPersonalDictionary must be called to load them.
|
||||
nsStringArray mDictionaryList;
|
||||
PRInt32 mDictionaryIndex;
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef short EDirection;
|
|||
[ptr] native nsIPresShellPtr(nsIPresShell);
|
||||
[ptr] native nsIContentPtr(nsIContent);
|
||||
|
||||
[scriptable, uuid(D4882FFB-E927-408b-96BE-D4391B456FA9)]
|
||||
[scriptable, uuid(e7cb6526-0809-47ee-b484-a6f297e536c0)]
|
||||
|
||||
interface nsIEditor : nsISupports
|
||||
{
|
||||
|
@ -285,7 +285,15 @@ interface nsIEditor : nsISupports
|
|||
|
||||
/* ------------ Inline Spell Checking methods -------------- */
|
||||
|
||||
readonly attribute nsIInlineSpellChecker inlineSpellChecker;
|
||||
/** Returns the inline spell checker associated with this object. The spell
|
||||
* checker is lazily created, so this function may create the object for
|
||||
* you during this call.
|
||||
* @param autoCreate If true, this will create a spell checker object
|
||||
* if one does not exist yet for this editor. If false
|
||||
* and the object has not been created, this function
|
||||
* WILL RETURN NULL.
|
||||
*/
|
||||
nsIInlineSpellChecker getInlineSpellChecker(in boolean autoCreate);
|
||||
|
||||
/* ------------ Clipboard methods -------------- */
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brett Wilson <brettw@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -40,25 +41,143 @@
|
|||
interface nsIEditor;
|
||||
interface nsITextServicesFilter;
|
||||
|
||||
[scriptable, uuid(6088a862-1229-11d9-941d-c035b2e390c6)]
|
||||
[scriptable, uuid(78201842-b5f8-441f-a696-fa343bd8a29a)]
|
||||
interface nsIEditorSpellCheck : nsISupports
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns true if we can enable spellchecking. If there are no available
|
||||
* dictionaries, this will return false.
|
||||
*/
|
||||
boolean canSpellCheck();
|
||||
|
||||
/**
|
||||
* Turns on the spell checker for the given editor. enableSelectionChecking
|
||||
* set means that we only want to check the current selection in the editor,
|
||||
* (this controls the behavior of GetNextMisspelledWord). For spellchecking
|
||||
* clients with no modal UI (such as inline spellcheckers), this flag doesn't
|
||||
* matter
|
||||
*/
|
||||
void InitSpellChecker(in nsIEditor editor, in boolean enableSelectionChecking);
|
||||
|
||||
/**
|
||||
* When interactively spell checking the document, this will return the
|
||||
* value of the next word that is misspelled. This also computes the
|
||||
* suggestions which you can get by calling GetSuggestedWord.
|
||||
*
|
||||
* @see nsISpellChecker::GetNextMisspelledWord
|
||||
*/
|
||||
wstring GetNextMisspelledWord();
|
||||
|
||||
/**
|
||||
* Used to get suggestions for the last word that was checked and found to
|
||||
* be misspelled. The first call will give you the first (best) suggestion.
|
||||
* Subsequent calls will iterate through all the suggestions, allowing you
|
||||
* to build a list. When there are no more suggestions, an empty string
|
||||
* (not a null pointer) will be returned.
|
||||
*
|
||||
* @see nsISpellChecker::GetSuggestedWord
|
||||
*/
|
||||
wstring GetSuggestedWord();
|
||||
|
||||
/**
|
||||
* Check a given word. In spite of the name, this function checks the word
|
||||
* you give it, returning true if the word is misspelled. If the word is
|
||||
* misspelled, it will compute the suggestions which you can get from
|
||||
* GetSuggestedWord().
|
||||
*
|
||||
* @see nsISpellChecker::CheckCurrentWord
|
||||
*/
|
||||
boolean CheckCurrentWord(in wstring suggestedWord);
|
||||
|
||||
/**
|
||||
* Use when modally checking the document to replace a word.
|
||||
*
|
||||
* @see nsISpellChecker::CheckCurrentWord
|
||||
*/
|
||||
void ReplaceWord(in wstring misspelledWord, in wstring replaceWord, in boolean allOccurrences);
|
||||
|
||||
/**
|
||||
* @see nsISpellChecker::IgnoreAll
|
||||
*/
|
||||
void IgnoreWordAllOccurrences(in wstring word);
|
||||
|
||||
/**
|
||||
* Fills an internal list of words added to the personal dictionary. These
|
||||
* words can be retrieved using GetPersonalDictionaryWord()
|
||||
*
|
||||
* @see nsISpellChecker::GetPersonalDictionary
|
||||
* @see GetPersonalDictionaryWord
|
||||
*/
|
||||
void GetPersonalDictionary();
|
||||
|
||||
/**
|
||||
* Used after you call GetPersonalDictionary() to iterate through all the
|
||||
* words added to the personal dictionary. Will return the empty string when
|
||||
* there are no more words.
|
||||
*/
|
||||
wstring GetPersonalDictionaryWord();
|
||||
|
||||
/**
|
||||
* Adds a word to the current personal dictionary.
|
||||
*
|
||||
* @see nsISpellChecker::AddWordToDictionary
|
||||
*/
|
||||
void AddWordToDictionary(in wstring word);
|
||||
|
||||
/**
|
||||
* Removes a word from the current personal dictionary.
|
||||
*
|
||||
* @see nsISpellChecker::RemoveWordFromPersonalDictionary
|
||||
*/
|
||||
void RemoveWordFromDictionary(in wstring word);
|
||||
|
||||
/**
|
||||
* Retrieves a list of the currently available dictionaries. The strings will
|
||||
* typically be language IDs, like "en-US".
|
||||
*
|
||||
* @see mozISpellCheckingEngine::GetDictionaryList
|
||||
*/
|
||||
void GetDictionaryList([array, size_is(count)] out wstring dictionaryList, out PRUint32 count);
|
||||
|
||||
/**
|
||||
* @see nsISpellChecker::GetCurrentDictionary
|
||||
*/
|
||||
wstring GetCurrentDictionary();
|
||||
|
||||
/**
|
||||
* @see nsISpellChecker::SetCurrentDictionary
|
||||
*/
|
||||
void SetCurrentDictionary(in wstring dictionary);
|
||||
|
||||
/**
|
||||
* Call this to free up the spell checking object. It will also save the
|
||||
* current selected language as the default for future use.
|
||||
*
|
||||
* If you have called CanSpellCheck but not InitSpellChecker, you can still
|
||||
* call this function to clear the cached spell check object, and no
|
||||
* preference saving will happen.
|
||||
*/
|
||||
void UninitSpellChecker();
|
||||
|
||||
/**
|
||||
* Used to filter the content (for example, to skip blockquotes in email from
|
||||
* spellchecking. Call this before calling InitSpellChecker; calling it
|
||||
* after initialization will have no effect.
|
||||
*
|
||||
* @see nsITextServicesDocument::setFilter
|
||||
*/
|
||||
void setFilter(in nsITextServicesFilter filter);
|
||||
|
||||
/**
|
||||
* Like CheckCurrentWord, checks the word you give it, returning true if it's
|
||||
* misspelled. This is faster than CheckCurrentWord because it does not
|
||||
* compute any suggestions.
|
||||
*
|
||||
* Watch out: this does not clear any suggestions left over from previous
|
||||
* calls to CheckCurrentWord, so there may be suggestions, but they will be
|
||||
* invalid.
|
||||
*/
|
||||
boolean CheckCurrentWordNoSuggest(in wstring suggestedWord);
|
||||
|
||||
};
|
||||
|
|
|
@ -1262,12 +1262,13 @@ nsEditor::MarkNodeDirty(nsIDOMNode* aNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::GetInlineSpellChecker(nsIInlineSpellChecker ** aInlineSpellChecker)
|
||||
NS_IMETHODIMP nsEditor::GetInlineSpellChecker(PRBool autoCreate,
|
||||
nsIInlineSpellChecker ** aInlineSpellChecker)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInlineSpellChecker);
|
||||
nsresult rv;
|
||||
|
||||
if (!mInlineSpellChecker) {
|
||||
if (!mInlineSpellChecker && autoCreate) {
|
||||
mInlineSpellChecker = do_CreateInstance(MOZ_INLINESPELLCHECKER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ var InlineSpellChecker =
|
|||
Init : function (editor, enable)
|
||||
{
|
||||
this.editor = editor;
|
||||
this.inlineSpellChecker = editor.inlineSpellChecker;
|
||||
this.inlineSpellChecker = editor.getInlineSpellChecker(true);
|
||||
this.inlineSpellChecker.enableRealTimeSpell = enable;
|
||||
},
|
||||
|
||||
|
|
|
@ -81,7 +81,11 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
NS_IMPL_ADDREF(mozInlineSpellChecker)
|
||||
NS_IMPL_RELEASE(mozInlineSpellChecker)
|
||||
|
||||
|
||||
mozInlineSpellChecker::SpellCheckingState
|
||||
mozInlineSpellChecker::gCanEnableSpellChecking =
|
||||
mozInlineSpellChecker::SpellCheck_Uninitialized;
|
||||
|
||||
mozInlineSpellChecker::mozInlineSpellChecker()
|
||||
{
|
||||
}
|
||||
|
@ -110,6 +114,40 @@ nsresult mozInlineSpellChecker::Cleanup()
|
|||
return UnregisterEventListeners();
|
||||
}
|
||||
|
||||
// mozInlineSpellChecker::CanEnableInlineSpellChecking
|
||||
//
|
||||
// This function can be called to see if it seems likely that we can enable
|
||||
// spellchecking before actually creating the InlineSpellChecking objects.
|
||||
//
|
||||
// The problem is that we can't get the dictionary list without actually
|
||||
// creating a whole bunch of spellchecking objects. This function tries to
|
||||
// do that and caches the result so we don't have to keep allocating those
|
||||
// objects if there are no dictionaries or spellchecking.
|
||||
//
|
||||
// This caching will prevent adding dictionaries at runtime if we start out
|
||||
// with no dictionaries! Installing dictionaries as extensions will require
|
||||
// a restart anyway, so it shouldn't be a problem.
|
||||
|
||||
PRBool mozInlineSpellChecker::CanEnableInlineSpellChecking() // static
|
||||
{
|
||||
nsresult rv;
|
||||
if (gCanEnableSpellChecking == SpellCheck_Uninitialized) {
|
||||
gCanEnableSpellChecking = SpellCheck_NotAvailable;
|
||||
|
||||
nsCOMPtr<nsIEditorSpellCheck> spellchecker =
|
||||
do_CreateInstance("@mozilla.org/editor/editorspellchecker;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
PRBool canSpellCheck = PR_FALSE;
|
||||
rv = spellchecker->CanSpellCheck(&canSpellCheck);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
if (canSpellCheck)
|
||||
gCanEnableSpellChecking = SpellCheck_Available;
|
||||
}
|
||||
return (gCanEnableSpellChecking == SpellCheck_Available);
|
||||
}
|
||||
|
||||
// the inline spell checker listens to mouse events and keyboard navigation events
|
||||
nsresult mozInlineSpellChecker::RegisterEventListeners()
|
||||
{
|
||||
|
@ -189,6 +227,9 @@ NS_IMETHODIMP mozInlineSpellChecker::SetEnableRealTimeSpell(PRBool aEnabled)
|
|||
RegisterEventListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// spellcheck the current contents
|
||||
res = SpellCheckRange(nsnull);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -297,8 +338,11 @@ NS_IMETHODIMP mozInlineSpellChecker::SpellCheckAfterEditorChange(PRInt32 action,
|
|||
break;
|
||||
|
||||
case kOpLoadHTML:
|
||||
// XXX this should cause a spellcheck of the entire document
|
||||
{
|
||||
// spell check the entire document
|
||||
SpellCheckRange(nsnull);
|
||||
break;
|
||||
}
|
||||
|
||||
case kOpInsertElement:
|
||||
PRBool iscollapsed;
|
||||
|
@ -334,6 +378,7 @@ NS_IMETHODIMP mozInlineSpellChecker::SpellCheckAfterEditorChange(PRInt32 action,
|
|||
return res;
|
||||
}
|
||||
|
||||
// supply a NULL range and this will check the entire editor
|
||||
NS_IMETHODIMP mozInlineSpellChecker::SpellCheckRange(nsIDOMRange *aRange)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
|
||||
|
@ -344,7 +389,22 @@ NS_IMETHODIMP mozInlineSpellChecker::SpellCheckRange(nsIDOMRange *aRange)
|
|||
|
||||
CleanupRangesInSelection(spellCheckSelection);
|
||||
|
||||
return SpellCheckRange(aRange,spellCheckSelection);
|
||||
if(aRange) {
|
||||
// use the given range
|
||||
rv = SpellCheckRange(aRange,spellCheckSelection);
|
||||
} else {
|
||||
// use full range: SpellCheckBetweenNodes will do the somewhat complicated
|
||||
// task of creating a range over the element we give it and call
|
||||
// SpellCheckRange(range,selection) for us
|
||||
nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
|
||||
if (!editor)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIDOMElement> rootElem;
|
||||
rv = editor->GetRootElement(getter_AddRefs(rootElem));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = SpellCheckBetweenNodes(rootElem, 0, rootElem, -1, spellCheckSelection);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP mozInlineSpellChecker::GetMispelledWord(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMRange **newword)
|
||||
|
|
|
@ -56,6 +56,12 @@ class mozInlineSpellChecker : public nsIInlineSpellChecker, nsIEditActionListene
|
|||
{
|
||||
private:
|
||||
|
||||
// Access with CanEnableInlineSpellChecking
|
||||
enum SpellCheckingState { SpellCheck_Uninitialized = -1,
|
||||
SpellCheck_NotAvailable = 0,
|
||||
SpellCheck_Available = 1};
|
||||
static SpellCheckingState gCanEnableSpellChecking;
|
||||
|
||||
nsWeakPtr mEditor;
|
||||
nsCOMPtr<nsIEditorSpellCheck> mSpellCheck;
|
||||
nsCOMPtr<nsITextServicesDocument> mTextServicesDocument;
|
||||
|
@ -113,6 +119,9 @@ public:
|
|||
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 mouseevent handler interface*/
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
|
|
|
@ -63,7 +63,41 @@
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSpellChecker)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozPersonalDictionary, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSpellI18NManager)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozInlineSpellChecker)
|
||||
|
||||
// This special constructor for the inline spell checker asks the inline
|
||||
// spell checker if we can create spell checking objects at all (ie, if there
|
||||
// are any dictionaries loaded) before trying to create one. The static
|
||||
// CanEnableInlineSpellChecking caches the value so this will be faster (we
|
||||
// have to run this code for every edit box we create, as well as for every
|
||||
// right click in those edit boxes).
|
||||
static NS_IMETHODIMP
|
||||
mozInlineSpellCheckerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
if (! mozInlineSpellChecker::CanEnableInlineSpellChecking())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
mozInlineSpellChecker* inst;
|
||||
|
||||
*aResult = NULL;
|
||||
if (NULL != aOuter) {
|
||||
rv = NS_ERROR_NO_AGGREGATION;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_NEWXPCOM(inst, mozInlineSpellChecker);
|
||||
if (NULL == inst) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
return rv;
|
||||
}
|
||||
NS_ADDREF(inst);
|
||||
rv = inst->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(inst);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Define a table of CIDs implemented by this module along with other
|
||||
|
|
|
@ -103,6 +103,7 @@ REQUIRES = xpcom \
|
|||
commandhandler \
|
||||
webbrwsr \
|
||||
uconv \
|
||||
txtsvc \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -57,6 +57,7 @@ REQUIRES = xpcom \
|
|||
necko \
|
||||
webshell \
|
||||
editor \
|
||||
txtsvc \
|
||||
intl \
|
||||
uconv \
|
||||
txmgr \
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "nsIScrollableFrame.h" //to turn off scroll bars
|
||||
#include "nsFormControlFrame.h" //for registering accesskeys
|
||||
#include "nsIDeviceContext.h" // to measure fonts
|
||||
#include "nsIInlineSpellChecker.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
|
@ -132,6 +133,8 @@
|
|||
|
||||
#define DEFAULT_COLUMN_WIDTH 20
|
||||
|
||||
#define PREF_DEFAULT_SPELLCHECK "layout.textarea.spellcheckDefault"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
|
||||
|
||||
|
@ -1661,6 +1664,63 @@ nsTextControlFrame::CreateFrameFor(nsPresContext* aPresContext,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// nsTextControlFrame::SetEnableRealTimeSpell
|
||||
//
|
||||
// This enables or disables the spellchecker based on the given flag. It
|
||||
// will only create a spellcheck object if necessary.
|
||||
|
||||
void
|
||||
nsTextControlFrame::SetEnableRealTimeSpell(PRBool aEnabled)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_ASSERTION(!aEnabled || !IsPasswordTextControl(),
|
||||
"don't enable real time spell for password controls");
|
||||
|
||||
// The editor will lazily create the spell checker object if it has not been
|
||||
// created. We only want one created if we are turning it on, since not
|
||||
// created implies there's no spell checking yet.
|
||||
nsCOMPtr<nsIInlineSpellChecker> inlineSpellChecker;
|
||||
rv = mEditor->GetInlineSpellChecker(aEnabled,
|
||||
getter_AddRefs(inlineSpellChecker));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && inlineSpellChecker) {
|
||||
inlineSpellChecker->SetEnableRealTimeSpell(aEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
// nsTextControlFrame::SyncRealTimeSpell
|
||||
//
|
||||
// This function is called to update whether inline spell checking is enabled
|
||||
// for the control. It is called on initialization and when things happen
|
||||
// that might affect spellchecking (for example, if it gets enabled or
|
||||
// disabled).
|
||||
//
|
||||
// Multi-line text controls are spellchecked when the preference is set.
|
||||
// Everything else (including read-only textareas) are not spellchecked by
|
||||
// default.
|
||||
|
||||
void
|
||||
nsTextControlFrame::SyncRealTimeSpell()
|
||||
{
|
||||
PRBool readOnly = PR_FALSE;
|
||||
if (mEditor) {
|
||||
PRUint32 flags;
|
||||
mEditor->GetFlags(&flags);
|
||||
if (flags & nsIPlaintextEditor::eEditorReadonlyMask)
|
||||
readOnly = PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool enable = PR_FALSE;
|
||||
if (!readOnly && !IsSingleLineTextControl()) {
|
||||
// multi-line text control: check the pref to see what the default should be
|
||||
// GetBoolPref defaults the value to PR_FALSE is the pref is not set
|
||||
enable = nsContentUtils::GetBoolPref(PREF_DEFAULT_SPELLCHECK);
|
||||
}
|
||||
SetEnableRealTimeSpell(enable);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::InitEditor()
|
||||
{
|
||||
|
@ -1745,6 +1805,8 @@ nsTextControlFrame::InitEditor()
|
|||
|
||||
transMgr->SetMaxTransactionCount(DEFAULT_UNDO_CAP);
|
||||
|
||||
SyncRealTimeSpell();
|
||||
|
||||
if (IsPasswordTextControl()) {
|
||||
// Disable undo for password textfields. Note that we want to do this at
|
||||
// the very end of InitEditor, so the calls to EnableUndo when setting the
|
||||
|
@ -2811,6 +2873,7 @@ nsTextControlFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
mSelCon->SetCaretEnabled(PR_TRUE);
|
||||
}
|
||||
mEditor->SetFlags(flags);
|
||||
SyncRealTimeSpell();
|
||||
}
|
||||
else if (mEditor && nsHTMLAtoms::disabled == aAttribute)
|
||||
{
|
||||
|
|
|
@ -290,6 +290,9 @@ private:
|
|||
nsresult SelectAllContents();
|
||||
nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd);
|
||||
|
||||
void SetEnableRealTimeSpell(PRBool aEnabled);
|
||||
void SyncRealTimeSpell();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
nsCOMPtr<nsISelectionController> mSelCon;
|
||||
|
|
Загрузка…
Ссылка в новой задаче