Bug 1119609 part.8 nsITextInputProcessor.keydown() and nsITextInputProcessor.keyup() should be able to only modify its modifier state without dispatching key events r=smaug, sr=smaug

This commit is contained in:
Masayuki Nakano 2015-02-19 15:50:19 +09:00
Родитель d8566e1894
Коммит 992c26882e
3 изменённых файлов: 83 добавлений и 6 удалений

Просмотреть файл

@ -480,6 +480,7 @@ TextInputProcessor::PrepareKeyboardEventToDispatch(
WidgetKeyboardEvent::ComputeKeyCodeFromKeyNameIndex(
aKeyboardEvent.mKeyNameIndex);
}
return NS_OK;
}
@ -523,6 +524,11 @@ TextInputProcessor::Keydown(nsIDOMKeyEvent* aDOMKeyEvent,
// event should indicate the releasing modifier is active.
ActivateModifierKey(modifierKeyData);
}
if (aKeyFlags & KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) {
return NS_OK;
}
} else if (NS_WARN_IF(aKeyFlags & KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT)) {
return NS_ERROR_INVALID_ARG;
}
keyEvent.modifiers = GetActiveModifiers();
@ -575,11 +581,17 @@ TextInputProcessor::Keyup(nsIDOMKeyEvent* aDOMKeyEvent,
}
*aDoDefault = !(aKeyFlags & KEY_DEFAULT_PREVENTED);
if (WidgetKeyboardEvent::GetModifierForKeyName(keyEvent.mKeyNameIndex) &&
!WidgetKeyboardEvent::IsLockableModifier(keyEvent.mKeyNameIndex)) {
// Inactivate modifier flag before dispatching keyup event (i.e., keyup
// event shouldn't indicate the releasing modifier is active.
InactivateModifierKey(ModifierKeyData(keyEvent));
if (WidgetKeyboardEvent::GetModifierForKeyName(keyEvent.mKeyNameIndex)) {
if (!WidgetKeyboardEvent::IsLockableModifier(keyEvent.mKeyNameIndex)) {
// Inactivate modifier flag before dispatching keyup event (i.e., keyup
// event shouldn't indicate the releasing modifier is active.
InactivateModifierKey(ModifierKeyData(keyEvent));
}
if (aKeyFlags & KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) {
return NS_OK;
}
} else if (NS_WARN_IF(aKeyFlags & KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT)) {
return NS_ERROR_INVALID_ARG;
}
keyEvent.modifiers = GetActiveModifiers();

Просмотреть файл

@ -1255,6 +1255,25 @@ function runKeyTests()
checkModifiers(testDesc, events[2], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[3], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[4], "keyup", kModifierKeys[i].key, kModifierKeys[i].code, [ ]);
// KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT shouldn't cause key events of modifier keys, but should modify the modifier state.
reset();
doPreventDefaults = [ "keypress" ];
testDesc = "A modifier key \"" + kModifierKeys[i].key + "\" (\"" + kModifierKeys[i].code + "\") with KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT and a printable key";
TIP.keydown(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
TIP.keydown(keyA);
TIP.keyup(keyA);
TIP.keyup(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
TIP.keydown(keyA);
TIP.keyup(keyA);
is(events.length, 6,
description + testDesc + " should cause 6 events");
checkModifiers(testDesc, events[0], "keydown", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[1], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[2], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[3], "keydown", "a", "KeyA", [ ]);
checkModifiers(testDesc, events[4], "keypress", "a", "KeyA", [ ]);
checkModifiers(testDesc, events[5], "keyup", "a", "KeyA", [ ]);
} else {
TIP.keydown(modKey);
checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" first keydown", [ kModifierKeys[i].key ]);
@ -1277,6 +1296,27 @@ function runKeyTests()
checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[5], "keydown", kModifierKeys[i].key, kModifierKeys[i].code, [ ]);
checkModifiers(testDesc, events[6], "keyup", kModifierKeys[i].key, kModifierKeys[i].code, [ ]);
// KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT shouldn't cause key events of modifier keys, but should modify the modifier state.
reset();
doPreventDefaults = [ "keypress" ];
testDesc = "A modifier key \"" + kModifierKeys[i].key + "\" (\"" + kModifierKeys[i].code + "\") with KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT and a printable key";
TIP.keydown(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
TIP.keyup(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
TIP.keydown(keyA);
TIP.keyup(keyA);
TIP.keydown(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
TIP.keyup(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
TIP.keydown(keyA);
TIP.keyup(keyA);
is(events.length, 6,
description + testDesc + " should cause 6 events");
checkModifiers(testDesc, events[0], "keydown", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[1], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[2], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]);
checkModifiers(testDesc, events[3], "keydown", "a", "KeyA", [ ]);
checkModifiers(testDesc, events[4], "keypress", "a", "KeyA", [ ]);
checkModifiers(testDesc, events[5], "keyup", "a", "KeyA", [ ]);
}
}
@ -1848,6 +1888,26 @@ function runErrorTests()
ok(e.message.contains("NS_ERROR_ILLEGAL_VALUE"),
description + "keyup(KEY_KEEP_KEYCODE_ZERO) should cause NS_ERROR_ILLEGAL_VALUE if the .keyCode of the key event is initialized with nonzero value");
}
// Specifying KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT with non-modifier key, it should cause an exception.
try {
var keyEvent = new KeyboardEvent("", { key: "a", code: "ShiftLeft" });
TIP.keyup(keyEvent, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
ok(false,
description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should fail if the .key value isn't a modifier key");
} catch (e) {
ok(e.message.contains("NS_ERROR_ILLEGAL_VALUE"),
description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should cause NS_ERROR_ILLEGAL_VALUE if the .key value isn't a modifier key");
}
try {
var keyEvent = new KeyboardEvent("", { key: "Enter", code: "ShiftLeft" });
TIP.keyup(keyEvent, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
ok(false,
description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should fail if the .key value isn't a modifier key");
} catch (e) {
ok(e.message.contains("NS_ERROR_ILLEGAL_VALUE"),
description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should cause NS_ERROR_ILLEGAL_VALUE if the .key value isn't a modifier key");
}
}
function runCommitCompositionTests()

Просмотреть файл

@ -224,7 +224,7 @@ interface nsITextInputProcessorCallback;
* TIP.keyup(leftShift);
*/
[scriptable, builtinclass, uuid(c8b5d3fb-5bed-4b77-b67f-77aee6ac5081)]
[scriptable, builtinclass, uuid(bb19b843-dbe2-41c5-8485-794121351d3a)]
interface nsITextInputProcessor : nsISupports
{
/**
@ -409,6 +409,11 @@ interface nsITextInputProcessor : nsISupports
// represents non-printable key. Note that if .keyCode is initialized with
// non-zero value, this flag causes throwing an exception.
const unsigned long KEY_KEEP_KEYCODE_ZERO = 0x00000010;
// If KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT is specified when the key event is
// a modifier key's, keydown() and keyup() only modifies its modifier state
// without dispatching key events. This is useful for testing odd behavior
// or emulating legacy API behavior.
const unsigned long KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT = 0x00000020;
/**
* keydown() may dispatch a keydown event and some keypress events if