mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Backed out 2 changesets (bug 1205983) for memory leaks on a CLOSED TREE
Backed out changeset f2c49c0ab84f (bug 1205983) Backed out changeset a81630dba992 (bug 1205983)
This commit is contained in:
parent
745da49b7b
commit
3b7a3c96c4
@ -636,6 +636,13 @@ nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary)
|
|||||||
return mSpellChecker->SetCurrentDictionary(aDictionary);
|
return mSpellChecker->SetCurrentDictionary(aDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorSpellCheck::CheckCurrentDictionary()
|
||||||
|
{
|
||||||
|
mSpellChecker->CheckCurrentDictionary();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditorSpellCheck::UninitSpellChecker()
|
nsEditorSpellCheck::UninitSpellChecker()
|
||||||
{
|
{
|
||||||
|
@ -9,4 +9,3 @@ skip-if = buildapp == 'b2g' || os == 'android'
|
|||||||
[test_bug717433.html]
|
[test_bug717433.html]
|
||||||
[test_bug1204147.html]
|
[test_bug1204147.html]
|
||||||
[test_bug1200533.html]
|
[test_bug1200533.html]
|
||||||
[test_bug1205983.html]
|
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1205983
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Test for Bug 1205983</title>
|
|
||||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1205983">Mozilla Bug 1205983</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div contenteditable id="de-DE" lang="de-DE" onfocus="deFocus()">German heute ist ein guter Tag</div>
|
|
||||||
<textarea id="en-US" lang="en-US" onfocus="enFocus()">Nogoodword today is a nice day</textarea>
|
|
||||||
|
|
||||||
<pre id="test">
|
|
||||||
<script class="testbody" type="text/javascript">
|
|
||||||
|
|
||||||
function getMisspelledWords(editor) {
|
|
||||||
return editor.selectionController.getSelection(Components.interfaces.nsISelectionController.SELECTION_SPELLCHECK).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
var elem_de;
|
|
||||||
var editor_de;
|
|
||||||
var selcon_de;
|
|
||||||
var de_DE;
|
|
||||||
var hunspell;
|
|
||||||
|
|
||||||
/** Test for Bug 1205983 **/
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
SimpleTest.waitForFocus(function() {
|
|
||||||
Components.utils.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm");
|
|
||||||
|
|
||||||
var dir = Components.classes["@mozilla.org/file/directory_service;1"]
|
|
||||||
.getService(Components.interfaces.nsIProperties)
|
|
||||||
.get("CurWorkD", Components.interfaces.nsIFile);
|
|
||||||
dir.append("tests");
|
|
||||||
dir.append("editor");
|
|
||||||
dir.append("composer");
|
|
||||||
dir.append("test");
|
|
||||||
|
|
||||||
hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
|
|
||||||
.getService(Components.interfaces.mozISpellCheckingEngine);
|
|
||||||
|
|
||||||
// Install de-DE dictionary.
|
|
||||||
de_DE = dir.clone();
|
|
||||||
de_DE.append("de-DE");
|
|
||||||
is(de_DE.exists(), true, "true expected (de_DE directory should exist)");
|
|
||||||
hunspell.addDirectory(de_DE);
|
|
||||||
|
|
||||||
document.getElementById('de-DE').focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
function deFocus() {
|
|
||||||
elem_de = document.getElementById('de-DE');
|
|
||||||
|
|
||||||
onSpellCheck(elem_de, function () {
|
|
||||||
var Ci = Components.interfaces;
|
|
||||||
var editingSession = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIEditingSession);
|
|
||||||
editor_de = editingSession.getEditorForWindow(window);
|
|
||||||
selcon_de = editor_de.selectionController;
|
|
||||||
var sel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
|
|
||||||
|
|
||||||
// Check that we spelled in German, so there is only one misspelled word.
|
|
||||||
is(sel.toString(), "German", "one misspelled word expected: German");
|
|
||||||
|
|
||||||
// Now focus the textarea, which requires English spelling.
|
|
||||||
document.getElementById('en-US').focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function enFocus() {
|
|
||||||
var elem_en = document.getElementById('en-US');
|
|
||||||
var editor_en = elem_en.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
|
|
||||||
editor_en.setSpellcheckUserOverride(true);
|
|
||||||
var inlineSpellChecker = editor_en.getInlineSpellChecker(true);
|
|
||||||
|
|
||||||
onSpellCheck(elem_en, function () {
|
|
||||||
var spellchecker = inlineSpellChecker.spellChecker;
|
|
||||||
try {
|
|
||||||
currentDictonary = spellchecker.GetCurrentDictionary();
|
|
||||||
} catch(e) {}
|
|
||||||
|
|
||||||
// Check that the English dictionary is loaded and that the spell check has worked.
|
|
||||||
is(currentDictonary, "en-US", "expected en-US");
|
|
||||||
is(getMisspelledWords(editor_en), "Nogoodword", "one misspelled word expected: Nogoodword");
|
|
||||||
|
|
||||||
// So far all was boring. The important thing is whether the spell check result
|
|
||||||
// in the de-DE editor is still the same. After losing focus, no spell check
|
|
||||||
// updates should take place there.
|
|
||||||
var sel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
|
|
||||||
is(sel.toString(), "German", "one misspelled word expected: German");
|
|
||||||
|
|
||||||
// Remove the fake de_DE dictionary again.
|
|
||||||
hunspell.removeDirectory(de_DE);
|
|
||||||
|
|
||||||
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
|
|
||||||
elem_de.onfocus = null;
|
|
||||||
elem_de.blur();
|
|
||||||
elem_de.focus();
|
|
||||||
|
|
||||||
// After removal, the de_DE editor should refresh the spelling with en-US.
|
|
||||||
onSpellCheck(elem_de, function () {
|
|
||||||
var sel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
|
|
||||||
is(sel.toString(), "heute" + "ist" + "ein" + "guter",
|
|
||||||
"some misspelled words expected: heute ist ein guter");
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -98,11 +98,6 @@ function enFocus() {
|
|||||||
// Remove the fake de_DE dictionary again.
|
// Remove the fake de_DE dictionary again.
|
||||||
hunspell.removeDirectory(de_DE);
|
hunspell.removeDirectory(de_DE);
|
||||||
|
|
||||||
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
|
|
||||||
elem_de.onfocus = null;
|
|
||||||
elem_de.blur();
|
|
||||||
elem_de.focus();
|
|
||||||
|
|
||||||
// After removal, the de_DE editor should refresh the spelling with en-US.
|
// After removal, the de_DE editor should refresh the spelling with en-US.
|
||||||
onSpellCheck(elem_de, function () {
|
onSpellCheck(elem_de, function () {
|
||||||
spellchecker = inlineSpellChecker.spellChecker;
|
spellchecker = inlineSpellChecker.spellChecker;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "PlaceholderTxn.h" // for PlaceholderTxn
|
#include "PlaceholderTxn.h" // for PlaceholderTxn
|
||||||
#include "SplitNodeTxn.h" // for SplitNodeTxn
|
#include "SplitNodeTxn.h" // for SplitNodeTxn
|
||||||
#include "mozFlushType.h" // for mozFlushType::Flush_Frames
|
#include "mozFlushType.h" // for mozFlushType::Flush_Frames
|
||||||
|
#include "mozISpellCheckingEngine.h"
|
||||||
#include "mozInlineSpellChecker.h" // for mozInlineSpellChecker
|
#include "mozInlineSpellChecker.h" // for mozInlineSpellChecker
|
||||||
#include "mozilla/CheckedInt.h" // for CheckedInt
|
#include "mozilla/CheckedInt.h" // for CheckedInt
|
||||||
#include "mozilla/IMEStateManager.h" // for IMEStateManager
|
#include "mozilla/IMEStateManager.h" // for IMEStateManager
|
||||||
@ -78,6 +79,7 @@
|
|||||||
#include "nsIInlineSpellChecker.h" // for nsIInlineSpellChecker, etc
|
#include "nsIInlineSpellChecker.h" // for nsIInlineSpellChecker, etc
|
||||||
#include "nsNameSpaceManager.h" // for kNameSpaceID_None, etc
|
#include "nsNameSpaceManager.h" // for kNameSpaceID_None, etc
|
||||||
#include "nsINode.h" // for nsINode, etc
|
#include "nsINode.h" // for nsINode, etc
|
||||||
|
#include "nsIObserverService.h" // for nsIObserverService
|
||||||
#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
|
#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
|
||||||
#include "nsIPresShell.h" // for nsIPresShell
|
#include "nsIPresShell.h" // for nsIPresShell
|
||||||
#include "nsISelectionController.h" // for nsISelectionController, etc
|
#include "nsISelectionController.h" // for nsISelectionController, etc
|
||||||
@ -146,6 +148,7 @@ nsEditor::nsEditor()
|
|||||||
, mDispatchInputEvent(true)
|
, mDispatchInputEvent(true)
|
||||||
, mIsInEditAction(false)
|
, mIsInEditAction(false)
|
||||||
, mHidingCaret(false)
|
, mHidingCaret(false)
|
||||||
|
, mObservingDictionaryUpdates(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +204,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsEditor)
|
|||||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIEditorIMESupport)
|
NS_INTERFACE_MAP_ENTRY(nsIEditorIMESupport)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIEditor)
|
NS_INTERFACE_MAP_ENTRY(nsIEditor)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditor)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditor)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
@ -300,6 +304,13 @@ nsEditor::PostCreate()
|
|||||||
// update the UI with our state
|
// update the UI with our state
|
||||||
NotifyDocumentListeners(eDocumentCreated);
|
NotifyDocumentListeners(eDocumentCreated);
|
||||||
NotifyDocumentListeners(eDocumentStateChanged);
|
NotifyDocumentListeners(eDocumentStateChanged);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
|
if (obs) {
|
||||||
|
obs->AddObserver(this,
|
||||||
|
SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION,
|
||||||
|
false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update nsTextStateManager and caret if we have focus
|
// update nsTextStateManager and caret if we have focus
|
||||||
@ -437,6 +448,14 @@ nsEditor::PreDestroy(bool aDestroyingFrames)
|
|||||||
|
|
||||||
IMEStateManager::OnEditorDestroying(this);
|
IMEStateManager::OnEditorDestroying(this);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
|
if (obs) {
|
||||||
|
obs->RemoveObserver(this,
|
||||||
|
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION);
|
||||||
|
obs->RemoveObserver(this,
|
||||||
|
SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION);
|
||||||
|
}
|
||||||
|
|
||||||
// Let spellchecker clean up its observers etc. It is important not to
|
// Let spellchecker clean up its observers etc. It is important not to
|
||||||
// actually free the spellchecker here, since the spellchecker could have
|
// actually free the spellchecker here, since the spellchecker could have
|
||||||
// caused flush notifications, which could have gotten here if a textbox
|
// caused flush notifications, which could have gotten here if a textbox
|
||||||
@ -1295,6 +1314,35 @@ NS_IMETHODIMP nsEditor::GetInlineSpellChecker(bool autoCreate,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsEditor::Observe(nsISupports* aSubj, const char *aTopic,
|
||||||
|
const char16_t *aData)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!strcmp(aTopic,
|
||||||
|
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION) ||
|
||||||
|
!strcmp(aTopic,
|
||||||
|
SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION),
|
||||||
|
"Unexpected observer topic");
|
||||||
|
|
||||||
|
// When mozInlineSpellChecker::CanEnableInlineSpellChecking changes
|
||||||
|
SyncRealTimeSpell();
|
||||||
|
|
||||||
|
// When nsIEditorSpellCheck::GetCurrentDictionary changes
|
||||||
|
if (mInlineSpellChecker) {
|
||||||
|
// Do the right thing in the spellchecker, if the dictionary is no longer
|
||||||
|
// available. This will not set a new dictionary.
|
||||||
|
nsCOMPtr<nsIEditorSpellCheck> editorSpellCheck;
|
||||||
|
mInlineSpellChecker->GetSpellChecker(getter_AddRefs(editorSpellCheck));
|
||||||
|
if (editorSpellCheck) {
|
||||||
|
editorSpellCheck->CheckCurrentDictionary();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the inline spell checker to reflect the new current dictionary
|
||||||
|
mInlineSpellChecker->SpellCheckRange(nullptr); // causes recheck
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
|
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
|
||||||
{
|
{
|
||||||
bool enable = GetDesiredSpellCheckState();
|
bool enable = GetDesiredSpellCheckState();
|
||||||
@ -5158,6 +5206,29 @@ nsEditor::OnFocus(nsIDOMEventTarget* aFocusEventTarget)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsEditor::StartWatchingDictionaryChanges()
|
||||||
|
{
|
||||||
|
if (!mObservingDictionaryUpdates) {
|
||||||
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
|
if (obs) {
|
||||||
|
obs->AddObserver(this, SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION, false);
|
||||||
|
}
|
||||||
|
mObservingDictionaryUpdates = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsEditor::StopWatchingDictionaryChanges()
|
||||||
|
{
|
||||||
|
// Removing an observer that wasn't added doesn't cause any harm.
|
||||||
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
|
if (obs) {
|
||||||
|
obs->RemoveObserver(this, SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION);
|
||||||
|
}
|
||||||
|
mObservingDictionaryUpdates = false;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditor::GetSuppressDispatchingInputEvent(bool *aSuppressed)
|
nsEditor::GetSuppressDispatchingInputEvent(bool *aSuppressed)
|
||||||
{
|
{
|
||||||
|
@ -140,6 +140,7 @@ inline bool operator!(const EditAction& aOp)
|
|||||||
class nsEditor : public nsIEditor,
|
class nsEditor : public nsIEditor,
|
||||||
public nsIEditorIMESupport,
|
public nsIEditorIMESupport,
|
||||||
public nsSupportsWeakReference,
|
public nsSupportsWeakReference,
|
||||||
|
public nsIObserver,
|
||||||
public nsIPhonetic
|
public nsIPhonetic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -187,6 +188,9 @@ public:
|
|||||||
/* ------------ nsIEditorIMESupport methods -------------- */
|
/* ------------ nsIEditorIMESupport methods -------------- */
|
||||||
NS_DECL_NSIEDITORIMESUPPORT
|
NS_DECL_NSIEDITORIMESUPPORT
|
||||||
|
|
||||||
|
/* ------------ nsIObserver methods -------------- */
|
||||||
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
// nsIPhonetic
|
// nsIPhonetic
|
||||||
NS_DECL_NSIPHONETIC
|
NS_DECL_NSIPHONETIC
|
||||||
|
|
||||||
@ -245,6 +249,9 @@ public:
|
|||||||
|
|
||||||
void SwitchTextDirectionTo(uint32_t aDirection);
|
void SwitchTextDirectionTo(uint32_t aDirection);
|
||||||
|
|
||||||
|
void StartWatchingDictionaryChanges();
|
||||||
|
void StopWatchingDictionaryChanges();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsresult DetermineCurrentDirection();
|
nsresult DetermineCurrentDirection();
|
||||||
void FireInputEvent();
|
void FireInputEvent();
|
||||||
@ -887,6 +894,7 @@ protected:
|
|||||||
bool mDispatchInputEvent;
|
bool mDispatchInputEvent;
|
||||||
bool mIsInEditAction; // true while the instance is handling an edit action
|
bool mIsInEditAction; // true while the instance is handling an edit action
|
||||||
bool mHidingCaret; // whether caret is hidden forcibly.
|
bool mHidingCaret; // whether caret is hidden forcibly.
|
||||||
|
bool mObservingDictionaryUpdates; // whether the editor is observing dictionary changes.
|
||||||
|
|
||||||
friend bool NSCanUnload(nsISupports* serviceMgr);
|
friend bool NSCanUnload(nsISupports* serviceMgr);
|
||||||
friend class nsAutoTxnsConserveSelection;
|
friend class nsAutoTxnsConserveSelection;
|
||||||
|
@ -1114,6 +1114,8 @@ nsEditorEventListener::Focus(nsIDOMEvent* aEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEditor->StartWatchingDictionaryChanges();
|
||||||
|
|
||||||
mEditor->OnFocus(target);
|
mEditor->OnFocus(target);
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
||||||
@ -1130,6 +1132,8 @@ nsEditorEventListener::Blur(nsIDOMEvent* aEvent)
|
|||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(aEvent, NS_OK);
|
NS_ENSURE_TRUE(aEvent, NS_OK);
|
||||||
|
|
||||||
|
mEditor->StopWatchingDictionaryChanges();
|
||||||
|
|
||||||
// check if something else is focused. If another element is focused, then
|
// check if something else is focused. If another element is focused, then
|
||||||
// we should not change the selection.
|
// we should not change the selection.
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
|
@ -9,10 +9,16 @@ interface nsIEditor;
|
|||||||
interface nsITextServicesFilter;
|
interface nsITextServicesFilter;
|
||||||
interface nsIEditorSpellCheckCallback;
|
interface nsIEditorSpellCheckCallback;
|
||||||
|
|
||||||
[scriptable, uuid(a171c25f-e4a8-4d08-adef-b797e6377bdc)]
|
[scriptable, uuid(dd32ef3b-a7d8-43d1-9617-5f2dddbe29eb)]
|
||||||
interface nsIEditorSpellCheck : nsISupports
|
interface nsIEditorSpellCheck : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
void checkCurrentDictionary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if we can enable spellchecking. If there are no available
|
* Returns true if we can enable spellchecking. If there are no available
|
||||||
* dictionaries, this will return false.
|
* dictionaries, this will return false.
|
||||||
|
@ -114,6 +114,12 @@ public:
|
|||||||
* empty string, spellchecker will be disabled.
|
* empty string, spellchecker will be disabled.
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary) = 0;
|
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)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsISpellChecker, NS_ISPELLCHECKER_IID)
|
||||||
|
@ -160,6 +160,12 @@ NS_IMETHODIMP mozHunspell::SetDictionary(const char16_t *aDictionary)
|
|||||||
mDecoder = nullptr;
|
mDecoder = nullptr;
|
||||||
mEncoder = nullptr;
|
mEncoder = nullptr;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
|
if (obs) {
|
||||||
|
obs->NotifyObservers(nullptr,
|
||||||
|
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +226,13 @@ NS_IMETHODIMP mozHunspell::SetDictionary(const char16_t *aDictionary)
|
|||||||
else
|
else
|
||||||
mLanguage = Substring(mDictionary, 0, pos);
|
mLanguage = Substring(mDictionary, 0, pos);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
|
if (obs) {
|
||||||
|
obs->NotifyObservers(nullptr,
|
||||||
|
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,19 +604,11 @@ NS_IMETHODIMP mozHunspell::RemoveDirectory(nsIFile *aDir)
|
|||||||
{
|
{
|
||||||
mDynamicDirectories.RemoveObject(aDir);
|
mDynamicDirectories.RemoveObject(aDir);
|
||||||
LoadDictionaryList(true);
|
LoadDictionaryList(true);
|
||||||
|
|
||||||
#ifdef MOZ_THUNDERBIRD
|
|
||||||
/*
|
|
||||||
* This notification is needed for Thunderbird. Thunderbird derives the dictionary
|
|
||||||
* from the document's "lang" attribute. If a dictionary is removed,
|
|
||||||
* we need to change the "lang" attribute.
|
|
||||||
*/
|
|
||||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||||
if (obs) {
|
if (obs) {
|
||||||
obs->NotifyObservers(nullptr,
|
obs->NotifyObservers(nullptr,
|
||||||
SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION,
|
SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION,
|
||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,8 @@ interface mozISpellCheckingEngine : nsISupports {
|
|||||||
#define DICTIONARY_SEARCH_DIRECTORY "DictD"
|
#define DICTIONARY_SEARCH_DIRECTORY "DictD"
|
||||||
#define DICTIONARY_SEARCH_DIRECTORY_LIST "DictDL"
|
#define DICTIONARY_SEARCH_DIRECTORY_LIST "DictDL"
|
||||||
|
|
||||||
|
#define SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION \
|
||||||
|
"spellcheck-dictionary-update"
|
||||||
#define SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION \
|
#define SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION \
|
||||||
"spellcheck-dictionary-remove"
|
"spellcheck-dictionary-remove"
|
||||||
%}
|
%}
|
||||||
|
@ -2021,8 +2021,10 @@ nsresult mozInlineSpellChecker::CurrentDictionaryUpdated()
|
|||||||
currentDictionary.Truncate();
|
currentDictionary.Truncate();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = SpellCheckRange(nullptr);
|
if (!mPreviousDictionary.Equals(currentDictionary)) {
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
nsresult rv = SpellCheckRange(nullptr);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -428,6 +428,31 @@ mozSpellChecker::SetCurrentDictionary(const nsAString &aDictionary)
|
|||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
mozSpellChecker::CheckCurrentDictionary()
|
||||||
|
{
|
||||||
|
// If the current dictionary has been uninstalled, we need to stop using it.
|
||||||
|
// This happens when there is a current engine, but that engine has no
|
||||||
|
// current dictionary.
|
||||||
|
|
||||||
|
if (!mSpellCheckingEngine) {
|
||||||
|
// We didn't have a current dictionary
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXPIDLString dictname;
|
||||||
|
mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
|
||||||
|
|
||||||
|
if (!dictname.IsEmpty()) {
|
||||||
|
// We still have a current dictionary
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We had a current dictionary, but it has gone, so we cannot use it anymore.
|
||||||
|
mSpellCheckingEngine = nullptr;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
mozSpellChecker::SetupDoc(int32_t *outBlockOffset)
|
mozSpellChecker::SetupDoc(int32_t *outBlockOffset)
|
||||||
{
|
{
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
NS_IMETHOD GetDictionaryList(nsTArray<nsString> *aDictionaryList) override;
|
NS_IMETHOD GetDictionaryList(nsTArray<nsString> *aDictionaryList) override;
|
||||||
NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary) override;
|
NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary) override;
|
||||||
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary) override;
|
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary) override;
|
||||||
|
NS_IMETHOD CheckCurrentDictionary() override;
|
||||||
|
|
||||||
void DeleteRemoteEngine() {
|
void DeleteRemoteEngine() {
|
||||||
mEngine = nullptr;
|
mEngine = nullptr;
|
||||||
|
@ -82,25 +82,17 @@ function RunTest() {
|
|||||||
// select map dictionary
|
// select map dictionary
|
||||||
setCurrentDictionary(editor, "maputf");
|
setCurrentDictionary(editor, "maputf");
|
||||||
|
|
||||||
// Focus again, so the spelling gets updated.
|
|
||||||
textbox.blur();
|
|
||||||
textbox.focus();
|
|
||||||
|
|
||||||
onSpellCheck(textbox, function () {
|
onSpellCheck(textbox, function () {
|
||||||
// test that map dictionary is in use
|
// test that map dictionary is in use
|
||||||
is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (1)");
|
is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings");
|
||||||
is(getCurrentDictionary(editor), "maputf", "current dictionary");
|
is(getCurrentDictionary(editor), "maputf", "current dictionary");
|
||||||
|
|
||||||
// uninstall map dictionary
|
// uninstall map dictionary
|
||||||
hunspell.removeDirectory(map);
|
hunspell.removeDirectory(map);
|
||||||
|
|
||||||
// Focus again, so the spelling gets updated.
|
|
||||||
textbox.blur();
|
|
||||||
textbox.focus();
|
|
||||||
|
|
||||||
onSpellCheck(textbox, function () {
|
onSpellCheck(textbox, function () {
|
||||||
// test that map dictionary is not in use
|
// test that map dictionary is not in use
|
||||||
isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (2)");
|
isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings");
|
||||||
isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
|
isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
|
||||||
|
|
||||||
// test that base dictionary is available and map dictionary is unavailable
|
// test that base dictionary is available and map dictionary is unavailable
|
||||||
|
Loading…
Reference in New Issue
Block a user