зеркало из https://github.com/mozilla/gecko-dev.git
397 строки
15 KiB
XML
397 строки
15 KiB
XML
<?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(testtag_menulists, 0);"
|
|
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>
|
|
<script type="application/javascript" src="xul_selectcontrol.js"></script>
|
|
|
|
<vbox id="scroller" style="overflow: auto" height="60">
|
|
<menulist id="menulist" onpopupshown="test_menulist_open(this, this.parentNode)"
|
|
onpopuphidden="$('menulist-in-listbox').open = true;">
|
|
<menupopup id="menulist-popup"/>
|
|
</menulist>
|
|
<button label="Two"/>
|
|
<button label="Three"/>
|
|
</vbox>
|
|
<listbox id="scroller-in-listbox" style="overflow: auto" height="60">
|
|
<listitem allowevents="true">
|
|
<menulist id="menulist-in-listbox" onpopupshown="test_menulist_open(this, this.parentNode.parentNode)"
|
|
onpopuphidden="SimpleTest.executeSoon(checkScrollAndFinish)">
|
|
<menupopup id="menulist-in-listbox-popup">
|
|
<menuitem label="One" value="one"/>
|
|
<menuitem label="Two" value="two"/>
|
|
</menupopup>
|
|
</menulist>
|
|
</listitem>
|
|
<listitem label="Two"/>
|
|
<listitem label="Three"/>
|
|
<listitem label="Four"/>
|
|
<listitem label="Five"/>
|
|
<listitem label="Six"/>
|
|
</listbox>
|
|
|
|
<hbox>
|
|
<menulist id="menulist-size">
|
|
<menupopup>
|
|
<menuitem label="Menuitem Label" width="200"/>
|
|
</menupopup>
|
|
</menulist>
|
|
</hbox>
|
|
|
|
<menulist id="menulist-editable" editable="true">
|
|
<menupopup id="menulist-popup-editable"/>
|
|
</menulist>
|
|
|
|
<menulist id="menulist-initwithvalue" value="two">
|
|
<menupopup>
|
|
<menuitem label="One" value="one"/>
|
|
<menuitem label="Two" value="two"/>
|
|
<menuitem label="Three" value="three"/>
|
|
</menupopup>
|
|
</menulist>
|
|
<menulist id="menulist-initwithselected" value="two">
|
|
<menupopup>
|
|
<menuitem label="One" value="one"/>
|
|
<menuitem label="Two" value="two"/>
|
|
<menuitem label="Three" value="three" selected="true"/>
|
|
</menupopup>
|
|
</menulist>
|
|
<menulist id="menulist-editable-initwithvalue" editable="true" value="Two">
|
|
<menupopup>
|
|
<menuitem label="One" value="one"/>
|
|
<menuitem label="Two" value="two"/>
|
|
<menuitem label="Three" value="three"/>
|
|
</menupopup>
|
|
</menulist>
|
|
<menulist id="menulist-editable-initwithselected" editable="true" value="two">
|
|
<menupopup>
|
|
<menuitem label="One" value="one"/>
|
|
<menuitem label="Two" value="two"/>
|
|
<menuitem label="Three" value="three" selected="true"/>
|
|
</menupopup>
|
|
</menulist>
|
|
|
|
<menulist id="menulist-clipped">
|
|
<menupopup height="65">
|
|
<menuitem label="One" value="one"/>
|
|
<menuitem label="Two" value="two"/>
|
|
<menuitem label="Three" value="three"/>
|
|
<menuitem label="Four" value="four"/>
|
|
<menuitem label="Five" value="five" selected="true"/>
|
|
<menuitem label="Six" value="six"/>
|
|
<menuitem label="Seven" value="seven"/>
|
|
<menuitem label="Eight" value="eight"/>
|
|
</menupopup>
|
|
</menulist>
|
|
|
|
<script class="testbody" type="application/javascript">
|
|
<![CDATA[
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
|
|
function testtag_menulists()
|
|
{
|
|
testtag_menulist_UI_start($("menulist"), false);
|
|
}
|
|
|
|
function testtag_menulist_UI_start(element, editable)
|
|
{
|
|
var testprefix = editable ? "editable" : "";
|
|
|
|
// check the menupopup property
|
|
var popup = element.menupopup;
|
|
ok(popup && popup.localName == "menupopup" &&
|
|
popup.parentNode == element, testprefix + " menupopup");
|
|
|
|
// test the interfaces that menulist implements
|
|
test_nsIDOMXULMenuListElement(element, testprefix, editable);
|
|
}
|
|
|
|
function testtag_menulist_UI_finish(element, editable)
|
|
{
|
|
element.value = "";
|
|
|
|
test_nsIDOMXULSelectControlElement(element, "menuitem",
|
|
editable ? "editable" : null);
|
|
|
|
if (!editable) {
|
|
testtag_menulist_UI_start($("menulist-editable"), true);
|
|
}
|
|
else {
|
|
// bug 566154, the menulist width should account for vertical scrollbar
|
|
ok(document.getElementById("menulist-size").getBoundingClientRect().width >= 210,
|
|
"menulist popup width includes scrollbar width");
|
|
|
|
$("menulist").open = true;
|
|
}
|
|
}
|
|
|
|
function test_nsIDOMXULMenuListElement(element, testprefix, editable)
|
|
{
|
|
is(element.open, false, testprefix + " open");
|
|
is(element.editable, editable, testprefix + " editable");
|
|
|
|
if (editable) {
|
|
var inputField = element.inputField;
|
|
is(inputField &&
|
|
inputField instanceof Components.interfaces.nsIDOMHTMLInputElement,
|
|
true, testprefix + " inputField");
|
|
|
|
// check if the select method works
|
|
inputField.select();
|
|
is(inputField.selectionStart, 0, testprefix + " empty select selectionStart");
|
|
is(inputField.selectionEnd, 0, testprefix + " empty select selectionEnd");
|
|
|
|
element.value = "Some Text";
|
|
inputField.select();
|
|
is(inputField.selectionStart, 0, testprefix + " empty select selectionStart");
|
|
is(inputField.selectionEnd, 9, testprefix + " empty select selectionEnd");
|
|
}
|
|
else {
|
|
is(element.inputField, null , testprefix + " inputField");
|
|
}
|
|
|
|
element.appendItem("Item One", "one");
|
|
var seconditem = element.appendItem("Item Two", "two");
|
|
var thirditem = element.appendItem("Item Three", "three");
|
|
element.appendItem("Item Four", "four");
|
|
|
|
seconditem.image = "happy.png";
|
|
seconditem.setAttribute("description", "This is the second description");
|
|
thirditem.image = "happy.png";
|
|
thirditem.setAttribute("description", "This is the third description");
|
|
|
|
// check the image and description properties
|
|
// editable menulists don't use the image or description properties currently
|
|
if (editable) {
|
|
element.selectedIndex = 1;
|
|
is(element.image, "", testprefix + " image set to selected");
|
|
is(element.description, "", testprefix + " description set to selected");
|
|
test_nsIDOMXULMenuListElement_finish(element, testprefix, editable);
|
|
}
|
|
else {
|
|
element.selectedIndex = 1;
|
|
is(element.image, "happy.png", testprefix + " image set to selected");
|
|
is(element.description, "This is the second description", testprefix + " description set to selected");
|
|
element.selectedIndex = -1;
|
|
is(element.image, "", testprefix + " image set when none selected");
|
|
is(element.description, "", testprefix + " description set when none selected");
|
|
element.selectedIndex = 2;
|
|
is(element.image, "happy.png", testprefix + " image set to selected again");
|
|
is(element.description, "This is the third description", testprefix + " description set to selected again");
|
|
|
|
// check that changing the properties of the selected item changes the menulist's properties
|
|
let properties = [{attr: "label", value: "Item Number Three"},
|
|
{attr: "value", value: "item-three"},
|
|
{attr: "image", value: "smile.png"},
|
|
{attr: "description", value: "Changed description"}];
|
|
test_nsIDOMXULMenuListElement_properties(element, testprefix, editable, thirditem, properties);
|
|
}
|
|
}
|
|
|
|
function test_nsIDOMXULMenuListElement_properties(element, testprefix, editable, thirditem, properties)
|
|
{
|
|
let {attr, value} = properties.shift();
|
|
let last = (properties.length == 0);
|
|
|
|
let mutObserver = new MutationObserver(() => {
|
|
is(element.getAttribute(attr), value, `${testprefix} ${attr} modified`);
|
|
done();
|
|
});
|
|
mutObserver.observe(element, { attributeFilter: [attr] });
|
|
|
|
let failureTimeout = setTimeout(() => {
|
|
ok(false, `${testprefix} ${attr} should have updated`);
|
|
done();
|
|
}, 2000);
|
|
|
|
function done()
|
|
{
|
|
clearTimeout(failureTimeout);
|
|
mutObserver.disconnect();
|
|
if (!last) {
|
|
test_nsIDOMXULMenuListElement_properties(element, testprefix, editable, thirditem, properties);
|
|
}
|
|
else {
|
|
test_nsIDOMXULMenuListElement_unselected(element, testprefix, editable, thirditem);
|
|
}
|
|
}
|
|
|
|
thirditem.setAttribute(attr, value)
|
|
}
|
|
|
|
function test_nsIDOMXULMenuListElement_unselected(element, testprefix, editable, thirditem)
|
|
{
|
|
let seconditem = thirditem.previousElementSibling;
|
|
seconditem.label = "Changed Label 2";
|
|
is(element.label, "Item Number Three", testprefix + " label of another item modified");
|
|
|
|
element.selectedIndex = 0;
|
|
is(element.image, "", testprefix + " image set to selected with no image");
|
|
is(element.description, "", testprefix + " description set to selected with no description");
|
|
test_nsIDOMXULMenuListElement_finish(element, testprefix, editable);
|
|
}
|
|
|
|
function test_nsIDOMXULMenuListElement_finish(element, testprefix, editable)
|
|
{
|
|
// check the removeAllItems method
|
|
element.appendItem("An Item", "anitem");
|
|
element.appendItem("Another Item", "anotheritem");
|
|
element.removeAllItems();
|
|
is(element.itemCount, 0, testprefix + " removeAllItems");
|
|
|
|
testtag_menulist_UI_finish(element, editable);
|
|
}
|
|
|
|
function test_menulist_open(element, scroller)
|
|
{
|
|
element.appendItem("Scroll Item 1", "scrollitem1");
|
|
element.appendItem("Scroll Item 2", "scrollitem2");
|
|
element.focus();
|
|
element.selectedIndex = 0;
|
|
|
|
/*
|
|
// bug 530504, mousewheel while menulist is open should not scroll menulist
|
|
// items or parent
|
|
var scrolled = false;
|
|
var mouseScrolled = function (event) { scrolled = true; }
|
|
window.addEventListener("DOMMouseScroll", mouseScrolled, false);
|
|
synthesizeWheel(element, 2, 2, { deltaY: 10,
|
|
deltaMode: WheelEvent.DOM_DELTA_LINE });
|
|
is(scrolled, true, "mousescroll " + element.id);
|
|
is(scroller.scrollTop, 0, "scroll position on mousescroll " + element.id);
|
|
window.removeEventListener("DOMMouseScroll", mouseScrolled, false);
|
|
*/
|
|
|
|
// bug 543065, hovering the mouse over an item should highlight it, not
|
|
// scroll the parent, and not change the selected index.
|
|
var item = element.menupopup.childNodes[1];
|
|
|
|
synthesizeMouse(element.menupopup.childNodes[1], 2, 2, { type: "mousemove" });
|
|
synthesizeMouse(element.menupopup.childNodes[1], 6, 6, { type: "mousemove" });
|
|
is(element.menuBoxObject.activeChild, item, "activeChild after menu highlight " + element.id);
|
|
is(element.selectedIndex, 0, "selectedIndex after menu highlight " + element.id);
|
|
is(scroller.scrollTop, 0, "scroll position after menu highlight " + element.id);
|
|
|
|
element.open = false;
|
|
}
|
|
|
|
function checkScrollAndFinish()
|
|
{
|
|
is($("scroller").scrollTop, 0, "mousewheel on menulist does not scroll vbox parent");
|
|
is($("scroller-in-listbox").scrollTop, 0, "mousewheel on menulist does not scroll listbox parent");
|
|
|
|
// bug 561243, outline causes the mouse click to be targeted incorrectly
|
|
var editableMenulist = $("menulist-editable");
|
|
editableMenulist.className = "outlined";
|
|
|
|
synthesizeMouse(editableMenulist.inputField, 25, 8, { type: "mousedown" });
|
|
synthesizeMouse(editableMenulist.inputField, 25, 8, { type: "mouseup" });
|
|
isnot(editableMenulist.inputField.selectionStart, editableMenulist.inputField.textLength,
|
|
"mouse event on editable menulist with outline caret position");
|
|
|
|
let menulist = $("menulist-size");
|
|
menulist.addEventListener("popupshown", function testAltClose() {
|
|
menulist.removeEventListener("popupshown", testAltClose);
|
|
|
|
sendKey("ALT");
|
|
is(menulist.menupopup.state, "open", "alt doesn't close menulist");
|
|
menulist.open = false;
|
|
|
|
dragScroll();
|
|
});
|
|
|
|
menulist.open = true;
|
|
}
|
|
|
|
function dragScroll()
|
|
{
|
|
let menulist = $("menulist-clipped");
|
|
menulist.addEventListener("popupshown", function testDragScroll() {
|
|
menulist.removeEventListener("popupshown", testDragScroll);
|
|
|
|
let popup = menulist.menupopup;
|
|
let scrollPos = popup.scrollBox.scrollTop;
|
|
let popupRect = popup.getBoundingClientRect();
|
|
|
|
// First, check that scrolling does not occur when the mouse is moved over the
|
|
// anchor button but not the popup yet.
|
|
synthesizeMouseAtPoint(popupRect.left + 5, popupRect.top - 10, { type: "mousemove" });
|
|
is(popup.scrollBox.scrollTop, scrollPos, "scroll position after mousemove over button should not change");
|
|
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.top + 10, { type: "mousemove" });
|
|
|
|
// Dragging above the popup scrolls it up.
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.top - 20, { type: "mousemove" });
|
|
ok(popup.scrollBox.scrollTop < scrollPos - 5, "scroll position at drag up");
|
|
|
|
// Dragging below the popup scrolls it down.
|
|
scrollPos = popup.scrollBox.scrollTop;
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 20, { type: "mousemove" });
|
|
ok(popup.scrollBox.scrollTop > scrollPos + 5, "scroll position at drag down");
|
|
|
|
// Releasing the mouse button and moving the mouse does not change the scroll position.
|
|
scrollPos = popup.scrollBox.scrollTop;
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 25, { type: "mouseup" });
|
|
is(popup.scrollBox.scrollTop, scrollPos, "scroll position at mouseup should not change");
|
|
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 20, { type: "mousemove" });
|
|
is(popup.scrollBox.scrollTop, scrollPos, "scroll position at mousemove after mouseup should not change");
|
|
|
|
// Now check dragging with a mousedown on an item
|
|
let menuRect = popup.childNodes[4].getBoundingClientRect();
|
|
synthesizeMouseAtPoint(menuRect.left + 5, menuRect.top + 5, { type: "mousedown" });
|
|
|
|
// Dragging below the popup scrolls it down.
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 20, { type: "mousemove" });
|
|
ok(popup.scrollBox.scrollTop > scrollPos + 5, "scroll position at drag down from item");
|
|
|
|
// Dragging above the popup scrolls it up.
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.top - 20, { type: "mousemove" });
|
|
is(popup.scrollBox.scrollTop, scrollPos, "scroll position at drag up from item");
|
|
|
|
scrollPos = popup.scrollBox.scrollTop;
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 25, { type: "mouseup" });
|
|
is(popup.scrollBox.scrollTop, scrollPos, "scroll position at mouseup should not change");
|
|
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 20, { type: "mousemove" });
|
|
is(popup.scrollBox.scrollTop, scrollPos, "scroll position at mousemove after mouseup should not change");
|
|
|
|
menulist.open = false;
|
|
|
|
let mouseMoveTarget = null;
|
|
popup.childNodes[4].click();
|
|
addEventListener("mousemove", function checkMouseMove(event) {
|
|
mouseMoveTarget = event.target;
|
|
}, {once: true});
|
|
synthesizeMouseAtPoint(popupRect.left + 20, popupRect.bottom + 20, { type: "mousemove" });
|
|
isnot(mouseMoveTarget, popup, "clicking on item when popup closed doesn't start dragging");
|
|
|
|
SimpleTest.finish();
|
|
});
|
|
|
|
menulist.open = true;
|
|
}
|
|
|
|
]]>
|
|
</script>
|
|
|
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
<style>
|
|
.outlined > .menulist-editable-box { outline: 1px solid black; }
|
|
</style>
|
|
<p id="display">
|
|
</p>
|
|
<div id="content" style="display: none">
|
|
</div>
|
|
<pre id="test">
|
|
</pre>
|
|
</body>
|
|
|
|
</window>
|