gecko/toolkit/content/tests/chrome/window_largemenu.xul

300 lines
10 KiB
XML

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Large Menu Tests"
onfocus="setTimeout(runTests, 0);"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<!--
This test checks that a large menu is displayed with arrow buttons
and is on the screen.
-->
<script>
<![CDATA[
var gOverflowed = false, gUnderflowed = false;
var gContextMenuTests = false;
var gScreenY = -1;
var gTestIndex = 0;
var gTests = ["open normal", "open flipped position", "open with scrolling",
"open after scrolling", "open small again",
"menu movement", "panel movement",
"context menu enough space below",
"context menu more space above",
"context menu too big either side",
"context menu larger than screen"];
function setDocumentScreenY()
{
var mouseFn = function(event) { gScreenY = event.screenY; }
// 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);
}
function runTests()
{
setDocumentScreenY();
nextTest();
}
function nextTest()
{
gOverflowed = false, gUnderflowed = false;
var y = screen.height;
if (gTestIndex == 1) // open flipped position test:
y -= 100;
else
y /= 2;
var popup = document.getElementById("popup");
if (gTestIndex == 2) {
// add some more menuitems so that scrolling will be necessary
for (var t = 1; t <= 30; t++) {
var menu = document.createElement("menuitem");
menu.setAttribute("label", "More" + t);
popup.appendChild(menu);
}
}
else if (gTestIndex == 4) {
for (var t = 1; t <= 30; t++)
popup.removeChild(popup.lastChild);
}
popup.openPopupAtScreen(100, y, false);
}
function popupShown()
{
if (gTests[gTestIndex] == "menu movement")
return testPopupMovement();
if (gContextMenuTests)
return contextMenuPopupShown();
var popup = document.getElementById("popup");
var rect = popup.getBoundingClientRect();
var sbo = document.getAnonymousNodes(popup)[0].scrollBoxObject;
var expectedScrollPos = 0;
if (gTestIndex == 0) {
// the popup should be in the center of the screen
is(Math.round(rect.top) + gScreenY, screen.height / 2,
gTests[gTestIndex] + " top");
ok(Math.round(rect.bottom) + gScreenY < screen.height,
gTests[gTestIndex] + " bottom");
ok(!gOverflowed && !gUnderflowed, gTests[gTestIndex] + " overflow")
}
else if (gTestIndex == 1) {
// the popup was supposed to open 100 pixels from the bottom, but that
// would put it off screen so it should be flipped to have its bottom
// edge 100 pixels from the bottom
ok(Math.round(rect.top) + gScreenY >= screen.top, gTests[gTestIndex] + " top");
is(Math.round(rect.bottom) + gScreenY, screen.height - 100,
gTests[gTestIndex] + " bottom");
ok(!gOverflowed && !gUnderflowed, gTests[gTestIndex] + " overflow")
}
else if (gTestIndex == 2) {
// the popup is too large so ensure that it is on screen
ok(Math.round(rect.top) + gScreenY >= screen.top, gTests[gTestIndex] + " top");
ok(Math.round(rect.bottom) + gScreenY < screen.height, gTests[gTestIndex] + " bottom");
ok(gOverflowed && !gUnderflowed, gTests[gTestIndex] + " overflow")
sbo.scrollTo(0, 40);
expectedScrollPos = 40;
}
else if (gTestIndex == 3) {
expectedScrollPos = 40;
}
else if (gTestIndex == 4) {
is(Math.round(rect.top) + gScreenY, screen.height / 2,
gTests[gTestIndex] + " top");
ok(Math.round(rect.bottom) + gScreenY < screen.height,
gTests[gTestIndex] + " bottom");
ok(!gOverflowed && gUnderflowed, gTests[gTestIndex] + " overflow")
}
var sx = { }, sy = { };
sbo.getPosition(sx, sy);
is(sy.value, expectedScrollPos, "menu scroll position");
popup.hidePopup();
}
function is(l, r, n) { window.opener.wrappedJSObject.SimpleTest.is(l,r,n); }
function ok(v, n) { window.opener.wrappedJSObject.SimpleTest.ok(v,n); }
function popupHidden()
{
gTestIndex++;
if (gTestIndex == gTests.length) {
window.opener.wrappedJSObject.SimpleTest.finish();
window.close();
}
else if (gTests[gTestIndex] == "context menu enough space below") {
gContextMenuTests = true;
window.moveTo(window.screenX, screen.availTop + 10);
synthesizeMouse(document.getElementById("label"), 4, 4, { type: "contextmenu", button: 2 });
}
else if (gTests[gTestIndex] == "menu movement") {
document.getElementById("popup").openPopup(
document.getElementById("label"), "after_start", 0, 0, false, false);
}
else if (gTests[gTestIndex] == "panel movement") {
document.getElementById("panel").openPopup(
document.getElementById("label"), "after_start", 0, 0, false, false);
}
else if (gContextMenuTests) {
contextMenuPopupHidden();
}
else {
nextTest();
}
}
function contextMenuPopupShown()
{
var popup = document.getElementById("popup");
var rect = popup.getBoundingClientRect();
var labelrect = document.getElementById("label").getBoundingClientRect();
// XXXndeakin disable test on Linux for now
is(rect.left, labelrect.left + 6, gTests[gTestIndex] + " left");
switch (gTests[gTestIndex]) {
case "context menu enough space below":
is(rect.top, labelrect.top + 6, gTests[gTestIndex] + " top");
break;
case "context menu more space above":
is(rect.top, labelrect.top - rect.height + 2, gTests[gTestIndex] + " top");
break;
case "context menu too big either side":
setDocumentScreenY();
// compare against the available size as well as the total size, as some
// platforms allow the menu to overlap os chrome and others do not
// the - 3 here is to account for 3 pixels that are subtracted from the
// screen size when sizing a popup for the popup shadow
var pos = (screen.availTop + screen.availHeight - 3 - rect.height) - gScreenY;
var availPos = (screen.top + screen.height - 3 - rect.height) - gScreenY;
ok(rect.top == pos || rect.top == availPos,
gTests[gTestIndex] + " top");
break;
case "context menu larger than screen":
ok(rect.top == -(gScreenY - screen.availTop) || rect.top == -(gScreenY - screen.top), gTests[gTestIndex] + " top");
break;
}
popup.hidePopup();
}
function contextMenuPopupHidden()
{
var screenAvailBottom = screen.availTop + screen.availHeight;
var desiredHeight = -1;
if (gTests[gTestIndex] == "context menu more space above") {
window.moveTo(window.screenX, screenAvailBottom - 80);
}
if (gTests[gTestIndex] == "context menu too big either side") {
window.moveTo(window.screenX, screenAvailBottom / 2 - 80);
desiredHeight = screenAvailBottom / 2 + 120;
}
else if (gTests[gTestIndex] == "context menu larger than screen") {
desiredHeight = screen.availHeight + 80;
}
if (desiredHeight >= 0) {
var popup = document.getElementById("popup");
var height = popup.getBoundingClientRect().height;
var itemheight = document.getElementById("firstitem").getBoundingClientRect().height;
while (height < desiredHeight) {
var menu = document.createElement("menuitem");
menu.setAttribute("label", "Item");
popup.appendChild(menu);
height += itemheight;
}
}
synthesizeMouse(document.getElementById("label"), 4, 4, { type: "contextmenu", button: 2 });
}
function testPopupMovement()
{
var button = document.getElementById("label");
var popup = document.getElementById((gTests[gTestIndex] == "panel movement") ? "panel" : "popup");
var rect = popup.getBoundingClientRect();
var overlapOSChrome = (navigator.platform.indexOf("Mac") == -1);
popup.moveTo(1, 1);
// is(popup.boxObject.screenX, overlapOSChrome ? 1 : screen.availLeft, gTests[gTestIndex] + " (1, 1) x");
// is(popup.boxObject.screenY, overlapOSChrome ? 1 : screen.availTop, gTests[gTestIndex] + " (1, 1) y");
popup.moveTo(100, 8000);
var expectedy = (overlapOSChrome ? screen.height + screen.top : screen.availHeight + screen.availTop) -
Math.round(rect.height) - 3;
is(popup.boxObject.screenX, 100, gTests[gTestIndex] + " (100, 8000) x");
is(popup.boxObject.screenY, expectedy, gTests[gTestIndex] + " (100, 8000) y");
popup.moveTo(6000, 100);
var expectedx = (overlapOSChrome ? screen.width + screen.left : screen.availWidth + screen.availLeft) -
Math.round(rect.width) - 3;
// is(popup.boxObject.screenX, expectedx, gTests[gTestIndex] + " (6000, 100) x");
is(popup.boxObject.screenY, 100, gTests[gTestIndex] + " (6000, 100) y");
is(popup.left, "", gTests[gTestIndex] + " left is empty after moving");
is(popup.top, "", gTests[gTestIndex] + " top is empty after moving");
popup.setAttribute("left", "80");
popup.setAttribute("top", "82");
is(popup.boxObject.screenX, 80, gTests[gTestIndex] + " set left and top x");
is(popup.boxObject.screenY, 82, gTests[gTestIndex] + " set left and top y");
popup.moveTo(95, 98);
is(popup.boxObject.screenX, 95, gTests[gTestIndex] + " move after set left and top x");
is(popup.boxObject.screenY, 98, gTests[gTestIndex] + " move after set left and top y");
is(popup.left, "95", gTests[gTestIndex] + " left is set after moving");
is(popup.top, "98", gTests[gTestIndex] + " top is set after moving");
popup.removeAttribute("left");
popup.removeAttribute("top");
popup.moveTo(-1, -1);
is(popup.boxObject.screenX, button.boxObject.screenX, gTests[gTestIndex] + " original x");
is(popup.boxObject.screenY, button.boxObject.screenY + button.getBoundingClientRect().height, gTests[gTestIndex] + " original y");
popup.hidePopup();
}
]]>
</script>
<button id="label" label="OK" context="popup"/>
<menupopup id="popup" onpopupshown="popupShown();" onpopuphidden="popupHidden();"
onoverflow="gOverflowed = true" onunderflow="gUnderflowed = true;">
<menuitem id="firstitem" label="1"/>
<menuitem label="2"/>
<menuitem label="3"/>
<menuitem label="4"/>
<menuitem label="5"/>
<menuitem label="6"/>
<menuitem label="7"/>
<menuitem label="8"/>
<menuitem label="9"/>
<menuitem label="10"/>
<menuitem label="11"/>
<menuitem label="12"/>
<menuitem label="13"/>
<menuitem label="14"/>
<menuitem label="15"/>
</menupopup>
<panel id="panel" onpopupshown="testPopupMovement();" onpopuphidden="popupHidden();">
<button label="OK"/>
</panel>
</window>