mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 250091, support page up and page down in menulists, r=neil
This commit is contained in:
parent
9399983176
commit
0bf9e896e5
@ -1635,6 +1635,87 @@ void nsMenuPopupFrame::EnsureMenuItemIsVisible(nsMenuFrame* aMenuItem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsMenuPopupFrame::ChangeByPage(bool aIsUp)
|
||||||
|
{
|
||||||
|
nsIFrame* parentMenu = GetParent();
|
||||||
|
if (parentMenu) {
|
||||||
|
// Only scroll by page within menulists.
|
||||||
|
nsCOMPtr<nsIDOMXULMenuListElement> menulist = do_QueryInterface(parentMenu->GetContent());
|
||||||
|
if (!menulist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMenuFrame* newMenu = nullptr;
|
||||||
|
nsIFrame* currentMenu = mCurrentMenu;
|
||||||
|
if (!currentMenu) {
|
||||||
|
// If there is no current menu item, get the first item. When moving up,
|
||||||
|
// just use this as the newMenu and leave currentMenu null so that no
|
||||||
|
// check for a later element is performed. When moving down, set currentMenu
|
||||||
|
// so that we look for one page down from the first item.
|
||||||
|
newMenu = nsXULPopupManager::GetNextMenuItem(this, nullptr, true);
|
||||||
|
if (!aIsUp) {
|
||||||
|
currentMenu = newMenu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentMenu) {
|
||||||
|
nscoord scrollHeight = mRect.height;
|
||||||
|
nsIScrollableFrame *scrollframe = GetScrollFrame(this);
|
||||||
|
if (scrollframe) {
|
||||||
|
scrollHeight = scrollframe->GetScrollPortRect().height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the position of the current item and add or subtract one popup's
|
||||||
|
// height to or from it.
|
||||||
|
nscoord targetPosition = aIsUp ? currentMenu->GetRect().YMost() - scrollHeight :
|
||||||
|
currentMenu->GetRect().y + scrollHeight;
|
||||||
|
|
||||||
|
// Indicates that the last visible child was a valid menuitem.
|
||||||
|
bool lastWasValid = false;
|
||||||
|
|
||||||
|
// Look for the next child which is just past the target position. This child
|
||||||
|
// will need to be selected.
|
||||||
|
while (currentMenu) {
|
||||||
|
// Only consider menu frames.
|
||||||
|
nsMenuFrame* menuFrame = do_QueryFrame(currentMenu);
|
||||||
|
if (menuFrame &&
|
||||||
|
nsXULPopupManager::IsValidMenuItem(PresContext(), menuFrame->GetContent(), true)) {
|
||||||
|
|
||||||
|
// If the right position was found, break out. Otherwise, look for another item.
|
||||||
|
if ((!aIsUp && currentMenu->GetRect().YMost() > targetPosition) ||
|
||||||
|
(aIsUp && currentMenu->GetRect().y < targetPosition)) {
|
||||||
|
|
||||||
|
// If the last visible child was not a valid menuitem or was disabled,
|
||||||
|
// use this as the menu to select, skipping over any non-valid items at
|
||||||
|
// the edge of the page.
|
||||||
|
if (!lastWasValid) {
|
||||||
|
newMenu = menuFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign this item to newMenu. This item will be selected in case we
|
||||||
|
// don't find any more.
|
||||||
|
lastWasValid = true;
|
||||||
|
newMenu = menuFrame;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastWasValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMenu = aIsUp ? currentMenu->GetPrevSibling() :
|
||||||
|
currentMenu->GetNextSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the new menuitem.
|
||||||
|
if (newMenu) {
|
||||||
|
ChangeMenuItem(newMenu, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsMenuFrame* aMenuItem)
|
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsMenuFrame* aMenuItem)
|
||||||
{
|
{
|
||||||
if (mCurrentMenu == aMenuItem)
|
if (mCurrentMenu == aMenuItem)
|
||||||
|
@ -326,6 +326,8 @@ public:
|
|||||||
|
|
||||||
void EnsureMenuItemIsVisible(nsMenuFrame* aMenuFrame);
|
void EnsureMenuItemIsVisible(nsMenuFrame* aMenuFrame);
|
||||||
|
|
||||||
|
void ChangeByPage(bool aIsUp);
|
||||||
|
|
||||||
// Move the popup to the screen coordinate (aLeft, aTop) in CSS pixels.
|
// Move the popup to the screen coordinate (aLeft, aTop) in CSS pixels.
|
||||||
// If aUpdateAttrs is true, and the popup already has left or top attributes,
|
// If aUpdateAttrs is true, and the popup already has left or top attributes,
|
||||||
// then those attributes are updated to the new location.
|
// then those attributes are updated to the new location.
|
||||||
|
@ -2172,6 +2172,13 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
|||||||
HandleKeyboardNavigation(keyCode);
|
HandleKeyboardNavigation(keyCode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nsIDOMKeyEvent::DOM_VK_PAGE_DOWN:
|
||||||
|
case nsIDOMKeyEvent::DOM_VK_PAGE_UP:
|
||||||
|
if (aTopVisibleMenuItem) {
|
||||||
|
aTopVisibleMenuItem->Frame()->ChangeByPage(keyCode == nsIDOMKeyEvent::DOM_VK_PAGE_UP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nsIDOMKeyEvent::DOM_VK_ESCAPE:
|
case nsIDOMKeyEvent::DOM_VK_ESCAPE:
|
||||||
// Pressing Escape hides one level of menus only. If no menu is open,
|
// Pressing Escape hides one level of menus only. If no menu is open,
|
||||||
// check if a menubar is active and inform it that a menu closed. Even
|
// check if a menubar is active and inform it that a menu closed. Even
|
||||||
|
@ -116,6 +116,7 @@ skip-if = buildapp == 'mulet'
|
|||||||
skip-if = buildapp == 'mulet'
|
skip-if = buildapp == 'mulet'
|
||||||
[test_menulist_keynav.xul]
|
[test_menulist_keynav.xul]
|
||||||
[test_menulist_null_value.xul]
|
[test_menulist_null_value.xul]
|
||||||
|
[test_menulist_paging.xul]
|
||||||
[test_mousecapture.xul]
|
[test_mousecapture.xul]
|
||||||
skip-if = buildapp == 'mulet'
|
skip-if = buildapp == 'mulet'
|
||||||
[test_mousescroll.xul]
|
[test_mousescroll.xul]
|
||||||
|
133
toolkit/content/tests/chrome/test_menulist_paging.xul
Normal file
133
toolkit/content/tests/chrome/test_menulist_paging.xul
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||||
|
|
||||||
|
<window title="Menulist Tests"
|
||||||
|
onload="setTimeout(startTest, 0);"
|
||||||
|
onpopupshown="menulistShown()" onpopuphidden="runTest()"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
|
||||||
|
<menulist id="menulist1">
|
||||||
|
<menupopup id="menulist-popup1">
|
||||||
|
<menuitem label="One"/>
|
||||||
|
<menuitem label="Two"/>
|
||||||
|
<menuitem label="Three"/>
|
||||||
|
<menuitem label="Four"/>
|
||||||
|
<menuitem label="Five"/>
|
||||||
|
<menuitem label="Six"/>
|
||||||
|
<menuitem label="Seven"/>
|
||||||
|
<menuitem label="Eight"/>
|
||||||
|
<menuitem label="Nine"/>
|
||||||
|
<menuitem label="Ten"/>
|
||||||
|
</menupopup>
|
||||||
|
</menulist>
|
||||||
|
|
||||||
|
<menulist id="menulist2">
|
||||||
|
<menupopup id="menulist-popup2">
|
||||||
|
<menuitem label="One" disabled="true"/>
|
||||||
|
<menuitem label="Two" selected="true"/>
|
||||||
|
<menuitem label="Three"/>
|
||||||
|
<menuitem label="Four"/>
|
||||||
|
<menuitem label="Five"/>
|
||||||
|
<menuitem label="Six"/>
|
||||||
|
<menuitem label="Seven"/>
|
||||||
|
<menuitem label="Eight"/>
|
||||||
|
<menuitem label="Nine"/>
|
||||||
|
<menuitem label="Ten" disabled="true"/>
|
||||||
|
</menupopup>
|
||||||
|
</menulist>
|
||||||
|
|
||||||
|
<menulist id="menulist3">
|
||||||
|
<menupopup id="menulist-popup3">
|
||||||
|
<label value="One"/>
|
||||||
|
<menuitem label="Two" selected="true"/>
|
||||||
|
<menuitem label="Three"/>
|
||||||
|
<menuitem label="Four"/>
|
||||||
|
<menuitem label="Five" disabled="true"/>
|
||||||
|
<menuitem label="Six" disabled="true"/>
|
||||||
|
<menuitem label="Seven"/>
|
||||||
|
<menuitem label="Eight"/>
|
||||||
|
<menuitem label="Nine"/>
|
||||||
|
<label value="Ten"/>
|
||||||
|
</menupopup>
|
||||||
|
</menulist>
|
||||||
|
|
||||||
|
<script class="testbody" type="application/javascript">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
let test;
|
||||||
|
|
||||||
|
// Windows allows disabled items to be selected.
|
||||||
|
let isWindows = navigator.platform.indexOf("Win") >= 0;
|
||||||
|
|
||||||
|
let tests = [
|
||||||
|
{ list: "menulist1", initial: 0, downs: [3, 6, 9, 9],
|
||||||
|
ups: [6, 3, 0, 0] },
|
||||||
|
{ list: "menulist2", initial: 1, downs: [4, 7, isWindows ? 9 : 8, isWindows ? 9 : 8],
|
||||||
|
ups: [isWindows ? 6 : 5, isWindows ? 3 : 2, isWindows ? 0 : 1] },
|
||||||
|
{ list: "menulist3", initial: 1, downs: [isWindows ? 4 : 6, isWindows ? 7 : 8, 8],
|
||||||
|
ups: [isWindows ? 5 : 3, isWindows ? 2 : 1, 1] }
|
||||||
|
];
|
||||||
|
|
||||||
|
function startTest()
|
||||||
|
{
|
||||||
|
let popup = document.getElementById("menulist-popup1");
|
||||||
|
let menupopupHeight = popup.getBoundingClientRect().height;
|
||||||
|
let menuitemHeight = popup.firstChild.getBoundingClientRect().height;
|
||||||
|
|
||||||
|
// First, set the height of each popup to the height of four menuitems plus
|
||||||
|
// any padding and border on the menupopup.
|
||||||
|
let height = menuitemHeight * 4 + (menupopupHeight - menuitemHeight * 10);
|
||||||
|
popup.height = height;
|
||||||
|
document.getElementById("menulist-popup2").height = height;
|
||||||
|
document.getElementById("menulist-popup3").height = height;
|
||||||
|
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest()
|
||||||
|
{
|
||||||
|
if (!tests.length) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
test = tests.shift();
|
||||||
|
document.getElementById(test.list).open = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function menulistShown()
|
||||||
|
{
|
||||||
|
let menulist = document.getElementById(test.list);
|
||||||
|
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.initial).label, test.list + " initial selection");
|
||||||
|
|
||||||
|
for (let i = 0; i < test.downs.length; i++) {
|
||||||
|
sendKey("PAGE_DOWN");
|
||||||
|
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.downs[i]).label, test.list + " page down " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < test.ups.length; i++) {
|
||||||
|
sendKey("PAGE_UP");
|
||||||
|
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.ups[i]).label, test.list + " page up " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
menulist.open = false;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p id="display">
|
||||||
|
</p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</window>
|
Loading…
Reference in New Issue
Block a user