Bug 993234 part.1 Implement KeyboardEvent.isComposing r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 10 Apr 2014 16:11:36 +0900
changeset 177922 839bf025c534f875fe59b1c681c7bcd3c5dd69ea
parent 177921 7699524771b13734c0215b0be6b695868d898e0b
child 177923 d40a8916b7e70824d066488d309fed4662f3d8e1
push id26569
push userryanvm@gmail.com
push dateFri, 11 Apr 2014 04:11:36 +0000
treeherdermozilla-central@783c5013dbec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs993234
milestone31.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 993234 part.1 Implement KeyboardEvent.isComposing r=smaug
dom/events/EventStateManager.cpp
dom/events/IMEStateManager.cpp
dom/events/KeyboardEvent.cpp
dom/events/KeyboardEvent.h
dom/webidl/KeyboardEvent.webidl
widget/TextEvents.h
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/TextComposition.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/UIEvent.h"
 
 #include "ContentEventHandler.h"
 #include "WheelHandlingHelper.h"
@@ -604,16 +605,26 @@ EventStateManager::PreHandleEvent(nsPres
     }
     // then fall through...
   case NS_KEY_DOWN:
   case NS_KEY_UP:
     {
       nsIContent* content = GetFocusedContent();
       if (content)
         mCurrentTargetContent = content;
+
+      // NOTE: Don't refer TextComposition::IsComposing() since DOM Level 3
+      //       Events defines that KeyboardEvent.isComposing is true when it's
+      //       dispatched after compositionstart and compositionend.
+      //       TextComposition::IsComposing() is false even before
+      //       compositionend if there is no composing string.
+      WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
+      nsRefPtr<TextComposition> composition =
+        IMEStateManager::GetTextCompositionFor(keyEvent);
+      keyEvent->mIsComposing = !!composition;
     }
     break;
   case NS_WHEEL_WHEEL:
   case NS_WHEEL_START:
   case NS_WHEEL_STOP:
     {
       NS_ASSERTION(aEvent->mFlags.mIsTrusted,
                    "Untrusted wheel event shouldn't be here");
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -763,14 +763,16 @@ IMEStateManager::GetTextCompositionFor(n
     sTextCompositions->GetCompositionFor(aWidget);
   return textComposition.forget();
 }
 
 // static
 already_AddRefed<TextComposition>
 IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent)
 {
-  MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsTextEvent(),
-             "aEvent has to be WidgetCompositionEvent or WidgetTextEvent");
+  MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsTextEvent() ||
+             aEvent->AsKeyboardEvent(),
+             "aEvent has to be WidgetCompositionEvent, WidgetTextEvent or "
+             "WidgetKeyboardEvent");
   return GetTextCompositionFor(aEvent->widget);
 }
 
 } // namespace mozilla
--- a/dom/events/KeyboardEvent.cpp
+++ b/dom/events/KeyboardEvent.cpp
@@ -100,16 +100,22 @@ KeyboardEvent::Repeat()
 NS_IMETHODIMP
 KeyboardEvent::GetRepeat(bool* aIsRepeat)
 {
   NS_ENSURE_ARG_POINTER(aIsRepeat);
   *aIsRepeat = Repeat();
   return NS_OK;
 }
 
