зеркало из https://github.com/mozilla/gecko-dev.git
Bug 607224, add property that specifies if a menu was opened via the keyboard, r=neil,a=blocking
This commit is contained in:
Родитель
20bd210d2f
Коммит
5829e48552
|
@ -41,7 +41,7 @@
|
|||
interface nsIDOMElement;
|
||||
interface nsIDOMKeyEvent;
|
||||
|
||||
[scriptable, uuid(F5099746-5049-4e81-A03E-945D5110FEE2)]
|
||||
[scriptable, uuid(3931F141-D640-48AB-A792-719D62CF1736)]
|
||||
interface nsIMenuBoxObject : nsISupports
|
||||
{
|
||||
void openMenu(in boolean openFlag);
|
||||
|
@ -49,6 +49,9 @@ interface nsIMenuBoxObject : nsISupports
|
|||
attribute nsIDOMElement activeChild;
|
||||
|
||||
boolean handleKeyPress(in nsIDOMKeyEvent keyEvent);
|
||||
|
||||
// true if the menu or menubar was opened via a keypress.
|
||||
readonly attribute boolean openedWithKey;
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
|
|
@ -151,6 +151,7 @@ nsMenuBarFrame::SetActive(PRBool aActiveFlag)
|
|||
InstallKeyboardNavigator();
|
||||
}
|
||||
else {
|
||||
mActiveByKeyboard = PR_FALSE;
|
||||
RemoveKeyboardNavigator();
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,9 @@ public:
|
|||
// needs to be closed.
|
||||
nsMenuFrame* ToggleMenuActiveState();
|
||||
|
||||
PRBool IsActiveByKeyboard() { return mActiveByKeyboard; }
|
||||
void SetActiveByKeyboard() { mActiveByKeyboard = PR_TRUE; }
|
||||
|
||||
// indicate that a menu on the menubar was closed. Returns true if the caller
|
||||
// may deselect the menuitem.
|
||||
virtual PRBool MenuClosed();
|
||||
|
@ -137,6 +140,10 @@ protected:
|
|||
PRPackedBool mStayActive;
|
||||
|
||||
PRPackedBool mIsActive; // Whether or not the menu bar is active (a menu item is highlighted or shown).
|
||||
|
||||
// whether the menubar was made active via the keyboard.
|
||||
PRPackedBool mActiveByKeyboard;
|
||||
|
||||
// The current menu that is active (highlighted), which may not be open. This will
|
||||
// be null if no menu is active.
|
||||
nsMenuFrame* mCurrentMenu;
|
||||
|
|
|
@ -179,6 +179,9 @@ nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent)
|
|||
{
|
||||
// The access key was down and is now up, and no other
|
||||
// keys were pressed in between.
|
||||
if (!mMenuBarFrame->IsActive()) {
|
||||
mMenuBarFrame->SetActiveByKeyboard();
|
||||
}
|
||||
ToggleMenuActiveState();
|
||||
}
|
||||
mAccessKeyDown = PR_FALSE;
|
||||
|
@ -257,6 +260,7 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
// so, we'll know the menu got activated.
|
||||
nsMenuFrame* result = mMenuBarFrame->FindMenuWithShortcut(keyEvent);
|
||||
if (result) {
|
||||
mMenuBarFrame->SetActiveByKeyboard();
|
||||
mMenuBarFrame->SetActive(PR_TRUE);
|
||||
result->OpenMenu(PR_TRUE);
|
||||
|
||||
|
@ -275,6 +279,7 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
if ((GetModifiers(keyEvent) & ~MODIFIER_CONTROL) == 0) {
|
||||
// The F10 key just went down by itself or with ctrl pressed.
|
||||
// In Windows, both of these activate the menu bar.
|
||||
mMenuBarFrame->SetActiveByKeyboard();
|
||||
ToggleMenuActiveState();
|
||||
|
||||
aKeyEvent->StopPropagation();
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsMenuFrame.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
|
@ -157,6 +158,28 @@ NS_IMETHODIMP nsMenuBoxObject::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent, PRBool*
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuBoxObject::GetOpenedWithKey(PRBool* aOpenedWithKey)
|
||||
{
|
||||
*aOpenedWithKey = PR_FALSE;
|
||||
|
||||
nsIFrame* frame = GetFrame(PR_FALSE);
|
||||
if (!frame || frame->GetType() != nsGkAtoms::menuFrame)
|
||||
return NS_OK;
|
||||
|
||||
frame = frame->GetParent();
|
||||
while (frame) {
|
||||
if (frame->GetType() == nsGkAtoms::menuBarFrame) {
|
||||
*aOpenedWithKey = (static_cast<nsMenuBarFrame *>(frame))->IsActiveByKeyboard();
|
||||
return NS_OK;
|
||||
}
|
||||
frame = frame->GetParent();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -85,7 +85,9 @@
|
|||
|
||||
window.opener.SimpleTest.waitForFocus(function () {
|
||||
gFilePopup = document.getElementById("filepopup");
|
||||
document.getElementById("filemenu").focus();
|
||||
var filemenu = document.getElementById("filemenu");
|
||||
filemenu.focus();
|
||||
is(filemenu.openedWithKey, false, "initial openedWithKey");
|
||||
startPopupTests(popupTests);
|
||||
}, window);
|
||||
|
||||
|
@ -98,6 +100,7 @@ var popupTests = [
|
|||
result: function (testname) {
|
||||
checkActive(gFilePopup, "", testname);
|
||||
checkOpen("filemenu", testname);
|
||||
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -168,6 +171,7 @@ var popupTests = [
|
|||
checkActive(document.getElementById("editpopup"), expected, testname);
|
||||
checkClosed("filemenu", testname);
|
||||
checkOpen("editmenu", testname);
|
||||
is(document.getElementById("editmenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -188,7 +192,10 @@ var popupTests = [
|
|||
"DOMMenuItemInactive copy" ];
|
||||
},
|
||||
test: function() { synthesizeKey("VK_ENTER", { }); },
|
||||
result: function(testname) { checkClosed("editmenu", testname); }
|
||||
result: function(testname) {
|
||||
checkClosed("editmenu", testname);
|
||||
is(document.getElementById("editmenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
// pressing Alt + a key should open the corresponding menu
|
||||
|
@ -199,7 +206,10 @@ var popupTests = [
|
|||
"DOMMenuItemActive toolbar", "popupshown viewpopup" ];
|
||||
},
|
||||
test: function() { synthesizeKey("V", { altKey: true }); },
|
||||
result: function(testname) { checkOpen("viewmenu", testname); }
|
||||
result: function(testname) {
|
||||
checkOpen("viewmenu", testname);
|
||||
is(document.getElementById("viewmenu").openedWithKey, true, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
// open the submenu with the cursor right key
|
||||
|
@ -289,7 +299,10 @@ var popupTests = [
|
|||
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
|
||||
events: [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ],
|
||||
test: function() { synthesizeKey("VK_ALT", { }); },
|
||||
result: function(testname) { checkClosed("filemenu", testname); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("filemenu").openedWithKey, true, testname + " openedWithKey");
|
||||
checkClosed("filemenu", testname);
|
||||
},
|
||||
},
|
||||
{
|
||||
// pressing cursor left should select the previous menu but not open it
|
||||
|
@ -315,7 +328,10 @@ var popupTests = [
|
|||
"DOMMenuItemInactive filemenu", "DOMMenuItemActive helpmenu",
|
||||
"DOMMenuItemActive contents", "popupshown helppopup" ],
|
||||
test: function() { synthesizeKey("H", { }); },
|
||||
result: function(testname) { checkOpen("helpmenu", testname); },
|
||||
result: function(testname) {
|
||||
checkOpen("helpmenu", testname);
|
||||
is(document.getElementById("helpmenu").openedWithKey, true, testname + " openedWithKey");
|
||||
},
|
||||
},
|
||||
{
|
||||
testname: "open with accelerator again",
|
||||
|
@ -324,7 +340,10 @@ var popupTests = [
|
|||
"DOMMenuItemActive helpmenu", "DOMMenuItemActive contents",
|
||||
"popupshown helppopup" ],
|
||||
test: function() { synthesizeKey("H", { altKey: true }); },
|
||||
result: function(testname) { checkOpen("helpmenu", testname); },
|
||||
result: function(testname) {
|
||||
checkOpen("helpmenu", testname);
|
||||
is(document.getElementById("helpmenu").openedWithKey, true, testname + " openedWithKey");
|
||||
},
|
||||
},
|
||||
{
|
||||
// check that pressing cursor up skips non menuitems
|
||||
|
@ -358,7 +377,10 @@ var popupTests = [
|
|||
testname: "F10 to activate menubar",
|
||||
events: [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ],
|
||||
test: function() { synthesizeKey("VK_F10", { }); },
|
||||
result: function(testname) { checkClosed("filemenu", testname); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("filemenu").openedWithKey, true, testname + " openedWithKey");
|
||||
checkClosed("filemenu", testname);
|
||||
},
|
||||
},
|
||||
{
|
||||
// pressing cursor down should open a menu
|
||||
|
@ -371,6 +393,9 @@ var popupTests = [
|
|||
// shortcut key are fired asynchronously
|
||||
"DOMMenuItemActive contents", "popupshown helppopup" ],
|
||||
test: function() { synthesizeKey("VK_LEFT", { }); synthesizeKey("VK_DOWN", { }); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("helpmenu").openedWithKey, true, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
// pressing a letter that doesn't correspond to an accelerator. The menu
|
||||
|
@ -436,7 +461,10 @@ var popupTests = [
|
|||
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
|
||||
events: [ "DOMMenuItemInactive filemenu", "DOMMenuBarInactive menubar" ],
|
||||
test: function() { synthesizeKey("S", { }); },
|
||||
result: function(testname) { checkClosed("secretmenu", testname); },
|
||||
result: function(testname) {
|
||||
checkClosed("secretmenu", testname);
|
||||
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
|
||||
},
|
||||
},
|
||||
{
|
||||
testname: "press on disabled menu",
|
||||
|
@ -521,6 +549,9 @@ var popupTests = [
|
|||
testname: "Deactivate menubar with tab key",
|
||||
events: [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ],
|
||||
test: function() { synthesizeKey("VK_TAB", { }); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "F10 to activate menubar for escape deactivation",
|
||||
|
@ -531,6 +562,9 @@ var popupTests = [
|
|||
testname: "Deactivate menubar with escape key",
|
||||
events: [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ],
|
||||
test: function() { synthesizeKey("VK_ESCAPE", { }); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "F10 to activate menubar for f10 deactivation",
|
||||
|
@ -541,6 +575,9 @@ var popupTests = [
|
|||
testname: "Deactivate menubar with f10 key",
|
||||
events: [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ],
|
||||
test: function() { synthesizeKey("VK_F10", { }); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "F10 to activate menubar for alt deactivation",
|
||||
|
@ -553,6 +590,9 @@ var popupTests = [
|
|||
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
|
||||
events: [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ],
|
||||
test: function() { synthesizeKey("VK_ALT", { }); },
|
||||
result: function(testname) {
|
||||
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "Don't activate menubar with mousedown during alt key auto-repeat",
|
||||
|
@ -628,5 +668,4 @@ var popupTests = [
|
|||
]]>
|
||||
</script>
|
||||
|
||||
|
||||
</window>
|
||||
|
|
|
@ -60,6 +60,12 @@
|
|||
]]></setter>
|
||||
</property>
|
||||
|
||||
<property name="openedWithKey" readonly="true">
|
||||
<getter><![CDATA[
|
||||
return this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).openedWithKey;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<!-- nsIDOMXULContainerElement interface -->
|
||||
<method name="appendItem">
|
||||
<parameter name="aLabel"/>
|
||||
|
|
Загрузка…
Ссылка в новой задаче