Bug 930893 part.2 Implement KeyboardEvent.initKeyboardEvent() r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 14 Apr 2014 15:37:48 +0900
changeset 178368 220e9d8b1454df524a8c198070846d7403f0c478
parent 178367 c7c4c0d0f613dc7775789706b70846782b6bb4f0
child 178369 8e5f7f4427dfaec51e4d778ac0a73061c129e6ab
push id42245
push usermasayuki@d-toybox.com
push dateMon, 14 Apr 2014 18:16:34 +0000
treeherdermozilla-inbound@220e9d8b1454 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs930893
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 930893 part.2 Implement KeyboardEvent.initKeyboardEvent() r=smaug
dom/events/KeyboardEvent.cpp
dom/events/KeyboardEvent.h
dom/events/test/test_dom_keyboard_event.html
dom/webidl/KeyboardEvent.webidl
--- a/dom/events/KeyboardEvent.cpp
+++ b/dom/events/KeyboardEvent.cpp
@@ -271,16 +271,38 @@ KeyboardEvent::InitKeyEvent(const nsAStr
   WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
   keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
   keyEvent->keyCode = aKeyCode;
   keyEvent->charCode = aCharCode;
 
   return NS_OK;
 }
 
+void
+KeyboardEvent::InitKeyboardEvent(const nsAString& aType,
+                                 bool aCanBubble,
+                                 bool aCancelable,
+                                 nsIDOMWindow* aView,
+                                 uint32_t aDetail,
+                                 const nsAString& aKey,
+                                 uint32_t aLocation,
+                                 const nsAString& aModifiersList,
+                                 bool aRepeat,
+                                 ErrorResult& aRv)
+{
+  aRv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
+
+  WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
+  keyEvent->modifiers = UIEvent::ComputeModifierState(aModifiersList);
+  keyEvent->location = aLocation;
+  keyEvent->mIsRepeat = aRepeat;
+  keyEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
+  keyEvent->mKeyValue = aKey;
+}
+
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsresult
 NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -64,16 +64,23 @@ public:
                     uint32_t aKeyCode, uint32_t aCharCode,
                     ErrorResult& aRv)
   {
     aRv = InitKeyEvent(aType, aCanBubble, aCancelable, aView,
                        aCtrlKey, aAltKey, aShiftKey,aMetaKey,
                        aKeyCode, aCharCode);
   }
 
+  void InitKeyboardEvent(const nsAString& aType,
+                         bool aCanBubble, bool aCancelable,
+                         nsIDOMWindow* aView, uint32_t aDetail,
+                         const nsAString& aKey, uint32_t aLocation,
+                         const nsAString& aModifiersList, bool aRepeat,
+                         ErrorResult& aRv);
+
 private:
   // True, if the instance is created with Constructor().
   bool mInitializedByCtor;
   // If the instance is created with Constructor(), which may have independent
   // value.  mInitializedWhichValue stores it.  I.e., this is invalid when
   // mInitializedByCtor is false.
   uint32_t mInitialzedWhichValue;
 };
