--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -316,18 +316,20 @@ nsContextMenu.prototype = {
!this.onTextInput && top.gBidiUI);
},
initSpellingItems: function() {
var canSpell = InlineSpellCheckerUI.canSpellCheck;
var onMisspelling = InlineSpellCheckerUI.overMisspelling;
this.showItem("spell-check-enabled", canSpell);
this.showItem("spell-separator", canSpell || this.onEditableArea);
- document.getElementById("spell-check-enabled")
- .setAttribute("checked", canSpell && InlineSpellCheckerUI.enabled);
+ if (canSpell) {
+ document.getElementById("spell-check-enabled")
+ .setAttribute("checked", InlineSpellCheckerUI.enabled);
+ }
this.showItem("spell-add-to-dictionary", onMisspelling);
// suggestion list
this.showItem("spell-suggestions-separator", onMisspelling);
if (onMisspelling) {
var suggestionsSeparator =
document.getElementById("spell-add-to-dictionary");
--- a/editor/composer/src/nsEditorSpellCheck.cpp
+++ b/editor/composer/src/nsEditorSpellCheck.cpp
@@ -645,24 +645,16 @@ nsEditorSpellCheck::SetCurrentDictionary
// Also store it in as a preference. It will be used as a default value
// when everything else fails.
Preferences::SetString("spellchecker.dictionary", aDictionary);
}
return mSpellChecker->SetCurrentDictionary(aDictionary);
}
-NS_IMETHODIMP
-nsEditorSpellCheck::GetSpellChecker(nsISpellChecker **aSpellChecker)
-{
- *aSpellChecker = mSpellChecker;
- NS_IF_ADDREF(*aSpellChecker);
- return NS_OK;
-}
-
NS_IMETHODIMP
nsEditorSpellCheck::UninitSpellChecker()
{
NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NOT_INITIALIZED);
// Cleanup - kill the spell checker
DeleteSuggestedWordList();
mDictionaryList.Clear();
@@ -821,17 +813,21 @@ nsEditorSpellCheck::UpdateCurrentDiction
// lang attribute, we try to get a dictionary. First try, en-US. If it does
// not work, pick the first one.
if (mPreferredLang.IsEmpty()) {
nsAutoString currentDictionary;
rv = GetCurrentDictionary(currentDictionary);
if (NS_FAILED(rv) || currentDictionary.IsEmpty()) {
rv = SetCurrentDictionary(NS_LITERAL_STRING("en-US"));
if (NS_FAILED(rv)) {
- mSpellChecker->CheckCurrentDictionary();
+ nsTArray<nsString> dictList;
+ rv = mSpellChecker->GetDictionaryList(&dictList);
+ if (NS_SUCCEEDED(rv) && dictList.Length() > 0) {
+ SetCurrentDictionary(dictList[0]);
+ }
}
}
}
// If an error was thrown while setting the dictionary, just
// fail silently so that the spellchecker dialog is allowed to come
// up. The user can manually reset the language to their choice on
// the dialog if it is wrong.
--- a/editor/idl/nsIEditorSpellCheck.idl
+++ b/editor/idl/nsIEditorSpellCheck.idl
@@ -35,30 +35,21 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIEditor;
interface nsITextServicesFilter;
-%{C++
-#include "nsISpellChecker.h"
-%}
-[ptr] native nsISpellChecker(nsISpellChecker);
-[scriptable, uuid(334946c3-0e93-4aac-b662-e1b56f95d68b)]
+[scriptable, uuid(af84da62-588f-409f-847d-feecc991bd93)]
interface nsIEditorSpellCheck : nsISupports
{
- /**
- * Get the spell checker used by this editor.
- */
- [noscript] readonly attribute nsISpellChecker spellChecker;
-
/**
* 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
--- a/editor/libeditor/base/Makefile.in
+++ b/editor/libeditor/base/Makefile.in
@@ -89,10 +89,9 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
INCLUDES += \
-I$(topsrcdir)/editor/libeditor/text \
-I$(topsrcdir)/content/base/src \
-I$(topsrcdir)/content/events/src \
-I$(topsrcdir)/layout/style \
- -I$(topsrcdir)/extensions/spellcheck/src \
$(NULL)
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -19,17 +19,16 @@
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Daniel Glazman <glazman@netscape.com>
* Masayuki Nakano <masayuki@d-toybox.com>
* Mats Palmgren <matspal@gmail.com>
- * Jesper Kristensen <mail@jesperkristensen.dk>
*
* 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"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -44,21 +43,16 @@
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDOMNSEvent.h"
#include "nsIMEStateManager.h"
#include "nsFocusManager.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
-#include "nsIObserverService.h"
-#include "mozilla/Services.h"
-#include "mozISpellCheckingEngine.h"
-#include "nsIEditorSpellCheck.h"
-#include "mozInlineSpellChecker.h"
#include "nsIDOMText.h"
#include "nsIDOMElement.h"
#include "nsIDOMAttr.h"
#include "nsIDOMNode.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMNodeList.h"
@@ -208,17 +202,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEventListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsEditor)
NS_INTERFACE_MAP_ENTRY(nsIPhonetic)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIEditorIMESupport)
NS_INTERFACE_MAP_ENTRY(nsIEditor)
- NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditor)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsEditor)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsEditor)
NS_IMETHODIMP
@@ -302,23 +295,16 @@ nsEditor::PostCreate()
// nuke the modification count, so the doc appears unmodified
// do this before we notify listeners
ResetModificationCount();
// update the UI with our state
NotifyDocumentListeners(eDocumentCreated);
NotifyDocumentListeners(eDocumentStateChanged);
-
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->AddObserver(this,
- SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
- PR_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);
@@ -421,22 +407,16 @@ nsEditor::GetDesiredSpellCheckState()
}
NS_IMETHODIMP
nsEditor::PreDestroy(PRBool aDestroyingFrames)
{
if (mDidPreDestroy)
return NS_OK;
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->RemoveObserver(this,
- SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION);
- }
-
// Let spellchecker clean up its observers etc. It is important not to
// actually free the spellchecker here, since the spellchecker could have
// caused flush notifications, which could have gotten here if a textbox
// is being removed. Setting the spellchecker to NULL could free the
// object that is still in use! It will be freed when the editor is
// destroyed.
if (mInlineSpellChecker)
mInlineSpellChecker->Cleanup(aDestroyingFrames);
@@ -1298,23 +1278,16 @@ NS_IMETHODIMP nsEditor::GetInlineSpellCh
if (mDidPreDestroy) {
// Don't allow people to get or create the spell checker once the editor
// is going away.
*aInlineSpellChecker = nsnull;
return autoCreate ? NS_ERROR_NOT_AVAILABLE : NS_OK;
}
- // We don't want to show the spell checking UI if there are no spell check dictionaries available.
- PRBool canSpell = mozInlineSpellChecker::CanEnableInlineSpellChecking();
- if (!canSpell) {
- *aInlineSpellChecker = nsnull;
- return NS_ERROR_FAILURE;
- }
-
nsresult rv;
if (!mInlineSpellChecker && autoCreate) {
mInlineSpellChecker = do_CreateInstance(MOZ_INLINESPELLCHECKER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
if (mInlineSpellChecker) {
rv = mInlineSpellChecker->Init(this);
@@ -1323,59 +1296,27 @@ NS_IMETHODIMP nsEditor::GetInlineSpellCh
NS_ENSURE_SUCCESS(rv, rv);
}
NS_IF_ADDREF(*aInlineSpellChecker = mInlineSpellChecker);
return NS_OK;
}
-NS_IMETHODIMP nsEditor::Observe(nsISupports* aSubj, const char *aTopic,
- const PRUnichar *aData)
-{
- NS_ASSERTION(!strcmp(aTopic,
- SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION),
- "Unexpected observer topic");
-
- // When mozInlineSpellChecker::CanEnableInlineSpellChecking changes
- SyncRealTimeSpell();
-
- // When nsIEditorSpellCheck::GetCurrentDictionary changes
- if (mInlineSpellChecker) {
- // if the current dictionary is no longer available, find another one
- nsCOMPtr<nsIEditorSpellCheck> editorSpellCheck;
- mInlineSpellChecker->GetSpellChecker(getter_AddRefs(editorSpellCheck));
- if (editorSpellCheck) {
- nsCOMPtr<nsISpellChecker> spellChecker;
- editorSpellCheck->GetSpellChecker(getter_AddRefs(spellChecker));
- spellChecker->CheckCurrentDictionary();
- }
-
- // update the inline spell checker to reflect the new current dictionary
- mInlineSpellChecker->SpellCheckRange(nsnull); // causes recheck
- }
-
- return NS_OK;
-}
-
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
{
NS_TIME_FUNCTION;
PRBool enable = GetDesiredSpellCheckState();
- // Initializes mInlineSpellChecker
nsCOMPtr<nsIInlineSpellChecker> spellChecker;
GetInlineSpellChecker(enable, getter_AddRefs(spellChecker));
- if (mInlineSpellChecker) {
- // We might have a mInlineSpellChecker even if there are no dictionaries
- // available since we don't destroy the mInlineSpellChecker when the last
- // dictionariy is removed, but in that case spellChecker is null
- mInlineSpellChecker->SetEnableRealTimeSpell(enable && spellChecker);
+ if (spellChecker) {
+ spellChecker->SetEnableRealTimeSpell(enable);
}
return NS_OK;
}
NS_IMETHODIMP nsEditor::SetSpellcheckUserOverride(PRBool enable)
{
mSpellcheckCheckboxState = enable ? eTriTrue : eTriFalse;
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -61,17 +61,16 @@
#include "nsIDOMElement.h"
#include "nsSelectionState.h"
#include "nsIEditorSpellCheck.h"
#include "nsIInlineSpellChecker.h"
#include "nsIDOMEventTarget.h"
#include "nsStubMutationObserver.h"
#include "nsIViewManager.h"
#include "nsCycleCollectionParticipant.h"
-#include "nsIObserver.h"
class nsIDOMCharacterData;
class nsIDOMRange;
class nsIPresShell;
class ChangeAttributeTxn;
class CreateElementTxn;
class InsertElementTxn;
class DeleteElementTxn;
@@ -96,17 +95,16 @@ class nsIDOMNSEvent;
/** implementation of an editor object. it will be the controller/focal point
* for the main editor services. i.e. the GUIManager, publishing, transaction
* manager, event interfaces. the idea for the event interfaces is to have them
* delegate the actual commands to the editor independent of the XPFE implementation.
*/
class nsEditor : public nsIEditor,
public nsIEditorIMESupport,
public nsSupportsWeakReference,
- public nsIObserver,
public nsIPhonetic
{
public:
enum IterDirection
{
kIterForward,
kIterBackward
@@ -150,19 +148,16 @@ public:
already_AddRefed<nsIPresShell> GetPresShell();
void NotifyEditorObservers();
/* ------------ nsIEditor methods -------------- */
NS_DECL_NSIEDITOR
/* ------------ nsIEditorIMESupport methods -------------- */
NS_DECL_NSIEDITORIMESUPPORT
- /* ------------ nsIObserver methods -------------- */
- NS_DECL_NSIOBSERVER
-
// nsIPhonetic
NS_DECL_NSIPHONETIC
public:
NS_IMETHOD InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsIDOMNode> *aInOutNode,
--- a/editor/txtsvc/public/nsISpellChecker.h
+++ b/editor/txtsvc/public/nsISpellChecker.h
@@ -39,19 +39,19 @@
#define nsISpellChecker_h__
#include "nsISupports.h"
#include "nsTArray.h"
#define NS_SPELLCHECKER_CONTRACTID "@mozilla.org/spellchecker;1"
#define NS_ISPELLCHECKER_IID \
-{ /* 27bff957-b486-40ae-9f5d-af0cdd211868 */ \
-0x27bff957, 0xb486, 0x40ae, \
- { 0x9f, 0x5d, 0xaf, 0x0c, 0xdd, 0x21, 0x18, 0x68 } }
+{ /* E75AC48C-E948-452E-8DB3-30FEE29FE3D2 */ \
+0xe75ac48c, 0xe948, 0x452e, \
+ { 0x8d, 0xb3, 0x30, 0xfe, 0xe2, 0x9f, 0xe3, 0xd2 } }
class nsITextServicesDocument;
class nsString;
/**
* A generic interface for a spelling checker.
*/
class nsISpellChecker : public nsISupports{
@@ -141,20 +141,14 @@ public:
/**
* Tells the spellchecker to use a specific dictionary.
* @param aDictionary a string that is in the list returned
* by GetDictionaryList() or an empty string. If aDictionary is
* empty string, spellchecker will be disabled.
*/
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary) = 0;
-
- /**
- * Call this on any change in installed dictionaries to ensure that the spell
- * checker is not using a current dictionary which is no longer available.
- */
- NS_IMETHOD CheckCurrentDictionary() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsISpellChecker, NS_ISPELLCHECKER_IID)
#endif // nsISpellChecker_h__
--- a/extensions/spellcheck/Makefile.in
+++ b/extensions/spellcheck/Makefile.in
@@ -39,13 +39,9 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = spellchecker
DIRS = idl locales hunspell src
-ifdef ENABLE_TESTS
-DIRS += tests
-endif
-
include $(topsrcdir)/config/rules.mk
--- a/extensions/spellcheck/hunspell/src/Makefile.in
+++ b/extensions/spellcheck/hunspell/src/Makefile.in
@@ -66,13 +66,11 @@ CPPSRCS += affentry.cpp \
# This variable is referenced in configure.in. Make sure to change that file
# too if you need to change this variable.
DEFINES = -DHUNSPELL_STATIC
endif
include $(topsrcdir)/config/rules.mk
-INCLUDES += -I$(topsrcdir)/extensions/spellcheck/src
-
ifdef MOZ_NATIVE_HUNSPELL
CXXFLAGS += $(MOZ_HUNSPELL_CFLAGS)
endif
--- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp
+++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp
@@ -36,17 +36,16 @@
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
- * Jesper Kristensen (mail@jesperkristensen.dk)
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -66,18 +65,16 @@
#include "nsIFile.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "mozISpellI18NManager.h"
#include "nsICharsetConverterManager.h"
#include "nsUnicharUtilCIID.h"
#include "nsUnicharUtils.h"
#include "nsCRT.h"
-#include "mozInlineSpellChecker.h"
-#include "mozilla/Services.h"
#include <stdlib.h>
#include "nsIMemoryReporter.h"
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell)
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell)
@@ -120,17 +117,18 @@ NS_MEMORY_REPORTER_IMPLEMENT(Hunspell,
nsresult
mozHunspell::Init()
{
if (!mDictionaries.Init())
return NS_ERROR_OUT_OF_MEMORY;
LoadDictionaryList();
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ nsCOMPtr<nsIObserverService> obs =
+ do_GetService("@mozilla.org/observer-service;1");
if (obs) {
obs->AddObserver(this, "profile-do-change", PR_TRUE);
}
mHunspellReporter = new NS_MEMORY_REPORTER_NAME(Hunspell);
NS_RegisterMemoryReporter(mHunspellReporter);
return NS_OK;
@@ -144,58 +142,60 @@ mozHunspell::~mozHunspell()
NS_UnregisterMemoryReporter(mHunspellReporter);
}
/* attribute wstring dictionary; */
NS_IMETHODIMP mozHunspell::GetDictionary(PRUnichar **aDictionary)
{
NS_ENSURE_ARG_POINTER(aDictionary);
+ if (mDictionary.IsEmpty())
+ return NS_ERROR_NOT_INITIALIZED;
+
*aDictionary = ToNewUnicode(mDictionary);
return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
/* set the Dictionary.
* This also Loads the dictionary and initializes the converter using the dictionaries converter
*/
NS_IMETHODIMP mozHunspell::SetDictionary(const PRUnichar *aDictionary)
{
NS_ENSURE_ARG_POINTER(aDictionary);
+ if (mDictionary.Equals(aDictionary))
+ return NS_OK;
+
nsIFile* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary));
if (!affFile)
return NS_ERROR_FILE_NOT_FOUND;
nsCAutoString dictFileName, affFileName;
// XXX This isn't really good. nsIFile->NativePath isn't safe for all
// character sets on Windows.
// A better way would be to QI to nsILocalFile, and get a filehandle
// from there. Only problem is that hunspell wants a path
nsresult rv = affFile->GetNativePath(affFileName);
NS_ENSURE_SUCCESS(rv, rv);
- if (mAffixFileName.Equals(affFileName.get()))
- return NS_OK;
-
dictFileName = affFileName;
PRInt32 dotPos = dictFileName.RFindChar('.');
if (dotPos == -1)
return NS_ERROR_FAILURE;
dictFileName.SetLength(dotPos);
dictFileName.AppendLiteral(".dic");
// SetDictionary can be called multiple times, so we might have a
// valid mHunspell instance which needs cleaned up.
delete mHunspell;
mDictionary = aDictionary;
- mAffixFileName = affFileName;
mHunspell = new Hunspell(affFileName.get(),
dictFileName.get());
if (!mHunspell)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsICharsetConverterManager> ccm =
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
@@ -217,23 +217,16 @@ NS_IMETHODIMP mozHunspell::SetDictionary
if (pos == -1)
pos = mDictionary.FindChar('_');
if (pos == -1)
mLanguage.Assign(mDictionary);
else
mLanguage = Substring(mDictionary, 0, pos);
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->NotifyObservers(nsnull,
- SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
- nsnull);
- }
-
return NS_OK;
}
/* readonly attribute wstring language; */
NS_IMETHODIMP mozHunspell::GetLanguage(PRUnichar **aLanguage)
{
NS_ENSURE_ARG_POINTER(aLanguage);
@@ -335,37 +328,28 @@ NS_IMETHODIMP mozHunspell::GetDictionary
}
*aDictionaries = ans.dics;
*aCount = ans.count;
return NS_OK;
}
-static PLDHashOperator
-FindFirstString(const nsAString& aString, nsIFile* aFile, void* aClosure)
-{
- nsAString *dic = (nsAString*) aClosure;
- dic->Assign(aString);
- return PL_DHASH_STOP;
-}
-
void
mozHunspell::LoadDictionaryList()
{
mDictionaries.Clear();
nsresult rv;
nsCOMPtr<nsIProperties> dirSvc =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
if (!dirSvc)
return;
- // find built in dictionaries
nsCOMPtr<nsIFile> dictDir;
rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY,
NS_GET_IID(nsIFile), getter_AddRefs(dictDir));
if (NS_SUCCEEDED(rv)) {
LoadDictionariesFromDir(dictDir);
}
else {
// try to load gredir/dictionaries
@@ -383,77 +367,31 @@ mozHunspell::LoadDictionaryList()
NS_GET_IID(nsIFile), getter_AddRefs(appDir));
PRBool equals;
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(appDir->Equals(greDir, &equals)) && !equals) {
appDir->AppendNative(NS_LITERAL_CSTRING("dictionaries"));
LoadDictionariesFromDir(appDir);
}
}
- // find dictionaries from extensions requiring restart
nsCOMPtr<nsISimpleEnumerator> dictDirs;
rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY_LIST,
NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dictDirs));
if (NS_FAILED(rv))
return;
PRBool hasMore;
while (NS_SUCCEEDED(dictDirs->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> elem;
dictDirs->GetNext(getter_AddRefs(elem));
dictDir = do_QueryInterface(elem);
if (dictDir)
LoadDictionariesFromDir(dictDir);
}
-
- // find dictionaries from restartless extensions
- for (PRUint32 i = 0; i < mDynamicDirectories.Count(); i++) {
- LoadDictionariesFromDir(mDynamicDirectories[i]);
- }
-
- // Now we have finished updating the list of dictionaries, update the current
- // dictionary and any editors which may use it.
- mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
-
- // If the current dictionary has gone, try to replace it with another
- // dictionary of the same language
- if (!mDictionary.IsEmpty()) {
- rv = SetDictionary(mDictionary.get());
- if (NS_SUCCEEDED(rv))
- return;
- }
-
- // If we didn't find a dictionary equal to the current dictionary or we had
- // no current dictionary, just pick an arbitrary dictionary.
- nsAutoString firstDictionary;
- mDictionaries.EnumerateRead(FindFirstString, &firstDictionary);
- if (!firstDictionary.IsEmpty()) {
- rv = SetDictionary(firstDictionary.get());
- if (NS_SUCCEEDED(rv))
- return;
- }
-
- // If there are no dictionaries, set no current dictionary
- if (!mDictionary.IsEmpty()) {
- delete mHunspell;
- mHunspell = nsnull;
- mDictionary.AssignLiteral("");
- mAffixFileName.AssignLiteral("");
- mLanguage.AssignLiteral("");
- mDecoder = nsnull;
- mEncoder = nsnull;
-
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->NotifyObservers(nsnull,
- SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
- nsnull);
- }
- }
}
NS_IMETHODIMP
mozHunspell::LoadDictionariesFromDir(nsIFile* aDir)
{
nsresult rv;
PRBool check = PR_FALSE;
@@ -599,24 +537,8 @@ mozHunspell::Observe(nsISupports* aSubj,
{
NS_ASSERTION(!strcmp(aTopic, "profile-do-change"),
"Unexpected observer topic");
LoadDictionaryList();
return NS_OK;
}
-
-/* void addDirectory(in nsIFile dir); */
-NS_IMETHODIMP mozHunspell::AddDirectory(nsIFile *aDir)
-{
- mDynamicDirectories.AppendObject(aDir);
- LoadDictionaryList();
- return NS_OK;
-}
-
-/* void removeDirectory(in nsIFile dir); */
-NS_IMETHODIMP mozHunspell::RemoveDirectory(nsIFile *aDir)
-{
- mDynamicDirectories.RemoveObject(aDir);
- LoadDictionaryList();
- return NS_OK;
-}
--- a/extensions/spellcheck/hunspell/src/mozHunspell.h
+++ b/extensions/spellcheck/hunspell/src/mozHunspell.h
@@ -36,17 +36,16 @@
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
- * Jesper Kristensen (mail@jesperkristensen.dk)
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -60,17 +59,16 @@
#ifndef mozHunspell_h__
#define mozHunspell_h__
#include <hunspell.hxx>
#include "mozISpellCheckingEngine.h"
#include "mozIPersonalDictionary.h"
#include "nsString.h"
#include "nsCOMPtr.h"
-#include "nsCOMArray.h"
#include "nsIObserver.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsInterfaceHashtable.h"
#include "nsWeakReference.h"
#include "nsCycleCollectionParticipant.h"
#define MOZ_HUNSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1"
@@ -106,19 +104,15 @@ protected:
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
// Hashtable matches dictionary name to .aff file
nsInterfaceHashtable<nsStringHashKey, nsIFile> mDictionaries;
nsString mDictionary;
nsString mLanguage;
- nsCString mAffixFileName;
-
- // dynamic dirs used to search for dictionaries
- nsCOMArray<nsIFile> mDynamicDirectories;
Hunspell *mHunspell;
nsIMemoryReporter* mHunspellReporter;
};
#endif
--- a/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
+++ b/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
@@ -15,17 +15,16 @@
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Jesper Kristensen <mail@jesperkristensen.dk>
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -36,41 +35,30 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIFile;
interface mozIPersonalDictionary;
-[scriptable, uuid(8ba643a4-7ddc-4662-b976-7ec123843f10)]
+[scriptable, uuid(6eb307d6-3567-481a-971a-feb666b8ae72)]
/**
* This interface represents a SpellChecker.
*/
interface mozISpellCheckingEngine : nsISupports {
/**
* The name of the current dictionary
- *
- * Whenever getDictionaryList is not empty, this attribute contains a value
- * from that list. Whenever getDictionaryList is empty, this attribute
- * contains the empty string. Setting this attribute to a value not in
- * getDictionaryList will throw NS_ERROR_FILE_NOT_FOUND.
- *
- * The spellcheck engine will send a notification with
- * "spellcheck-dictionary-update" as topic when this changes.
*/
attribute wstring dictionary;
/**
* The language this spellchecker is using when checking
- *
- * The spellcheck engine will send a notification with
- * "spellcheck-dictionary-update" as topic when this changes.
*/
readonly attribute wstring language;
/**
* Does the engine provide its own personal dictionary?
*/
readonly attribute boolean providesPersonalDictionary;
@@ -96,45 +84,26 @@ interface mozISpellCheckingEngine : nsIS
/**
* Get the list of dictionaries
*/
void getDictionaryList([array, size_is(count)] out wstring dictionaries, out PRUint32 count);
/**
* check a word
- *
- * The spellcheck engine will send a notification with
- * "spellcheck-dictionary-update" as topic when this changes.
*/
boolean check(in wstring word);
/**
* get a list of suggestions for a misspelled word
- *
- * The spellcheck engine will send a notification with
- * "spellcheck-dictionary-update" as topic when this changes.
*/
void suggest(in wstring word,[array, size_is(count)] out wstring suggestions, out PRUint32 count);
/**
* Load dictionaries from the specified dir
*/
void loadDictionariesFromDir(in nsIFile dir);
-
- /**
- * Add dictionaries from a directory to the spell checker
- */
- void addDirectory(in nsIFile dir);
-
- /**
- * Remove dictionaries from a directory from the spell checker
- */
- void removeDirectory(in nsIFile dir);
};
%{C++
#define DICTIONARY_SEARCH_DIRECTORY "DictD"
#define DICTIONARY_SEARCH_DIRECTORY_LIST "DictDL"
-
-#define SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION \
- "spellcheck-dictionary-update"
%}
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -595,19 +595,19 @@ nsresult mozInlineSpellChecker::Cleanup(
// 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.
//
-// Whenever dictionaries are added or removed at runtime, this value must be
-// updated before an observer notification is sent out about the change, to
-// avoid editors getting a wrong cached result.
+// 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 // static
mozInlineSpellChecker::CanEnableInlineSpellChecking()
{
nsresult rv;
if (gCanEnableSpellChecking == SpellCheck_Uninitialized) {
gCanEnableSpellChecking = SpellCheck_NotAvailable;
@@ -620,22 +620,16 @@ mozInlineSpellChecker::CanEnableInlineSp
NS_ENSURE_SUCCESS(rv, PR_FALSE);
if (canSpellCheck)
gCanEnableSpellChecking = SpellCheck_Available;
}
return (gCanEnableSpellChecking == SpellCheck_Available);
}
-void // static
-mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking()
-{
- gCanEnableSpellChecking = SpellCheck_Uninitialized;
-}
-
// mozInlineSpellChecker::RegisterEventListeners
//
// The inline spell checker listens to mouse events and keyboard navigation+ // events.
nsresult
mozInlineSpellChecker::RegisterEventListeners()
{
nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -224,20 +224,18 @@ private:
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIEDITACTIONLISTENER
NS_DECL_NSIINLINESPELLCHECKER
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozInlineSpellChecker, nsIDOMEventListener)
- // returns true if there are any spell checking dictionaries available
+ // returns true if it looks likely that we can enable real-time spell checking
static PRBool CanEnableInlineSpellChecking();
- // update the cached value whenever the list of available dictionaries changes
- static void UpdateCanEnableInlineSpellChecking();
nsresult Blur(nsIDOMEvent* aEvent);
nsresult MouseClick(nsIDOMEvent* aMouseEvent);
nsresult KeyPress(nsIDOMEvent* aKeyEvent);
mozInlineSpellChecker();
virtual ~mozInlineSpellChecker();
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -13,17 +13,16 @@
*
* The Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.com
- * Jesper Kristensen <mail@jesperkristensen.dk>
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -73,16 +72,19 @@ mozSpellChecker::~mozSpellChecker()
}
nsresult
mozSpellChecker::Init()
{
mPersonalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
mSpellCheckingEngine = nsnull;
+ mCurrentEngineContractId = nsnull;
+ mDictionariesMap.Init();
+ InitSpellCheckDictionaryMap();
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::SetDocument(nsITextServicesDocument *aDoc, PRBool aFromStartofDoc)
{
mTsDoc = aDoc;
@@ -300,55 +302,45 @@ mozSpellChecker::GetPersonalDictionary(n
nsAutoString word;
while (NS_SUCCEEDED(words->HasMore(&hasMore)) && hasMore) {
words->GetNext(word);
aWordList->AppendElement(word);
}
return NS_OK;
}
+struct AppendNewStruct
+{
+ nsTArray<nsString> *dictionaryList;
+ PRBool failed;
+};
+
+static PLDHashOperator
+AppendNewString(const nsAString& aString, nsCString*, void* aClosure)
+{
+ AppendNewStruct *ans = (AppendNewStruct*) aClosure;
+
+ if (!ans->dictionaryList->AppendElement(aString))
+ {
+ ans->failed = PR_TRUE;
+ return PL_DHASH_STOP;
+ }
+
+ return PL_DHASH_NEXT;
+}
+
NS_IMETHODIMP
mozSpellChecker::GetDictionaryList(nsTArray<nsString> *aDictionaryList)
{
- nsresult rv;
-
- // For catching duplicates
- nsClassHashtable<nsStringHashKey, nsCString> dictionaries;
- dictionaries.Init();
-
- nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
- rv = GetEngineList(&spellCheckingEngines);
- NS_ENSURE_SUCCESS(rv, rv);
-
- for (PRUint32 i = 0; i < spellCheckingEngines.Count(); i++) {
- nsCOMPtr<mozISpellCheckingEngine> engine = spellCheckingEngines[i];
+ AppendNewStruct ans = {aDictionaryList, PR_FALSE};
- PRUint32 count = 0;
- PRUnichar **words = NULL;
- engine->GetDictionaryList(&words, &count);
- for (PRUint32 k = 0; k < count; k++) {
- nsAutoString dictName;
-
- dictName.Assign(words[k]);
+ mDictionariesMap.EnumerateRead(AppendNewString, &ans);
- // Skip duplicate dictionaries. Only take the first one
- // for each name.
- if (dictionaries.Get(dictName, NULL))
- continue;
-
- dictionaries.Put(dictName, NULL);
-
- if (!aDictionaryList->AppendElement(dictName)) {
- NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
- return NS_ERROR_OUT_OF_MEMORY;
- }
- }
-
- NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
- }
+ if (ans.failed)
+ return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::GetCurrentDictionary(nsAString &aDictionary)
{
nsXPIDLString dictname;
@@ -359,97 +351,54 @@ mozSpellChecker::GetCurrentDictionary(ns
mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
aDictionary = dictname;
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::SetCurrentDictionary(const nsAString &aDictionary)
{
- mSpellCheckingEngine = nsnull;
+ nsresult rv;
+ nsCString *contractId;
if (aDictionary.IsEmpty()) {
+ mCurrentEngineContractId = nsnull;
+ mSpellCheckingEngine = nsnull;
return NS_OK;
}
- nsresult rv;
- nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
- rv = GetEngineList(&spellCheckingEngines);
- NS_ENSURE_SUCCESS(rv, rv);
-
- for (PRUint32 i = 0; i < spellCheckingEngines.Count(); i++) {
- nsCOMPtr<mozISpellCheckingEngine> engine = spellCheckingEngines[i];
+ if (!mDictionariesMap.Get(aDictionary, &contractId)){
+ NS_WARNING("Dictionary not found");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
- rv = engine->SetDictionary(PromiseFlatString(aDictionary).get());
- if (NS_SUCCEEDED(rv)) {
- mSpellCheckingEngine = engine;
+ if (!mCurrentEngineContractId || !mCurrentEngineContractId->Equals(*contractId)){
+ mSpellCheckingEngine = do_GetService(contractId->get(), &rv);
+ if (NS_FAILED(rv))
+ return rv;
- nsCOMPtr<mozIPersonalDictionary> personalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
- mSpellCheckingEngine->SetPersonalDictionary(personalDictionary.get());
-
- return NS_OK;
- }
+ mCurrentEngineContractId = contractId;
}
- // We could not find any engine with the requested dictionary
- return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
-mozSpellChecker::CheckCurrentDictionary()
-{
- // Check if the current engine has any dictionaries available. If not,
- // the last dictionary has just been uninstalled, and we need to stop using
- // the engine.
- if (mSpellCheckingEngine) {
- nsXPIDLString dictname;
-
- mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
-
- // We still have a dictionary, so keep using that.
- if (!dictname.IsEmpty()) {
- return NS_OK;
- }
-
- // Our current dictionary has gone, so we cannot use the engine anymore.
- mSpellCheckingEngine = nsnull;
+ nsresult res;
+ res = mSpellCheckingEngine->SetDictionary(PromiseFlatString(aDictionary).get());
+ if(NS_FAILED(res)){
+ NS_WARNING("Dictionary load failed");
+ return res;
}
- // We have no current engine. Pick one.
- nsresult rv;
- nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
- rv = GetEngineList(&spellCheckingEngines);
- NS_ENSURE_SUCCESS(rv, rv);
-
- for (PRUint32 i = 0; i < spellCheckingEngines.Count(); i++) {
- nsCOMPtr<mozISpellCheckingEngine> engine = spellCheckingEngines[i];
-
- nsXPIDLString dictname;
-
- engine->GetDictionary(getter_Copies(dictname));
-
- if (!dictname.IsEmpty()) {
- mSpellCheckingEngine = engine;
+ mSpellCheckingEngine->SetPersonalDictionary(mPersonalDictionary);
- nsCOMPtr<mozIPersonalDictionary> personalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
- mSpellCheckingEngine->SetPersonalDictionary(personalDictionary.get());
-
- nsXPIDLString language;
- nsresult rv;
- nsCOMPtr<mozISpellI18NManager> serv = do_GetService("@mozilla.org/spellchecker/i18nmanager;1", &rv);
- if(serv && NS_SUCCEEDED(rv)) {
- serv->GetUtil(language.get(), getter_AddRefs(mConverter));
- }
-
- return NS_OK;
- }
+ nsXPIDLString language;
+
+ nsCOMPtr<mozISpellI18NManager> serv(do_GetService("@mozilla.org/spellchecker/i18nmanager;1", &res));
+ if(serv && NS_SUCCEEDED(res)){
+ res = serv->GetUtil(language.get(),getter_AddRefs(mConverter));
}
-
- // There are no dictionaries available
- return NS_OK;
+ return res;
}
nsresult
mozSpellChecker::SetupDoc(PRInt32 *outBlockOffset)
{
nsresult rv;
nsITextServicesDocument::TSDBlockSelectionStatus blockStatus;
@@ -523,20 +472,21 @@ mozSpellChecker::GetCurrentBlockIndex(ns
} while (NS_SUCCEEDED(result) && !isDone);
*outBlockIndex = blockIndex;
return result;
}
nsresult
-mozSpellChecker::GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aSpellCheckingEngines)
+mozSpellChecker::InitSpellCheckDictionaryMap()
{
nsresult rv;
PRBool hasMoreEngines;
+ nsTArray<nsCString> contractIds;
nsCOMPtr<nsICategoryManager> catMgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (!catMgr)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISimpleEnumerator> catEntries;
// Get contract IDs of registrated external spell-check engines and
@@ -553,29 +503,57 @@ mozSpellChecker::GetEngineList(nsCOMArra
if (NS_FAILED(rv))
return rv;
nsCString contractId;
rv = entry->GetData(contractId);
if (NS_FAILED(rv))
return rv;
+ contractIds.AppendElement(contractId);
+ }
+
+ contractIds.AppendElement(NS_LITERAL_CSTRING(DEFAULT_SPELL_CHECKER));
+
+ // Retrieve dictionaries from all available spellcheckers and
+ // fill mDictionariesMap hash (only the first dictionary with the
+ // each name is used).
+ for (PRUint32 i=0;i < contractIds.Length();i++){
+ PRUint32 count,k;
+ PRUnichar **words;
+
+ const nsCString& contractId = contractIds[i];
+
// Try to load spellchecker engine. Ignore errors silently
// except for the last one (HunSpell).
nsCOMPtr<mozISpellCheckingEngine> engine =
do_GetService(contractId.get(), &rv);
- if (NS_SUCCEEDED(rv)) {
- aSpellCheckingEngines->AppendObject(engine);
+ if (NS_FAILED(rv)){
+ // Fail if not succeeded to load HunSpell. Ignore errors
+ // for external spellcheck engines.
+ if (i==contractIds.Length()-1){
+ return rv;
+ }
+
+ continue;
}
- }
+
+ engine->GetDictionaryList(&words,&count);
+ for(k=0;k<count;k++){
+ nsAutoString dictName;
- // Try to load HunSpell spellchecker engine.
- nsCOMPtr<mozISpellCheckingEngine> engine =
- do_GetService(DEFAULT_SPELL_CHECKER, &rv);
- if (NS_FAILED(rv)) {
- // Fail if not succeeded to load HunSpell. Ignore errors
- // for external spellcheck engines.
- return rv;
+ dictName.Assign(words[k]);
+
+ nsCString dictCName = NS_ConvertUTF16toUTF8(dictName);
+
+ // Skip duplicate dictionaries. Only take the first one
+ // for each name.
+ if (mDictionariesMap.Get(dictName, NULL))
+ continue;
+
+ mDictionariesMap.Put(dictName, new nsCString(contractId));
+ }
+
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
}
- aSpellCheckingEngines->AppendObject(engine);
return NS_OK;
}
--- a/extensions/spellcheck/src/mozSpellChecker.h
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -15,17 +15,16 @@
* The Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.com
- * Jesper Kristensen <mail@jesperkristensen.dk>
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -35,17 +34,16 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozSpellChecker_h__
#define mozSpellChecker_h__
#include "nsCOMPtr.h"
-#include "nsCOMArray.h"
#include "nsISpellChecker.h"
#include "nsString.h"
#include "nsITextServicesDocument.h"
#include "mozIPersonalDictionary.h"
#include "mozISpellCheckingEngine.h"
#include "nsClassHashtable.h"
#include "nsVoidArray.h"
#include "nsTArray.h"
@@ -72,25 +70,29 @@ public:
NS_IMETHOD AddWordToPersonalDictionary(const nsAString &aWord);
NS_IMETHOD RemoveWordFromPersonalDictionary(const nsAString &aWord);
NS_IMETHOD GetPersonalDictionary(nsTArray<nsString> *aWordList);
NS_IMETHOD GetDictionaryList(nsTArray<nsString> *aDictionaryList);
NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary);
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary);
- NS_IMETHOD CheckCurrentDictionary();
protected:
nsCOMPtr<mozISpellI18NUtil> mConverter;
nsCOMPtr<nsITextServicesDocument> mTsDoc;
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
+ // Hastable maps directory name to the spellchecker contract ID
+ nsClassHashtable<nsStringHashKey, nsCString> mDictionariesMap;
+
+ nsString mDictionaryName;
+ nsCString *mCurrentEngineContractId;
nsCOMPtr<mozISpellCheckingEngine> mSpellCheckingEngine;
PRBool mFromStart;
nsresult SetupDoc(PRInt32 *outBlockOffset);
nsresult GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *outBlockIndex);
- nsresult GetEngineList(nsCOMArray<mozISpellCheckingEngine> *aDictionaryList);
+ nsresult InitSpellCheckDictionaryMap();
};
#endif // mozSpellChecker_h__
--- a/extensions/spellcheck/src/mozSpellCheckerFactory.cpp
+++ b/extensions/spellcheck/src/mozSpellCheckerFactory.cpp
@@ -54,17 +54,49 @@ 0x8227F019, 0xAFC7, 0x461e,
0x9fe5d975, 0x9bd, 0x44aa, \
{ 0xa0, 0x1a, 0x66, 0x40, 0x2e, 0xa2, 0x86, 0x57} }
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozHunspell, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(mozHunspellDirProvider)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozSpellChecker, Init)
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 nsresult
+mozInlineSpellCheckerConstructor(nsISupports *aOuter, REFNSIID aIID,
+ void **aResult)
+{
+ if (! mozInlineSpellChecker::CanEnableInlineSpellChecking())
+ return NS_ERROR_FAILURE;
+
+ nsresult rv;
+
+ *aResult = NULL;
+ if (NULL != aOuter) {
+ rv = NS_ERROR_NO_AGGREGATION;
+ return rv;
+ }
+
+ mozInlineSpellChecker* inst = new 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;
+}
NS_DEFINE_NAMED_CID(MOZ_HUNSPELL_CID);
NS_DEFINE_NAMED_CID(HUNSPELLDIRPROVIDER_CID);
NS_DEFINE_NAMED_CID(NS_SPELLCHECKER_CID);
NS_DEFINE_NAMED_CID(MOZ_PERSONALDICTIONARY_CID);
NS_DEFINE_NAMED_CID(MOZ_SPELLI18NMANAGER_CID);
NS_DEFINE_NAMED_CID(MOZ_INLINESPELLCHECKER_CID);
deleted file mode 100644
--- a/extensions/spellcheck/tests/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-relativesrcdir = extensions/spellcheck/tests
-
-include $(DEPTH)/config/autoconf.mk
-
-DIRS = chrome
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/Makefile.in
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-relativesrcdir = extensions/spellcheck/tests/chrome
-
-include $(DEPTH)/config/autoconf.mk
-
-DIRS = base map
-
-include $(topsrcdir)/config/rules.mk
-
-_TEST_FILES = test_add_remove_dictionaries.xul \
- $(NULL)
-
-libs:: $(_TEST_FILES)
- $(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/base/Makefile.in
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-relativesrcdir = extensions/spellcheck/tests/chrome/base
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
-_TEST_FILES = base_utf.dic \
- base_utf.aff \
- $(NULL)
-
-libs:: $(_TEST_FILES)
- $(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/base/base_utf.aff
+++ /dev/null
@@ -1,198 +0,0 @@
-# OpenOffice.org’s en_US.aff file
-# with Unicode apostrophe: ’
-
-SET UTF-8
-TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
-
-MAXNGRAMSUGS 1
-WORDCHARS .'’
-
-PFX A Y 1
-PFX A 0 re .
-
-PFX I Y 1
-PFX I 0 in .
-
-PFX U Y 1
-PFX U 0 un .
-
-PFX C Y 1
-PFX C 0 de .
-
-PFX E Y 1
-PFX E 0 dis .
-
-PFX F Y 1
-PFX F 0 con .
-
-PFX K Y 1
-PFX K 0 pro .
-
-SFX V N 2
-SFX V e ive e
-SFX V 0 ive [^e]
-
-SFX N Y 3
-SFX N e ion e
-SFX N y ication y
-SFX N 0 en [^ey]
-
-SFX X Y 3
-SFX X e ions e
-SFX X y ications y
-SFX X 0 ens [^ey]
-
-SFX H N 2
-SFX H y ieth y
-SFX H 0 th [^y]
-
-SFX Y Y 1
-SFX Y 0 ly .
-
-SFX G Y 2
-SFX G e ing e
-SFX G 0 ing [^e]
-
-SFX J Y 2
-SFX J e ings e
-SFX J 0 ings [^e]
-
-SFX D Y 4
-SFX D 0 d e
-SFX D y ied [^aeiou]y
-SFX D 0 ed [^ey]
-SFX D 0 ed [aeiou]y
-
-SFX T N 4
-SFX T 0 st e
-SFX T y iest [^aeiou]y
-SFX T 0 est [aeiou]y
-SFX T 0 est [^ey]
-
-SFX R Y 4
-SFX R 0 r e
-SFX R y ier [^aeiou]y
-SFX R 0 er [aeiou]y
-SFX R 0 er [^ey]
-
-SFX Z Y 4
-SFX Z 0 rs e
-SFX Z y iers [^aeiou]y
-SFX Z 0 ers [aeiou]y
-SFX Z 0 ers [^ey]
-
-SFX S Y 4
-SFX S y ies [^aeiou]y
-SFX S 0 s [aeiou]y
-SFX S 0 es [sxzh]
-SFX S 0 s [^sxzhy]
-
-SFX P Y 3
-SFX P y iness [^aeiou]y
-SFX P 0 ness [aeiou]y
-SFX P 0 ness [^y]
-
-SFX M Y 1
-SFX M 0 's .
-
-SFX B Y 3
-SFX B 0 able [^aeiou]
-SFX B 0 able ee
-SFX B e able [^aeiou]e
-
-SFX L Y 1
-SFX L 0 ment .
-
-REP 88
-REP a ei
-REP ei a
-REP a ey
-REP ey a
-REP ai ie
-REP ie ai
-REP are air
-REP are ear
-REP are eir
-REP air are
-REP air ere
-REP ere air
-REP ere ear
-REP ere eir
-REP ear are
-REP ear air
-REP ear ere
-REP eir are
-REP eir ere
-REP ch te
-REP te ch
-REP ch ti
-REP ti ch
-REP ch tu
-REP tu ch
-REP ch s
-REP s ch
-REP ch k
-REP k ch
-REP f ph
-REP ph f
-REP gh f
-REP f gh
-REP i igh
-REP igh i
-REP i uy
-REP uy i
-REP i ee
-REP ee i
-REP j di
-REP di j
-REP j gg
-REP gg j
-REP j ge
-REP ge j
-REP s ti
-REP ti s
-REP s ci
-REP ci s
-REP k cc
-REP cc k
-REP k qu
-REP qu k
-REP kw qu
-REP o eau
-REP eau o
-REP o ew
-REP ew o
-REP oo ew
-REP ew oo
-REP ew ui
-REP ui ew
-REP oo ui
-REP ui oo
-REP ew u
-REP u ew
-REP oo u
-REP u oo
-REP u oe
-REP oe u
-REP u ieu
-REP ieu u
-REP ue ew
-REP ew ue
-REP uff ough
-REP oo ieu
-REP ieu oo
-REP ier ear
-REP ear ier
-REP ear air
-REP air ear
-REP w qu
-REP qu w
-REP z ss
-REP ss z
-REP shun tion
-REP shun sion
-REP shun cion
-McDonalds’sá/w
-McDonald’sszá/g3) st:McDonaldâs po:noun_prs is:TRANS
-McDonald’sszal/g4) st:McDonaldâs po:noun_prs is:INSTR
-McDonald’ssal/w
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/base/base_utf.dic
+++ /dev/null
@@ -1,29 +0,0 @@
-28
-created/U
-create/XKVNGADS
-imply/GNSDX
-natural/PUY
-like/USPBY
-convey/BDGS
-look/GZRDS
-text
-hello
-said
-sawyer
-NASA
-rotten
-day
-tomorrow
-seven
-FAQ/SM
-can’t
-doesn’t
-etc
-won’t
-lip
-text
-horrifying
-speech
-suggest
-uncreate/V
-Hunspell
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/map/Makefile.in
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-relativesrcdir = extensions/spellcheck/tests/chrome/map
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
-_TEST_FILES = maputf.dic \
- maputf.aff \
- $(NULL)
-
-libs:: $(_TEST_FILES)
- $(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/map/maputf.aff
+++ /dev/null
@@ -1,11 +0,0 @@
-# With MAP suggestion, Hunspell can add missing accents to a word.
-
-SET UTF-8
-
-# switch off ngram suggestion for testing
-MAXNGRAMSUGS 0
-
-MAP 3
-MAP uúü
-MAP öóo
-MAP ß(ss)
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/map/maputf.dic
+++ /dev/null
@@ -1,4 +0,0 @@
-3
-Frühstück
-tükörfúró
-groß
deleted file mode 100644
--- a/extensions/spellcheck/tests/chrome/test_add_remove_dictionaries.xul
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-
-<window title="Add and remove dictionaries test"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- onload="RunTest();">
- <title>Add and remove dictionaries test</title>
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-
- <script type="application/javascript">
- <![CDATA[
-SimpleTest.waitForExplicitFinish();
-
-function getMisspelledWords(editor) {
- return editor.selectionController.getSelection(Components.interfaces.nsISelectionController.SELECTION_SPELLCHECK).toString();
-}
-
-function getDictionaryList(editor) {
- var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
- var o1 = {};
- spellchecker.GetDictionaryList(o1, {});
- return o1.value;
-}
-
-function getCurrentDictionary(editor) {
- var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
- return spellchecker.GetCurrentDictionary();
-}
-
-function setCurrentDictionary(editor, dictionary) {
- var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
- spellchecker.SetCurrentDictionary(dictionary);
-}
-
-function RunTest() {
- var editor = document.getElementById('textbox').editor;
-
- var dir = Components.classes["@mozilla.org/file/directory_service;1"].
- getService(Components.interfaces.nsIProperties).
- get("CurWorkD", Components.interfaces.nsIFile);
- dir.append("chrome");
- dir.append("extensions");
- dir.append("spellcheck");
- dir.append("tests");
- dir.append("chrome");
-
- var hunspell = Components
- .classes["@mozilla.org/spellchecker/engine;1"]
- .getService(Components.interfaces.mozISpellCheckingEngine);
-
- // install base dictionary
- var base = dir.clone();
- base.append("base");
- ok(base.exists());
- hunspell.addDirectory(base);
-
- // install map dictionary
- var map = dir.clone();
- map.append("map");
- ok(map.exists());
- hunspell.addDirectory(map);
-
- // test that base and map dictionaries are available
- var dicts = getDictionaryList(editor);
- isnot(dicts.indexOf("base_utf"), -1, "base is available");
- isnot(dicts.indexOf("maputf"), -1, "map is available");
-
- // select base dictionary
- setCurrentDictionary(editor, "base_utf");
-
- SimpleTest.executeSoon(function() {
- // test that base dictionary is in use
- is(getMisspelledWords(editor), "Frühstück" + "qwertyu", "base misspellings");
- is(getCurrentDictionary(editor), "base_utf", "current dictionary");
-
- // select map dictionary
- setCurrentDictionary(editor, "maputf");
-
- SimpleTest.executeSoon(function() {
- // test that map dictionary is in use
- is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings");
- is(getCurrentDictionary(editor), "maputf", "current dictionary");
-
- // uninstall map dictionary
- hunspell.removeDirectory(map);
-
- SimpleTest.executeSoon(function() {
- // test that map dictionary is not in use
- isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings");
- isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
-
- // test that base dictionary is available and map dictionary is unavailable
- var dicts = getDictionaryList(editor);
- isnot(dicts.indexOf("base_utf"), -1, "base is available");
- is(dicts.indexOf("maputf"), -1, "map is unavailable");
-
- // uninstall base dictionary
- hunspell.removeDirectory(base);
-
- SimpleTest.finish();
- });
- });
- });
-}
- ]]>
- </script>
- <textbox id="textbox" spellcheck="true" value="created imply Frühstück tomorrow qwertyu"/>
-</window>