зеркало из https://github.com/mozilla/pjs.git
Bug 295285 - onpopupshowing does not expose accesskeys (event.shiftKey) r=enn
This commit is contained in:
Родитель
73fb32b307
Коммит
c4cdffded8
|
@ -767,6 +767,9 @@ protected:
|
|||
// root prescontext's root frame.
|
||||
nsIntPoint mCachedMousePoint;
|
||||
|
||||
// cached modifiers
|
||||
PRInt8 mCachedModifiers;
|
||||
|
||||
// set to the currently active menu bar, if any
|
||||
nsMenuBarFrame* mActiveMenuBar;
|
||||
|
||||
|
|
|
@ -73,6 +73,11 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#define FLAG_ALT 0x01
|
||||
#define FLAG_CONTROL 0x02
|
||||
#define FLAG_SHIFT 0x04
|
||||
#define FLAG_META 0x08
|
||||
|
||||
const nsNavigationDirection DirectionFromKeyCodeTable[2][6] = {
|
||||
{
|
||||
eNavigationDirection_Last, // NS_VK_END
|
||||
|
@ -140,6 +145,7 @@ NS_IMPL_ISUPPORTS4(nsXULPopupManager,
|
|||
nsXULPopupManager::nsXULPopupManager() :
|
||||
mRangeOffset(0),
|
||||
mCachedMousePoint(0, 0),
|
||||
mCachedModifiers(0),
|
||||
mActiveMenuBar(nsnull),
|
||||
mPopups(nsnull),
|
||||
mNoHidePanels(nsnull),
|
||||
|
@ -462,6 +468,8 @@ nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup,
|
|||
}
|
||||
}
|
||||
|
||||
mCachedModifiers = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMNSUIEvent> uiEvent = do_QueryInterface(aEvent);
|
||||
if (uiEvent) {
|
||||
uiEvent->GetRangeParent(getter_AddRefs(mRangeParent));
|
||||
|
@ -475,6 +483,22 @@ nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup,
|
|||
nsEvent* event;
|
||||
event = privateEvent->GetInternalNSEvent();
|
||||
if (event) {
|
||||
if (event->eventStructType == NS_MOUSE_EVENT ||
|
||||
event->eventStructType == NS_KEY_EVENT) {
|
||||
nsInputEvent* inputEvent = static_cast<nsInputEvent*>(event);
|
||||
if (inputEvent->isAlt) {
|
||||
mCachedModifiers |= FLAG_ALT;
|
||||
}
|
||||
if (inputEvent->isControl) {
|
||||
mCachedModifiers |= FLAG_CONTROL;
|
||||
}
|
||||
if (inputEvent->isShift) {
|
||||
mCachedModifiers |= FLAG_SHIFT;
|
||||
}
|
||||
if (inputEvent->isMeta) {
|
||||
mCachedModifiers |= FLAG_META;
|
||||
}
|
||||
}
|
||||
nsIDocument* doc = aPopup->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
|
@ -1187,10 +1211,19 @@ nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup,
|
|||
}
|
||||
|
||||
event.refPoint = mCachedMousePoint;
|
||||
|
||||
event.isAlt = !!(mCachedModifiers & FLAG_ALT);
|
||||
event.isControl = !!(mCachedModifiers & FLAG_CONTROL);
|
||||
event.isShift = !!(mCachedModifiers & FLAG_SHIFT);
|
||||
event.isMeta = !!(mCachedModifiers & FLAG_META);
|
||||
|
||||
nsEventDispatcher::Dispatch(popup, presContext, &event, nsnull, &status);
|
||||
|
||||
mCachedMousePoint = nsIntPoint(0, 0);
|
||||
mOpeningPopup = nsnull;
|
||||
|
||||
mCachedModifiers = 0;
|
||||
|
||||
// if a panel, blur whatever has focus so that the panel can take the focus.
|
||||
// This is done after the popupshowing event in case that event is cancelled.
|
||||
// Using noautofocus="true" will disable this behaviour, which is needed for
|
||||
|
|
|
@ -3,6 +3,22 @@ var gTrigger = null;
|
|||
var gIsMenu = false;
|
||||
var gScreenX = -1, gScreenY = -1;
|
||||
var gCachedEvent = null;
|
||||
var gCachedEvent2 = null;
|
||||
|
||||
function cacheEvent(modifiers)
|
||||
{
|
||||
var cachedEvent = null;
|
||||
|
||||
var mouseFn = function(event) {
|
||||
cachedEvent = event;
|
||||
}
|
||||
|
||||
window.addEventListener("mousedown", mouseFn, false);
|
||||
synthesizeMouse(document.documentElement, 0, 0, modifiers);
|
||||
window.removeEventListener("mousedown", mouseFn, false);
|
||||
|
||||
return cachedEvent;
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
|
@ -15,17 +31,13 @@ function runTests()
|
|||
|
||||
gIsMenu = gTrigger.boxObject instanceof Components.interfaces.nsIMenuBoxObject;
|
||||
|
||||
var mouseFn = function(event) {
|
||||
gScreenX = event.screenX;
|
||||
gScreenY = event.screenY;
|
||||
// cache the event so that we can use it in calls to openPopup
|
||||
gCachedEvent = event;
|
||||
}
|
||||
// a hacky way to get the screen position of the document. Cache the event
|
||||
// so that we can use it in calls to openPopup.
|
||||
gCachedEvent = cacheEvent({ shiftKey: true });
|
||||
gScreenX = gCachedEvent.screenX;
|
||||
gScreenY = gCachedEvent.screenY;
|
||||
gCachedEvent2 = cacheEvent({ altKey: true, ctrlKey: true, shiftKey: true, metaKey: true });
|
||||
|
||||
// a hacky way to get the screen position of the document
|
||||
window.addEventListener("mousedown", mouseFn, false);
|
||||
synthesizeMouse(document.documentElement, 0, 0, { });
|
||||
window.removeEventListener("mousedown", mouseFn, false);
|
||||
startPopupTests(popupTests);
|
||||
}
|
||||
|
||||
|
@ -254,7 +266,7 @@ var popupTests = [
|
|||
// can be used to override the popup's position. This test also passes an
|
||||
// event to openPopup to check the trigger node.
|
||||
testname: "open popup anchored with override",
|
||||
events: [ "popupshowing thepopup", "popupshown thepopup" ],
|
||||
events: [ "popupshowing thepopup 0010", "popupshown thepopup" ],
|
||||
test: function(testname, step) {
|
||||
// attribute overrides the position passed in
|
||||
gMenuPopup.setAttribute("position", "end_after");
|
||||
|
@ -403,7 +415,7 @@ var popupTests = [
|
|||
},
|
||||
{
|
||||
testname: "open context popup at screen",
|
||||
events: [ "popupshowing thepopup", "popupshown thepopup" ],
|
||||
events: [ "popupshowing thepopup 0010", "popupshown thepopup" ],
|
||||
test: function(testname, step) {
|
||||
gExpectedTriggerNode = gCachedEvent.target;
|
||||
gMenuPopup.openPopupAtScreen(gScreenX + 8, gScreenY + 16, true, gCachedEvent);
|
||||
|
@ -558,6 +570,14 @@ var popupTests = [
|
|||
checkActive(gMenuPopup, "", testname);
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "open context popup at screen with all modifiers set",
|
||||
events: [ "popupshowing thepopup 1111", "popupshown thepopup" ],
|
||||
autohide: "thepopup",
|
||||
test: function(testname, step) {
|
||||
gMenuPopup.openPopupAtScreen(gScreenX + 8, gScreenY + 16, true, gCachedEvent2);
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "open popup with open property",
|
||||
events: [ "popupshowing thepopup", "popupshown thepopup" ],
|
||||
|
|
|
@ -133,6 +133,16 @@ function eventOccurred(event)
|
|||
matches = eventitem[0] == event.type && eventitem[1] == event.target.id;
|
||||
}
|
||||
|
||||
var modifiersMask = eventitem[2];
|
||||
if (modifiersMask) {
|
||||
var m = "";
|
||||
m += event.altKey ? '1' : '0';
|
||||
m += event.ctrlKey ? '1' : '0';
|
||||
m += event.shiftKey ? '1' : '0';
|
||||
m += event.metaKey ? '1' : '0';
|
||||
is(m, modifiersMask, test.testname + " modifiers mask matches");
|
||||
}
|
||||
|
||||
var expectedState;
|
||||
switch (event.type) {
|
||||
case "popupshowing": expectedState = "showing"; break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче