Bug 1167022 part.4 Get rid of MozIMEFocus(In|Out) events r=smaug
☠☠ backed out by fb82a47beb96 ☠ ☠
authorMasayuki Nakano <masayuki@d-toybox.com>
Sun, 24 May 2015 10:11:37 +0900
changeset 277748 de4013b979a78d93badbc0493b3f190488e72a81
parent 277747 b97f76c4be1c00dc96db4354123742c1e2ee2ad3
child 277749 262801a17a4076034f8a74162a97ed83802711e4
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1167022
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1167022 part.4 Get rid of MozIMEFocus(In|Out) events r=smaug
dom/events/IMEContentObserver.cpp
dom/events/IMEContentObserver.h
dom/events/IMEStateManager.cpp
dom/events/IMEStateManager.h
widget/tests/test_imestate.html
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -38,17 +38,17 @@ namespace mozilla {
 
 using namespace widget;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IMEContentObserver)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IMEContentObserver)
   nsAutoScriptBlocker scriptBlocker;
 
-  tmp->NotifyIMEOfBlur(true);
+  tmp->NotifyIMEOfBlur();
   tmp->UnregisterObservers();
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mWidget)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelection)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRootContent)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditableNode)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditor)
@@ -165,22 +165,16 @@ IMEContentObserver::Init(nsIWidget* aWid
   if (!mRootContent && mEditableNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     // The document node is editable, but there are no contents, this document
     // is not editable.
     return;
   }
   NS_ENSURE_TRUE_VOID(mRootContent);
 
   if (firstInitialization) {
-    if (IMEStateManager::IsTestingIME()) {
-      nsIDocument* doc = aPresContext->Document();
-      (new AsyncEventDispatcher(doc, NS_LITERAL_STRING("MozIMEFocusIn"),
-                                false, false))->RunDOMEventWhenSafe();
-    }
-
     aWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_FOCUS));
 
     // NOTIFY_IME_OF_FOCUS might cause recreating IMEContentObserver
     // instance via IMEStateManager::UpdateIMEState().  So, this
     // instance might already have been destroyed, check it.
     if (!mRootContent) {
       return;
     }
@@ -215,37 +209,24 @@ IMEContentObserver::ObserveEditableNode(
     // Add scroll position listener and reflow observer to detect position and
     // size changes
     mDocShell->AddWeakScrollObserver(this);
     mDocShell->AddWeakReflowObserver(this);
   }
 }
 
 void
-IMEContentObserver::NotifyIMEOfBlur(bool aPostEvent)
+IMEContentObserver::NotifyIMEOfBlur()
 {
   // If this failed to initialize, mRootContent may be null, then, we
   // should not call NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR))
   if (!mRootContent || !mWidget) {
     return;
   }
 
-  if (IMEStateManager::IsTestingIME() && mEditableNode) {
-    nsIDocument* doc = mEditableNode->OwnerDoc();
-    if (doc) {
-      nsRefPtr<AsyncEventDispatcher> dispatcher =
-        new AsyncEventDispatcher(doc, NS_LITERAL_STRING("MozIMEFocusOut"),
-                                 false, false);
-      if (aPostEvent) {
-        dispatcher->PostDOMEvent();
-      } else {
-        dispatcher->RunDOMEventWhenSafe();
-      }
-    }
-  }
   // A test event handler might destroy the widget.
   if (mWidget) {
     mWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR));
   }
 }
 
 void
 IMEContentObserver::UnregisterObservers()
@@ -277,17 +258,17 @@ IMEContentObserver::GetPresContext() con
   return mESM ? mESM->GetPresContext() : nullptr;
 }
 
 void
 IMEContentObserver::Destroy()
 {
   // WARNING: When you change this method, you have to check Unlink() too.
 
-  NotifyIMEOfBlur(false);
+  NotifyIMEOfBlur();
   UnregisterObservers();
 
   mEditor = nullptr;
   // Even if there are some pending notification, it'll never notify the widget.
   mWidget = nullptr;
   mSelection = nullptr;
   mRootContent = nullptr;
   mEditableNode = nullptr;
--- a/dom/events/IMEContentObserver.h
+++ b/dom/events/IMEContentObserver.h
@@ -155,20 +155,18 @@ private:
   void MaybeNotifyIMEOfTextChange(const TextChangeData& aTextChangeData);
   void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition);
   void MaybeNotifyIMEOfPositionChange();
 
   void NotifyContentAdded(nsINode* aContainer, int32_t aStart, int32_t aEnd);
   void ObserveEditableNode();
   /**
    *  NotifyIMEOfBlur() notifies IME of blur.
-   *  @param aPostEvent     When true, DOM event will be posted to the thread.
-   *                        Otherwise, dispatched when safe.
    */
