diff --git a/editor/spellchecker/tests/mochitest.ini b/editor/spellchecker/tests/mochitest.ini
index 5261b8b1c747..5eb78058f041 100644
--- a/editor/spellchecker/tests/mochitest.ini
+++ b/editor/spellchecker/tests/mochitest.ini
@@ -40,4 +40,5 @@ skip-if = e10s
[test_bug1418629.html]
[test_bug1497480.html]
[test_bug1602526.html]
+[test_spellcheck_after_pressing_navigation_key.html]
[test_suggest.html]
diff --git a/editor/spellchecker/tests/test_spellcheck_after_pressing_navigation_key.html b/editor/spellchecker/tests/test_spellcheck_after_pressing_navigation_key.html
new file mode 100644
index 000000000000..2e0c9bd4db4e
--- /dev/null
+++ b/editor/spellchecker/tests/test_spellcheck_after_pressing_navigation_key.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+ Test for Bug 1729653
+
+
+
+
+
+
+
+
+
diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
index a854937965cd..4123e4cb9cab 100644
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -38,9 +38,11 @@
#include "mozilla/EditorBase.h"
#include "mozilla/EditorSpellCheck.h"
#include "mozilla/EditorUtils.h"
+#include "mozilla/EventListenerManager.h"
#include "mozilla/Logging.h"
#include "mozilla/RangeUtils.h"
#include "mozilla/Services.h"
+#include "mozilla/TextEvents.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/KeyboardEvent.h"
#include "mozilla/dom/KeyboardEventBinding.h"
@@ -698,38 +700,54 @@ mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking() {
// events.
nsresult mozInlineSpellChecker::RegisterEventListeners() {
- if (NS_WARN_IF(!mEditorBase)) {
+ if (MOZ_UNLIKELY(NS_WARN_IF(!mEditorBase))) {
return NS_ERROR_FAILURE;
}
StartToListenToEditSubActions();
RefPtr doc = mEditorBase->GetDocument();
- if (NS_WARN_IF(!doc)) {
+ if (MOZ_UNLIKELY(NS_WARN_IF(!doc))) {
return NS_ERROR_FAILURE;
}
- doc->AddEventListener(u"blur"_ns, this, true, false);
- doc->AddEventListener(u"click"_ns, this, false, false);
- doc->AddEventListener(u"keypress"_ns, this, false, false);
+ EventListenerManager* eventListenerManager =
+ doc->GetOrCreateListenerManager();
+ if (MOZ_UNLIKELY(NS_WARN_IF(!eventListenerManager))) {
+ return NS_ERROR_FAILURE;
+ }
+ eventListenerManager->AddEventListenerByType(
+ this, u"blur"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->AddEventListenerByType(
+ this, u"click"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->AddEventListenerByType(
+ this, u"keydown"_ns, TrustedEventsAtSystemGroupCapture());
return NS_OK;
}
// mozInlineSpellChecker::UnregisterEventListeners
nsresult mozInlineSpellChecker::UnregisterEventListeners() {
- if (NS_WARN_IF(!mEditorBase)) {
+ if (MOZ_UNLIKELY(NS_WARN_IF(!mEditorBase))) {
return NS_ERROR_FAILURE;
}
EndListeningToEditSubActions();
RefPtr doc = mEditorBase->GetDocument();
- if (NS_WARN_IF(!doc)) {
+ if (MOZ_UNLIKELY(NS_WARN_IF(!doc))) {
return NS_ERROR_FAILURE;
}
- doc->RemoveEventListener(u"blur"_ns, this, true);
- doc->RemoveEventListener(u"click"_ns, this, false);
- doc->RemoveEventListener(u"keypress"_ns, this, false);
+ EventListenerManager* eventListenerManager =
+ doc->GetOrCreateListenerManager();
+ if (MOZ_UNLIKELY(NS_WARN_IF(!eventListenerManager))) {
+ return NS_ERROR_FAILURE;
+ }
+ eventListenerManager->RemoveEventListenerByType(
+ this, u"blur"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->RemoveEventListenerByType(
+ this, u"click"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->RemoveEventListenerByType(
+ this, u"keydown"_ns, TrustedEventsAtSystemGroupCapture());
return NS_OK;
}
@@ -1959,64 +1977,72 @@ nsresult mozInlineSpellChecker::HandleNavigationEvent(
return NS_OK;
}
-NS_IMETHODIMP
-mozInlineSpellChecker::HandleEvent(Event* aEvent) {
- nsAutoString eventType;
- aEvent->GetType(eventType);
-
- if (eventType.EqualsLiteral("blur")) {
- return OnBlur(aEvent);
- }
- if (eventType.EqualsLiteral("click")) {
- return OnMouseClick(aEvent);
- }
- if (eventType.EqualsLiteral("keypress")) {
- return OnKeyPress(aEvent);
+NS_IMETHODIMP mozInlineSpellChecker::HandleEvent(Event* aEvent) {
+ WidgetEvent* widgetEvent = aEvent->WidgetEventPtr();
+ if (MOZ_UNLIKELY(!widgetEvent)) {
+ return NS_OK;
}
- return NS_OK;
+ switch (widgetEvent->mMessage) {
+ case eBlur:
+ OnBlur(*aEvent);
+ return NS_OK;
+ case eMouseClick:
+ OnMouseClick(*aEvent);
+ return NS_OK;
+ case eKeyDown:
+ OnKeyDown(*aEvent);
+ return NS_OK;
+ default:
+ MOZ_ASSERT_UNREACHABLE("You must forgot to handle new event type");
+ return NS_OK;
+ }
}
-nsresult mozInlineSpellChecker::OnBlur(Event* aEvent) {
+void mozInlineSpellChecker::OnBlur(Event& aEvent) {
// force spellcheck on blur, for instance when tabbing out of a textbox
HandleNavigationEvent(true);
- return NS_OK;
}
-nsresult mozInlineSpellChecker::OnMouseClick(Event* aMouseEvent) {
- MouseEvent* mouseEvent = aMouseEvent->AsMouseEvent();
- NS_ENSURE_TRUE(mouseEvent, NS_OK);
+void mozInlineSpellChecker::OnMouseClick(Event& aMouseEvent) {
+ MouseEvent* mouseEvent = aMouseEvent.AsMouseEvent();
+ if (MOZ_UNLIKELY(!mouseEvent)) {
+ return;
+ }
// ignore any errors from HandleNavigationEvent as we don't want to prevent
// anyone else from seeing this event.
HandleNavigationEvent(mouseEvent->Button() != 0);
- return NS_OK;
}
-nsresult mozInlineSpellChecker::OnKeyPress(Event* aKeyEvent) {
- RefPtr keyEvent = aKeyEvent->AsKeyboardEvent();
- NS_ENSURE_TRUE(keyEvent, NS_OK);
-
- uint32_t keyCode = keyEvent->KeyCode();
-
- // we only care about navigation keys that moved selection
- switch (keyCode) {
- case KeyboardEvent_Binding::DOM_VK_RIGHT:
- case KeyboardEvent_Binding::DOM_VK_LEFT:
- HandleNavigationEvent(
- false, keyCode == KeyboardEvent_Binding::DOM_VK_RIGHT ? 1 : -1);
- break;
- case KeyboardEvent_Binding::DOM_VK_UP:
- case KeyboardEvent_Binding::DOM_VK_DOWN:
- case KeyboardEvent_Binding::DOM_VK_HOME:
- case KeyboardEvent_Binding::DOM_VK_END:
- case KeyboardEvent_Binding::DOM_VK_PAGE_UP:
- case KeyboardEvent_Binding::DOM_VK_PAGE_DOWN:
- HandleNavigationEvent(true /* force a spelling correction */);
- break;
+void mozInlineSpellChecker::OnKeyDown(Event& aKeyEvent) {
+ WidgetKeyboardEvent* widgetKeyboardEvent =
+ aKeyEvent.WidgetEventPtr()->AsKeyboardEvent();
+ if (MOZ_UNLIKELY(!widgetKeyboardEvent)) {
+ return;
}
- return NS_OK;
+ // we only care about navigation keys that moved selection
+ switch (widgetKeyboardEvent->mKeyNameIndex) {
+ case KEY_NAME_INDEX_ArrowRight:
+ // XXX Does this work with RTL text?
+ HandleNavigationEvent(false, 1);
+ return;
+ case KEY_NAME_INDEX_ArrowLeft:
+ // XXX Does this work with RTL text?
+ HandleNavigationEvent(false, -1);
+ return;
+ case KEY_NAME_INDEX_ArrowUp:
+ case KEY_NAME_INDEX_ArrowDown:
+ case KEY_NAME_INDEX_Home:
+ case KEY_NAME_INDEX_End:
+ case KEY_NAME_INDEX_PageDown:
+ case KEY_NAME_INDEX_PageUp:
+ HandleNavigationEvent(true /* force a spelling correction */);
+ return;
+ default:
+ return;
+ }
}
// Used as the nsIEditorSpellCheck::UpdateCurrentDictionary callback.
diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h
index 8b8e2acab19e..a87d39d1a2d8 100644
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -220,10 +220,6 @@ class mozInlineSpellChecker final : public nsIInlineSpellChecker,
// update the cached value whenever the list of available dictionaries changes
static void UpdateCanEnableInlineSpellChecking();
- nsresult OnBlur(mozilla::dom::Event* aEvent);
- nsresult OnMouseClick(mozilla::dom::Event* aMouseEvent);
- nsresult OnKeyPress(mozilla::dom::Event* aKeyEvent);
-
mozInlineSpellChecker();
// spell checks all of the words between two nodes
@@ -336,6 +332,10 @@ class mozInlineSpellChecker final : public nsIInlineSpellChecker,
void StartToListenToEditSubActions() { mIsListeningToEditSubActions = true; }
void EndListeningToEditSubActions() { mIsListeningToEditSubActions = false; }
+
+ void OnBlur(mozilla::dom::Event& aEvent);
+ void OnMouseClick(mozilla::dom::Event& aMouseEvent);
+ void OnKeyDown(mozilla::dom::Event& aKeyEvent);
};
#endif // #ifndef mozilla_mozInlineSpellChecker_h