+bool
+KeyboardEvent::IsComposing()
+{
+  return mEvent->AsKeyboardEvent()->mIsComposing;
+}
+
 NS_IMETHODIMP
 KeyboardEvent::GetModifierState(const nsAString& aKey,
                                 bool* aState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   *aState = GetModifierState(aKey);
   return NS_OK;
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -41,16 +41,17 @@ public:
   bool MetaKey();
 
   bool GetModifierState(const nsAString& aKey)
   {
     return GetModifierStateInternal(aKey);
   }
 
   bool Repeat();
+  bool IsComposing();
   uint32_t CharCode();
   uint32_t KeyCode();
   virtual uint32_t Which() MOZ_OVERRIDE;
   uint32_t Location();
 
   void InitKeyEvent(const nsAString& aType, bool aCanBubble, bool aCancelable,
                     nsIDOMWindow* aView, bool aCtrlKey, bool aAltKey,
                     bool aShiftKey, bool aMetaKey,
--- a/dom/webidl/KeyboardEvent.webidl
+++ b/dom/webidl/KeyboardEvent.webidl
@@ -22,14 +22,15 @@ interface KeyboardEvent : UIEvent
   const unsigned long DOM_KEY_LOCATION_LEFT     = 0x01;
   const unsigned long DOM_KEY_LOCATION_RIGHT    = 0x02;
   const unsigned long DOM_KEY_LOCATION_NUMPAD   = 0x03;
   const unsigned long DOM_KEY_LOCATION_MOBILE   = 0x04;
   const unsigned long DOM_KEY_LOCATION_JOYSTICK = 0x05;
 
   readonly attribute unsigned long location;
   readonly attribute boolean       repeat;
+  readonly attribute boolean       isComposing;
 
   readonly attribute DOMString key;
 };
 
 // Mozilla extensions
 KeyboardEvent implements KeyEvent;
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -73,24 +73,27 @@ private:
 
   WidgetKeyboardEvent()
   {
   }
 
 public:
   virtual WidgetKeyboardEvent* AsKeyboardEvent() MOZ_OVERRIDE { return this; }
 
-  WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) :
-    WidgetInputEvent(aIsTrusted, aMessage, aWidget, NS_KEY_EVENT),
-    keyCode(0), charCode(0),
-    location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD),
-    isChar(false), mIsRepeat(false),
-    mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified),
-    mNativeKeyEvent(nullptr),
-    mUniqueId(0)
+  WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
+    : WidgetInputEvent(aIsTrusted, aMessage, aWidget, NS_KEY_EVENT)
+    , keyCode(0)
+    , charCode(0)
+    , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD)
+    , isChar(false)
+    , mIsRepeat(false)
+    , mIsComposing(false)
+    , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified)
+    , mNativeKeyEvent(nullptr)
+    , mUniqueId(0)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
     MOZ_ASSERT(eventStructType == NS_KEY_EVENT,
                "Duplicate() must be overridden by sub class");
     // Not copying widget, it is a weak reference.
@@ -114,16 +117,20 @@ public:
   // OS translated Unicode chars which are used for accesskey and accelkey
   // handling. The handlers will try from first character to last character.
   nsTArray<AlternativeCharCode> alternativeCharCodes;
   // Indicates whether the event signifies a printable character
   bool isChar;
   // Indicates whether the event is generated by auto repeat or not.
   // if this is keyup event, always false.
   bool mIsRepeat;
+  // Indicates whether the event is generated during IME (or deadkey)
+  // composition.  This is initialized by EventStateManager.  So, key event
+  // dispatchers don't need to initialize this.
+  bool mIsComposing;
   // DOM KeyboardEvent.key
   KeyNameIndex mKeyNameIndex;
   // DOM KeyboardEvent.key only when mKeyNameIndex is KEY_NAME_INDEX_USE_STRING.
   nsString mKeyValue;
   // OS-specific native event can optionally be preserved
   void* mNativeKeyEvent;
   // Unique id associated with a keydown / keypress event. Used in identifing
   // keypress events for removal from async event dispatch queue in metrofx
@@ -150,16 +157,17 @@ public:
     AssignInputEventData(aEvent, aCopyTargets);
 
     keyCode = aEvent.keyCode;
     charCode = aEvent.charCode;
     location = aEvent.location;
     alternativeCharCodes = aEvent.alternativeCharCodes;
     isChar = aEvent.isChar;
     mIsRepeat = aEvent.mIsRepeat;
+    mIsComposing = aEvent.mIsComposing;
     mKeyNameIndex = aEvent.mKeyNameIndex;
     mKeyValue = aEvent.mKeyValue;
     // Don't copy mNativeKeyEvent because it may be referred after its instance
     // is destroyed.
     mNativeKeyEvent = nullptr;
     mUniqueId = aEvent.mUniqueId;
   }
 };