-  void NotifyIMEOfBlur(bool aPostEvent);
+  void NotifyIMEOfBlur();
   /**
    *  UnregisterObservers() unregisters all listeners and observers.
    */
   void UnregisterObservers();
   void StoreTextChangeData(const TextChangeData& aTextChangeData);
   void FlushMergeableNotifications();
 
 #ifdef DEBUG
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -175,17 +175,16 @@ GetNotifyIMEMessageName(IMEMessage aMess
     default:
       return "unacceptable IME notification message";
   }
 }
 
 nsIContent* IMEStateManager::sContent = nullptr;
 nsPresContext* IMEStateManager::sPresContext = nullptr;
 bool IMEStateManager::sInstalledMenuKeyboardListener = false;
-bool IMEStateManager::sIsTestingIME = false;
 bool IMEStateManager::sIsGettingNewIMEState = false;
 
 // sActiveIMEContentObserver points to the currently active IMEContentObserver.
 // sActiveIMEContentObserver is null if there is no focused editor.
 IMEContentObserver* IMEStateManager::sActiveIMEContentObserver = nullptr;
 TextCompositionArray* IMEStateManager::sTextCompositions = nullptr;
 
 // static
@@ -1201,22 +1200,16 @@ IMEStateManager::CreateIMEContentObserve
   // If it's not text editable, we don't need to create IMEContentObserver.
   if (!IsIMEObserverNeeded(widget->GetInputContext().mIMEState)) {
     MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::CreateIMEContentObserver() doesn't create "
        "IMEContentObserver because of non-editable IME state"));
     return;
   }
 
-  static bool sInitializeIsTestingIME = true;
-  if (sInitializeIsTestingIME) {
-    Preferences::AddBoolVarCache(&sIsTestingIME, "test.IME", false);
-    sInitializeIsTestingIME = false;
-  }
-
   MOZ_LOG(sISMLog, PR_LOG_DEBUG,
     ("ISM:   IMEStateManager::CreateIMEContentObserver() is creating an "
      "IMEContentObserver instance..."));
   sActiveIMEContentObserver = new IMEContentObserver();
   NS_ADDREF(sActiveIMEContentObserver);
 
   // IMEContentObserver::Init() might create another IMEContentObserver
   // instance.  So, sActiveIMEContentObserver would be replaced with new one.
--- a/dom/events/IMEStateManager.h
+++ b/dom/events/IMEStateManager.h
@@ -133,17 +133,16 @@ public:
    * Send a notification to IME.  It depends on the IME or platform spec what
    * will occur (or not occur).
    */
   static nsresult NotifyIME(IMEMessage aMessage, nsIWidget* aWidget);
   static nsresult NotifyIME(IMEMessage aMessage, nsPresContext* aPresContext);
 
   static nsINode* GetRootEditableNode(nsPresContext* aPresContext,
                                       nsIContent* aContent);