--- a/dom/events/test/test_dom_keyboard_event.html
+++ b/dom/events/test/test_dom_keyboard_event.html
@@ -15,100 +15,177 @@
 <script type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(runTests, window);
 
 function testInitializingUntrustedEvent()
 {
   const kTests = [
-    { createEventArg: "KeyboardEvent",
+    // initKeyEvent
+    { createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
       type: "keydown", bubbles: true, cancelable: true, view: null,
       ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
-      keyCode: 0x00, charCode: 0x00 },
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 0
 
-    { createEventArg: "keyboardevent",
+    { createEventArg: "keyboardevent", useInitKeyboardEvent: false,
       type: "keyup", bubbles: false, cancelable: true, view: window,
       ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
-      keyCode: 0x10, charCode: 0x00 },
+      keyCode: 0x10, charCode: 0x00,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 1
 
-    { createEventArg: "Keyboardevent",
+    { createEventArg: "Keyboardevent", useInitKeyboardEvent: false,
       type: "keypess", bubbles: true, cancelable: false, view: null,
       ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
-      keyCode: 0x11, charCode: 0x30 },
+      keyCode: 0x11, charCode: 0x30,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 2
 
-    { createEventArg: "keyboardEvent",
+    { createEventArg: "keyboardEvent", useInitKeyboardEvent: false,
       type: "boo", bubbles: false, cancelable: false, view: window,
       ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
-      keyCode: 0x30, charCode: 0x40 },
+      keyCode: 0x30, charCode: 0x40,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 3
 
-    { createEventArg: "KeyEvents",
+    { createEventArg: "KeyEvents", useInitKeyboardEvent: false,
       type: "foo", bubbles: true, cancelable: true, view: null,
       ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
-      keyCode: 0x00, charCode: 0x50 },
+      keyCode: 0x00, charCode: 0x50,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 4
 
-    { createEventArg: "keyevents",
+    { createEventArg: "keyevents", useInitKeyboardEvent: false,
       type: "bar", bubbles: false, cancelable: true, view: window,
       ctrlKey: true, altKey: true, shiftKey: false, metaKey: false,
-      keyCode: 0x00, charCode: 0x60 },
+      keyCode: 0x00, charCode: 0x60,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 5
 
-    { createEventArg: "Keyevents",
+    { createEventArg: "Keyevents", useInitKeyboardEvent: false,
       type: "keydown", bubbles: true, cancelable: false, view: null,
       ctrlKey: false, altKey: true, shiftKey: false, metaKey: true,
-      keyCode: 0x30, charCode: 0x00 },
+      keyCode: 0x30, charCode: 0x00,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 6
 
-    { createEventArg: "keyEvents",
+    { createEventArg: "keyEvents", useInitKeyboardEvent: false,
       type: "keyup", bubbles: false, cancelable: false, view: window,
       ctrlKey: true, altKey: false, shiftKey: true, metaKey: false,
-      keyCode: 0x10, charCode: 0x80 },
+      keyCode: 0x10, charCode: 0x80,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 7
 
-    { createEventArg: "KeyboardEvent",
+    { createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
       type: "keypress", bubbles: false, cancelable: false, view: window,
       ctrlKey: true, altKey: false, shiftKey: true, metaKey: true,
-      keyCode: 0x10, charCode: 0x80 },
+      keyCode: 0x10, charCode: 0x80,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 8
 
-    { createEventArg: "KeyboardEvent",
+    { createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
       type: "foo", bubbles: false, cancelable: false, view: window,
       ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
-      keyCode: 0x10, charCode: 0x80 },
+      keyCode: 0x10, charCode: 0x80,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 9
+
+    // initKeyboardEvent
+    { createEventArg: "KeyboardEvent", useInitKeyboardEvent: true,
+      type: "keydown", bubbles: true, cancelable: true, view: null,
+      ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "", location: 0,  modifiersList: "", repeat: false,
+    }, // 10
+
+    { createEventArg: "keyboardevent", useInitKeyboardEvent: true,
+      type: "keyup", bubbles: false, cancelable: true, view: window,
+      ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 2, key: "Unidentified", location: 1,  modifiersList: "Control", repeat: false,
+    }, // 11
+
+    { createEventArg: "Keyboardevent", useInitKeyboardEvent: true,
+      type: "keypess", bubbles: true, cancelable: false, view: null,
+      ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "FooBar", location: 2,  modifiersList: "Alt", repeat: true,
+    }, // 12
+
+    { createEventArg: "keyboardevent", useInitKeyboardEvent: true,
+      type: "foo", bubbles: true, cancelable: true, view: null,
+      ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "a", location: 0,  modifiersList: "Meta", repeat: false,
+    }, // 13
+
+    { createEventArg: "Keyevents", useInitKeyboardEvent: true,
+      type: "", bubbles: false, cancelable: false, view: null,
+      ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "3", location: 0,  modifiersList: "Control Alt Meta Shift", repeat: true,
+    }, // 14
+
+    { createEventArg: "keyevents", useInitKeyboardEvent: true,
+      type: "", bubbles: false, cancelable: false, view: null,
+      ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "3", location: 6,  modifiersList: "Shift", repeat: true,
+    }, // 15
+
+    { createEventArg: "keyevents", useInitKeyboardEvent: true,
+      type: "", bubbles: false, cancelable: false, view: null,
+      ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
+      keyCode: 0x00, charCode: 0x00,
+      detail: 0, key: "", location: 4,  modifiersList: "Shift, Alt", repeat: false,
+    }, // 16
   ];
 
   const kOtherModifierName = [
     "CapsLock", "NumLock", "ScrollLock", "SymbolLock", "Fn", "OS", "AltGraph"
   ];
 
   const kInvalidModifierName = [
     "shift", "control", "alt", "meta", "capslock", "numlock", "scrolllock",
     "symbollock", "fn", "os", "altgraph", "Invalid", "Shift Control",
     "Win", "Scroll"
   ];
 
   for (var i = 0; i < kTests.length; i++) {
     var description = "testInitializingUntrustedEvent, Index: " + i + ", ";
     const kTest = kTests[i];
     var e = document.createEvent(kTest.createEventArg);
-    e.initKeyEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
-                   kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
-                   kTest.keyCode, kTest.charCode);
+    if (kTest.useInitKeyboardEvent) {
+      // IE has extra argument for |.locale|.  Calling with it shouldn't cause error for compatibility with IE.
+      e.initKeyboardEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view, kTest.detail,
+                          kTest.key, kTest.location, kTest.modifiersList, kTest.repeat, "locale");
+    } else {
+      e.initKeyEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
+                     kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
+                     kTest.keyCode, kTest.charCode);
+    }
     is(e.toString(), "[object KeyboardEvent]",
        description + 'class string should be "KeyboardEvent"');
 
     for (var attr in kTest) {
-      if (attr == "createEventArg") {
+      if (attr == "createEventArg" || attr == "useInitKeyboardEvent" || attr == "modifiersList") {
         continue;
       }
-      if (attr == "keyCode") {
+      if (!kTest.useInitKeyboardEvent && attr == "keyCode") {
         // If this is keydown, keyup of keypress event, keycod must be correct.
         if (kTest.type == "keydown" || kTest.type == "keyup" || kTest.type == "keypress") {
           is(e[attr], kTest[attr], description + attr + " returns wrong value");
         // Otherwise, should be always zero (why?)
         } else {
           is(e[attr], 0, description + attr + " returns non-zero for invalid event");
         }
-      } else if (attr == "charCode") {
+      } else if (!kTest.useInitKeyboardEvent && attr == "charCode") {
         // If this is keydown or keyup event, charCode always 0.
         if (kTest.type == "keydown" || kTest.type == "keyup") {
           is(e[attr], 0, description + attr + " returns non-zero for keydown or keyup event");
         // If this is keypress event, charCode must be correct.
         } else if (kTest.type == "keypress") {
           is(e[attr], kTest[attr], description + attr + " returns wrong value");
         // Otherwise, we have a bug.
         } else {
@@ -117,19 +194,16 @@ function testInitializingUntrustedEvent(
           }
         }
       } else {
         is(e[attr], kTest[attr], description + attr + " returns wrong value");
       }
     }
     is(e.isTrusted, false, description + "isTrusted returns wrong value");
 
-    // Currently, there is no way to initialize char and key attribute values.
-    ok(e.key === "", description + "key must return empty string - got " + e.key);
-
     // getModifierState() tests
     is(e.getModifierState("Shift"), kTest.shiftKey,
        description + "getModifierState(\"Shift\") returns wrong value");
     is(e.getModifierState("Control"), kTest.ctrlKey,
        description + "getModifierState(\"Control\") returns wrong value");
     is(e.getModifierState("Alt"), kTest.altKey,
        description + "getModifierState(\"Alt\") returns wrong value");
     is(e.getModifierState("Meta"), kTest.metaKey,
--- a/dom/webidl/KeyboardEvent.webidl
+++ b/dom/webidl/KeyboardEvent.webidl
@@ -26,16 +26,27 @@ interface KeyboardEvent : UIEvent
   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;
+
+  [Throws]
+  void initKeyboardEvent(DOMString typeArg,
+                         boolean bubblesArg,
+                         boolean cancelableArg,
+                         WindowProxy? viewArg,
+                         long detailArg,
+                         DOMString keyArg,
+                         unsigned long locationArg,
+                         DOMString modifiersListArg,
+                         boolean repeatArg);
 };
 
 dictionary KeyboardEventInit : UIEventInit
 {
   DOMString      key           = "";
   unsigned long  location      = 0;
   boolean        ctrlKey       = false;
   boolean        shiftKey      = false;