-  static bool IsTestingIME() { return sIsTestingIME; }
 
 protected:
   static nsresult OnChangeFocusInternal(nsPresContext* aPresContext,
                                         nsIContent* aContent,
                                         InputContextAction aAction);
   static void SetIMEState(const IMEState &aState,
                           nsIContent* aContent,
                           nsIWidget* aWidget,
@@ -157,17 +156,16 @@ protected:
 
   static bool IsEditable(nsINode* node);
 
   static bool IsIMEObserverNeeded(const IMEState& aState);
 
   static nsIContent*    sContent;
   static nsPresContext* sPresContext;
   static bool           sInstalledMenuKeyboardListener;
-  static bool           sIsTestingIME;
   static bool           sIsGettingNewIMEState;
 
   class MOZ_STACK_CLASS GettingNewIMEStateBlocker final
   {
   public:
     GettingNewIMEStateBlocker()
       : mOldValue(IMEStateManager::sIsGettingNewIMEState)
     {
--- a/widget/tests/test_imestate.html
+++ b/widget/tests/test_imestate.html
@@ -140,16 +140,42 @@ const kIMEEnabledSupported = navigator.p
 // We support to control IME open state on Windows and Mac actually.  However,
 // we cannot test it on Mac if the current keyboard layout is not CJK. And also
 // we cannot test it on Win32 if the system didn't be installed IME. So,
 // currently we should not run the open state testing.
 const kIMEOpenSupported = false;
 
 function runBasicTest(aIsEditable, aInDesignMode, aDescription)
 {
+  var onIMEFocusBlurHandler = null;
+  var TIPCallback = function(aTIP, aNotification) {
+    switch (aNotification.type) {
+      case "request-to-commit":
+        aTIP.commitComposition();
+        break;
+      case "request-to-cancel":
+        aTIP.cancelComposition();
+        break;
+      case "notify-focus":
+      case "notify-blur":
+        if (onIMEFocusBlurHandler) {
+          onIMEFocusBlurHandler(aNotification);
+        }
+        break;
+    }
+    return true;
+  };
+
+  var TIP = Components.classes["@mozilla.org/text-input-processor;1"]
+              .createInstance(Components.interfaces.nsITextInputProcessor);
+  if (!TIP.beginInputTransactionForTests(window, TIPCallback)) {
+    ok(false, "runBasicTest(): failed to begin input transaction");
+    return;
+  }
+
   function test(aTest)
   {
     function moveFocus(aTest, aFocusEventHandler)
     {
       if (aInDesignMode) {
         if (document.activeElement) {
           document.activeElement.blur();
         }
@@ -166,32 +192,22 @@ function runBasicTest(aIsEditable, aInDe
       var subDocument = null;
       if (element.contentDocument) {
         focusEventTarget = element.contentDocument;
         subDocument = element.contentDocument;
         element = element.contentDocument.documentElement;
       }
 
       focusEventTarget.addEventListener("focus", aFocusEventHandler, true);
-      document.addEventListener("MozIMEFocusIn", aFocusEventHandler, true);
-      document.addEventListener("MozIMEFocusOut", aFocusEventHandler, true);
-      if (subDocument) {
-        subDocument.addEventListener("MozIMEFocusIn", aFocusEventHandler, true);
-        subDocument.addEventListener("MozIMEFocusOut", aFocusEventHandler, true);
-      }
+      onIMEFocusBlurHandler = aFocusEventHandler;
 
       element.focus();
 
       focusEventTarget.removeEventListener("focus", aFocusEventHandler, true);
-      document.removeEventListener("MozIMEFocusIn", aFocusEventHandler, true);
-      document.removeEventListener("MozIMEFocusOut", aFocusEventHandler, true);
-      if (element.contentDocument) {
-        subDocument.removeEventListener("MozIMEFocusIn", aFocusEventHandler, true);
-        subDocument.removeEventListener("MozIMEFocusOut", aFocusEventHandler, true);
-      }
+      onIMEFocusBlurHandler = null;
 
       var focusedElement = gFM.focusedElement;
       if (focusedElement) {
         var bindingParent = document.getBindingParent(focusedElement);
         if (bindingParent) {
           focusedElement = bindingParent;
         }
       }
@@ -217,101 +233,101 @@ function runBasicTest(aIsEditable, aInDe
       is(gUtils.IMEIsOpen,
          aTest.changeOpened ? aTest.expectedOpened : aOpened, message);
     }
 
     // IME Enabled state testing
     var enabled = gUtils.IME_STATUS_ENABLED;
     if (kIMEEnabledSupported) {
       var focusEventCount = 0;
-      var mozIMEFocusInCount = 0;
-      var mozIMEFocusOutCount = 0;
+      var IMEReceivesFocus = 0;
+      var IMEReceivesBlur = 0;
       var IMEHasFocus = false;
 
       function onFocus(aEvent)
       {
         switch (aEvent.type) {
           case "focus":
             focusEventCount++;
             is(gUtils.IMEStatus, aTest.expectedEnabled,
                aDescription + ": " + aTest.description + ", wrong enabled state at focus event");
             break;
-          case "MozIMEFocusIn":
-            mozIMEFocusInCount++;
+          case "notify-focus":
+            IMEReceivesFocus++;
             IMEHasFocus = true;
             is(gUtils.IMEStatus, aTest.expectedEnabled,
                aDescription + ": " + aTest.description +
-                 ", MozIMEFocusIn event must be fired after IME state is updated");
+                 ", IME should receive a focus notification after IME state is updated");
             break;
-          case "MozIMEFocusOut":
-            mozIMEFocusOutCount++;
+          case "notify-blur":
+            IMEReceivesBlur++;
             IMEHasFocus = false;
             var changingStatus = !(aIsEditable && aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED);
             if (aTest.toDesignModeEditor) {
               is(gUtils.IME_STATUS_ENABLED, aTest.expectedEnabled,
                  aDescription + ": " + aTest.description +
-                   ", MozIMEFocusOut event must be fired after IME state is updated");
+                   ", IME should receive a blur notification after IME state is updated");
             } else if (changingStatus) {
               isnot(gUtils.IMEStatus, aTest.expectedEnabled,
                     aDescription + ": " + aTest.description +
-                      ", MozIMEFocusOut event must be fired before IME state is updated");
+                      ", IME should receive a blur notification before IME state is updated");
             } else {
               is(gUtils.IMEStatus, aTest.expectedEnabled,
                  aDescription + ": " + aTest.description +
-                   ", MozIMEFocusOut event must be fired with expected IME state if the state isn't being changed");
+                   ", IME should receive a blur notification and its context has expected IME state if the state isn't being changed");
             }
             break;
         }
       }
 
       if (!moveFocus(aTest, onFocus)) {
         return;
       }
 
       if (aTest.focusable) {
         if (!aTest.focusEventNotFired) {
           ok(focusEventCount > 0,
              aDescription + ": " + aTest.description + ", focus event is never fired");
           if (aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED || aTest.expectedEnabled == gUtils.IME_STATUS_PASSWORD) {
-            ok(mozIMEFocusInCount > 0,
-               aDescription + ": " + aTest.description + ", MozIMEFocusIn event should be fired");
+            ok(IMEReceivesFocus > 0,
+               aDescription + ": " + aTest.description + ", IME should receive a focus notification");
             if (aInDesignMode && !aTest.toDesignModeEditor) {
-              is(mozIMEFocusOutCount, 0,
+              is(IMEReceivesBlur, 0,
                  aDescription + ": " + aTest.description +
-                   ", MozIMEFocusOut event shouldn't be fired in designMode since focus isn't moved from another editor");
+                   ", IME shouldn't receive a blur notification in designMode since focus isn't moved from another editor");
             } else {
-              ok(mozIMEFocusOutCount > 0,
+              ok(IMEReceivesBlur > 0,
                  aDescription + ": " + aTest.description +
-                   ", MozIMEFocusOut event should be fired for the previous focused editor");
+                   ", IME should receive a blur notification for the previous focused editor");
             }
             ok(IMEHasFocus,
                aDescription + ": " + aTest.description +
-                 ", The latest MozIMEFocus* event must be MozIMEFocusIn");
+                 ", IME should have focus right now");
           } else {
-            is(mozIMEFocusInCount, 0,
+            is(IMEReceivesFocus, 0,
                aDescription + ": " + aTest.description +
-                 ", MozIMEFocusIn event shouldn't be fired");
-            ok(mozIMEFocusOutCount > 0,
+                 ", IME shouldn't receive a focus notification");
+            ok(IMEReceivesBlur > 0,
                aDescription + ": " + aTest.description +
-                 ", MozIMEFocusOut event should be fired");
+                 ", IME should receive a blur notification");
             ok(!IMEHasFocus,
                aDescription + ": " + aTest.description +
-                 ", The latest MozIMEFocus* event must be MozIMEFocusOut");
+                 ", IME shouldn't have focus right now");
           }
         } else {
           todo(focusEventCount > 0,
                aDescription + ": " + aTest.description + ", focus event should be fired");
         }
       } else {
-        is(mozIMEFocusInCount, 0,
+        is(IMEReceivesFocus, 0,
            aDescription + ": " + aTest.description +
-             ", MozIMEFocusIn event shouldn't be fired at testing non-focusable element");
-        is(mozIMEFocusOutCount, 0,
+             ", IME shouldn't receive a focus notification at testing non-focusable element");
+        is(IMEReceivesBlur, 0,
            aDescription + ": " + aTest.description +
-             ", MozIMEFocusOut event shouldn't be fired at testing non-focusable element");
+             ", IME shouldn't receive a blur notification at testing non-focusable element");
       }
 
       enabled = gUtils.IMEStatus;
       inputtype = gUtils.focusedInputType;
       is(enabled, aTest.expectedEnabled,
          aDescription + ": " + aTest.description + ", wrong enabled state");
       if (aTest.expectedType && !aInDesignMode) {
         is(inputtype, aTest.expectedType,
@@ -1444,17 +1460,16 @@ function runEditorReframeTests(aCallback
   }, 20);
 }
 
 function runTests()
 {
   if (!kIMEEnabledSupported && !kIMEOpenSupported)
     return;
 
-  SpecialPowers.pushPrefEnv({"set":[["test.IME", true]]}, function() {
   // test for normal contents.
   runBasicTest(false, false, "Testing of normal contents");
 
   // test for plugin contents
   runPluginTest();
 
   var container = document.getElementById("display");
   // test for contentEditable="true"
@@ -1494,17 +1509,16 @@ function runTests()
   // XXX temporary disable against failure
   //runTestPasswordFieldOnDialog();
 
   // Asynchronous tests
   runEditorReframeTests(function () {
     // This will call onFinish(), so, this test must be the last.
     runEditableSubframeTests();
   });
- });
 }
 
 function onFinish()
 {
   SimpleTest.finish();
 }
 
 </script>