import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,8 @@
"use strict";
module.exports = {
"extends": [
"../../../../testing/mochitest/mochitest.eslintrc.js",
"../../../../testing/mochitest/chrome.eslintrc.js"
]
};

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,20 @@
[DEFAULT]
skip-if = os == 'android'
support-files =
tree_shared.js
popup_shared.js
window_menubar.xul
seek_with_sound.ogg
[test_contextmenu_nested.xul]
skip-if = os == 'linux' # Bug 1116215
[test_contextmenu_menugroup.xul]
skip-if = os == 'linux' # Bug 1115088
[test_editor_currentURI.xul]
[test_menubar.xul]
skip-if = os == 'mac'
[test_popupanchor.xul]
skip-if = os == 'android'
[test_popupreflows.xul]
[test_tree_column_reorder.xul]
[test_videocontrols_onclickplay.html]

View file

@ -0,0 +1,23 @@
"use strict";
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
ok(false, errorMsg);
moveOn();
}
var conditionPassed;
try {
conditionPassed = condition();
} catch (e) {
ok(false, e + "\n" + e.stack);
conditionPassed = false;
}
if (conditionPassed) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); nextTest(); };
}

View file

@ -0,0 +1,40 @@
[DEFAULT]
support-files =
audio.wav
audio.ogg
seek_with_sound.ogg
head.js
tree_shared.js
videocontrols_direction-1-ref.html
videocontrols_direction-1a.html
videocontrols_direction-1b.html
videocontrols_direction-1c.html
videocontrols_direction-1d.html
videocontrols_direction-1e.html
videocontrols_direction-2-ref.html
videocontrols_direction-2a.html
videocontrols_direction-2b.html
videocontrols_direction-2c.html
videocontrols_direction-2d.html
videocontrols_direction-2e.html
videocontrols_direction_test.js
videomask.css
[test_audiocontrols_dimensions.html]
skip-if = toolkit == 'android'
[test_mousecapture_area.html]
[test_videocontrols.html]
tags = fullscreen
skip-if = toolkit == 'android' #TIMED_OUT
[test_videocontrols_vtt.html]
skip-if = toolkit == 'android'
[test_videocontrols_iframe_fullscreen.html]
[test_videocontrols_audio.html]
[test_videocontrols_audio_direction.html]
[test_videocontrols_jsdisabled.html]
skip-if = toolkit == 'android' # bug 1272646
[test_videocontrols_standalone.html]
skip-if = true # bug 1075573, bug 1262130
[test_videocontrols_video_direction.html]
skip-if = os == 'win'
[test_bug898940.html]

View file

@ -0,0 +1,424 @@
/*
* This script is used for menu and popup tests. Call startPopupTests to start
* the tests, passing an array of tests as an argument. Each test is an object
* with the following properties:
* testname - name of the test
* test - function to call to perform the test
* events - a list of events that are expected to be fired in sequence
* as a result of calling the 'test' function. This list should be
* an array of strings of the form "eventtype targetid" where
* 'eventtype' is the event type and 'targetid' is the id of
* target of the event. This function will be passed two
* arguments, the testname and the step argument.
* Alternatively, events may be a function which returns the array
* of events. This can be used when the events vary per platform.
* result - function to call after all the events have fired to check
* for additional results. May be null. This function will be
* passed two arguments, the testname and the step argument.
* steps - optional array of values. The test will be repeated for
* each step, passing each successive value within the array to
* the test and result functions
* autohide - if set, should be set to the id of a popup to hide after
* the test is complete. This is a convenience for some tests.
* condition - an optional function which, if it returns false, causes the
* test to be skipped.
* end - used for debugging. Set to true to stop the tests after running
* this one.
*/
const menuactiveAttribute = "_moz-menuactive";
var gPopupTests = null;
var gTestIndex = -1;
var gTestStepIndex = 0;
var gTestEventIndex = 0;
var gAutoHide = false;
var gExpectedEventDetails = null;
var gExpectedTriggerNode = null;
var gWindowUtils;
var gPopupWidth = -1, gPopupHeight = -1;
function startPopupTests(tests)
{
document.addEventListener("popupshowing", eventOccurred, false);
document.addEventListener("popupshown", eventOccurred, false);
document.addEventListener("popuphiding", eventOccurred, false);
document.addEventListener("popuphidden", eventOccurred, false);
document.addEventListener("command", eventOccurred, false);
document.addEventListener("DOMMenuItemActive", eventOccurred, false);
document.addEventListener("DOMMenuItemInactive", eventOccurred, false);
document.addEventListener("DOMMenuInactive", eventOccurred, false);
document.addEventListener("DOMMenuBarActive", eventOccurred, false);
document.addEventListener("DOMMenuBarInactive", eventOccurred, false);
gPopupTests = tests;
gWindowUtils = SpecialPowers.getDOMWindowUtils(window);
goNext();
}
function finish()
{
if (window.opener) {
window.close();
window.opener.SimpleTest.finish();
return;
}
SimpleTest.finish();
return;
}
function ok(condition, message) {
if (window.opener)
window.opener.SimpleTest.ok(condition, message);
else
SimpleTest.ok(condition, message);
}
function is(left, right, message) {
if (window.opener)
window.opener.SimpleTest.is(left, right, message);
else
SimpleTest.is(left, right, message);
}
function disableNonTestMouse(aDisable) {
gWindowUtils.disableNonTestMouseEvents(aDisable);
}
function eventOccurred(event)
{
if (gPopupTests.length <= gTestIndex) {
ok(false, "Extra " + event.type + " event fired");
return;
}
var test = gPopupTests[gTestIndex];
if ("autohide" in test && gAutoHide) {
if (event.type == "DOMMenuInactive") {
gAutoHide = false;
setTimeout(goNextStep, 0);
}
return;
}
var events = test.events;
if (typeof events == "function")
events = events();
if (events) {
if (events.length <= gTestEventIndex) {
ok(false, "Extra " + event.type + " event fired for " + event.target.id +
" " +gPopupTests[gTestIndex].testname);
return;
}
var eventitem = events[gTestEventIndex].split(" ");
var matches;
if (eventitem[1] == "#tooltip") {
is(event.originalTarget.localName, "tooltip",
test.testname + " event.originalTarget.localName is 'tooltip'");
is(event.originalTarget.getAttribute("default"), "true",
test.testname + " event.originalTarget default attribute is 'true'");
matches = event.originalTarget.localName == "tooltip" &&
event.originalTarget.getAttribute("default") == "true";
} else {
is(event.type, eventitem[0],
test.testname + " event type " + event.type + " fired");
is(event.target.id, eventitem[1],
test.testname + " event target ID " + event.target.id);
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;
case "popupshown": expectedState = "open"; break;
case "popuphiding": expectedState = "hiding"; break;
case "popuphidden": expectedState = "closed"; break;
}
if (gExpectedTriggerNode && event.type == "popupshowing") {
if (gExpectedTriggerNode == "notset") // check against null instead
gExpectedTriggerNode = null;
is(event.originalTarget.triggerNode, gExpectedTriggerNode, test.testname + " popupshowing triggerNode");
var isTooltip = (event.target.localName == "tooltip");
is(document.popupNode, isTooltip ? null : gExpectedTriggerNode,
test.testname + " popupshowing document.popupNode");
is(document.tooltipNode, isTooltip ? gExpectedTriggerNode : null,
test.testname + " popupshowing document.tooltipNode");
}
if (expectedState)
is(event.originalTarget.state, expectedState,
test.testname + " " + event.type + " state");
if (matches) {
gTestEventIndex++
if (events.length <= gTestEventIndex)
setTimeout(checkResult, 0);
}
}
}
function checkResult()
{
var step = null;
var test = gPopupTests[gTestIndex];
if ("steps" in test)
step = test.steps[gTestStepIndex];
if ("result" in test)
test.result(test.testname, step);
if ("autohide" in test) {
gAutoHide = true;
document.getElementById(test.autohide).hidePopup();
return;
}
goNextStep();
}
function goNextStep()
{
gTestEventIndex = 0;
var step = null;
var test = gPopupTests[gTestIndex];
if ("steps" in test) {
gTestStepIndex++;
step = test.steps[gTestStepIndex];
if (gTestStepIndex < test.steps.length) {
test.test(test.testname, step);
return;
}
}
goNext();
}
function goNext()
{
// We want to continue after the next animation frame so that
// we're in a stable state and don't get spurious mouse events at unexpected targets.
window.requestAnimationFrame(
function() {
setTimeout(goNextStepSync, 0);
}
);
}
function goNextStepSync()
{
if (gTestIndex >= 0 && "end" in gPopupTests[gTestIndex] && gPopupTests[gTestIndex].end) {
finish();
return;
}
gTestIndex++;
gTestStepIndex = 0;
if (gTestIndex < gPopupTests.length) {
var test = gPopupTests[gTestIndex];
// Set the location hash so it's easy to see which test is running
document.location.hash = test.testname;
// skip the test if the condition returns false
if ("condition" in test && !test.condition()) {
goNext();
return;
}
// start with the first step if there are any
var step = null;
if ("steps" in test)
step = test.steps[gTestStepIndex];
test.test(test.testname, step);
// no events to check for so just check the result
if (!("events" in test))
checkResult();
}
else {
finish();
}
}
function openMenu(menu)
{
if ("open" in menu) {
menu.open = true;
}
else {
var bo = menu.boxObject;
if (bo instanceof MenuBoxObject)
bo.openMenu(true);
else
synthesizeMouse(menu, 4, 4, { });
}
}
function closeMenu(menu, popup)
{
if ("open" in menu) {
menu.open = false;
}
else {
var bo = menu.boxObject;
if (bo instanceof MenuBoxObject)
bo.openMenu(false);
else
popup.hidePopup();
}
}
function checkActive(popup, id, testname)
{
var activeok = true;
var children = popup.childNodes;
for (var c = 0; c < children.length; c++) {
var child = children[c];
if ((id == child.id && child.getAttribute(menuactiveAttribute) != "true") ||
(id != child.id && child.hasAttribute(menuactiveAttribute) != "")) {
activeok = false;
break;
}
}
ok(activeok, testname + " item " + (id ? id : "none") + " active");
}
function checkOpen(menuid, testname)
{
var menu = document.getElementById(menuid);
if ("open" in menu)
ok(menu.open, testname + " " + menuid + " menu is open");
else if (menu.boxObject instanceof MenuBoxObject)
ok(menu.getAttribute("open") == "true", testname + " " + menuid + " menu is open");
}
function checkClosed(menuid, testname)
{
var menu = document.getElementById(menuid);
if ("open" in menu)
ok(!menu.open, testname + " " + menuid + " menu is open");
else if (menu.boxObject instanceof MenuBoxObject)
ok(!menu.hasAttribute("open"), testname + " " + menuid + " menu is closed");
}
function convertPosition(anchor, align)
{
if (anchor == "topleft" && align == "topleft") return "overlap";
if (anchor == "topleft" && align == "topright") return "start_before";
if (anchor == "topleft" && align == "bottomleft") return "before_start";
if (anchor == "topright" && align == "topleft") return "end_before";
if (anchor == "topright" && align == "bottomright") return "before_end";
if (anchor == "bottomleft" && align == "bottomright") return "start_after";
if (anchor == "bottomleft" && align == "topleft") return "after_start";
if (anchor == "bottomright" && align == "bottomleft") return "end_after";
if (anchor == "bottomright" && align == "topright") return "after_end";
return "";
}
/*
* When checking position of the bottom or right edge of the popup's rect,
* use this instead of strict equality check of rounded values,
* because we snap the top/left edges to pixel boundaries,
* which can shift the bottom/right up to 0.5px from its "ideal" location,
* and could cause it to round differently. (See bug 622507.)
*/
function isWithinHalfPixel(a, b)
{
return Math.abs(a - b) <= 0.5;
}
function compareEdge(anchor, popup, edge, offsetX, offsetY, testname)
{
testname += " " + edge;
checkOpen(anchor.id, testname);
var anchorrect = anchor.getBoundingClientRect();
var popuprect = popup.getBoundingClientRect();
var check1 = false, check2 = false;
if (gPopupWidth == -1) {
ok((Math.round(popuprect.right) - Math.round(popuprect.left)) &&
(Math.round(popuprect.bottom) - Math.round(popuprect.top)),
testname + " size");
}
else {
is(Math.round(popuprect.width), gPopupWidth, testname + " width");
is(Math.round(popuprect.height), gPopupHeight, testname + " height");
}
var spaceIdx = edge.indexOf(" ");
if (spaceIdx > 0) {
let cornerX, cornerY;
let [position, align] = edge.split(" ");
switch (position) {
case "topleft": cornerX = anchorrect.left; cornerY = anchorrect.top; break;
case "topcenter": cornerX = anchorrect.left + anchorrect.width / 2; cornerY = anchorrect.top; break;
case "topright": cornerX = anchorrect.right; cornerY = anchorrect.top; break;
case "leftcenter": cornerX = anchorrect.left; cornerY = anchorrect.top + anchorrect.height / 2; break;
case "rightcenter": cornerX = anchorrect.right; cornerY = anchorrect.top + anchorrect.height / 2; break;
case "bottomleft": cornerX = anchorrect.left; cornerY = anchorrect.bottom; break;
case "bottomcenter": cornerX = anchorrect.left + anchorrect.width / 2; cornerY = anchorrect.bottom; break;
case "bottomright": cornerX = anchorrect.right; cornerY = anchorrect.bottom; break;
}
switch (align) {
case "topleft": cornerX += offsetX; cornerY += offsetY; break;
case "topright": cornerX += -popuprect.width + offsetX; cornerY += offsetY; break;
case "bottomleft": cornerX += offsetX; cornerY += -popuprect.height + offsetY; break;
case "bottomright": cornerX += -popuprect.width + offsetX; cornerY += -popuprect.height + offsetY; break;
}
is(Math.round(popuprect.left), Math.round(cornerX), testname + " x position");
is(Math.round(popuprect.top), Math.round(cornerY), testname + " y position");
return;
}
if (edge == "after_pointer") {
is(Math.round(popuprect.left), Math.round(anchorrect.left) + offsetX, testname + " x position");
is(Math.round(popuprect.top), Math.round(anchorrect.top) + offsetY + 21, testname + " y position");
return;
}
if (edge == "overlap") {
ok(Math.round(anchorrect.left) + offsetY == Math.round(popuprect.left) &&
Math.round(anchorrect.top) + offsetY == Math.round(popuprect.top),
testname + " position");
return;
}
if (edge.indexOf("before") == 0)
check1 = isWithinHalfPixel(anchorrect.top + offsetY, popuprect.bottom);
else if (edge.indexOf("after") == 0)
check1 = (Math.round(anchorrect.bottom) + offsetY == Math.round(popuprect.top));
else if (edge.indexOf("start") == 0)
check1 = isWithinHalfPixel(anchorrect.left + offsetX, popuprect.right);
else if (edge.indexOf("end") == 0)
check1 = (Math.round(anchorrect.right) + offsetX == Math.round(popuprect.left));
if (0 < edge.indexOf("before"))
check2 = (Math.round(anchorrect.top) + offsetY == Math.round(popuprect.top));
else if (0 < edge.indexOf("after"))
check2 = isWithinHalfPixel(anchorrect.bottom + offsetY, popuprect.bottom);
else if (0 < edge.indexOf("start"))
check2 = (Math.round(anchorrect.left) + offsetX == Math.round(popuprect.left));
else if (0 < edge.indexOf("end"))
check2 = isWithinHalfPixel(anchorrect.right + offsetX, popuprect.right);
ok(check1 && check2, testname + " position");
}

Binary file not shown.

View file

@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Audio controls test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<audio id="audio" controls preload="auto"></audio>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
function loadedmetadata(event) {
is(event.type, "loadedmetadata", "checking event type");
is(audio.clientHeight, 28, "checking height of audio element");
SimpleTest.finish();
}
var audio = document.getElementById("audio");
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startTest);
function startTest() {
// Kick off test once audio has loaded.
audio.addEventListener("loadedmetadata", loadedmetadata, false);
audio.src = "audio.wav";
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that an audio element that's already playing when controls are attached displays the controls</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<audio id="audio" controls src="audio.ogg"></audio>
</div>
<pre id="test">
<script class="testbody">
var audio = document.getElementById("audio");
audio.play();
audio.ontimeupdate = function doTest() {
ok(audio.getBoundingClientRect().height > 0,
"checking audio element height is greater than zero");
audio.ontimeupdate = null;
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,102 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Context menugroup Tests"
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="popup_shared.js"></script>
<menupopup id="context">
<menugroup>
<menuitem id="a"/>
<menuitem id="b"/>
</menugroup>
<menuitem id="c" label="c"/>
<menugroup/>
</menupopup>
<button label="Check"/>
<vbox id="popuparea" popup="context" width="20" height="20"/>
<script type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
var gMenuPopup = $("context");
ok(gMenuPopup, "Got the reference to the context menu");
var popupTests = [
{
testname: "one-down-key",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "popupshowing context", "popupshown context", "DOMMenuItemActive a" ],
test: function () {
synthesizeMouse($("popuparea"), 4, 4, {});
synthesizeKey("VK_DOWN", {});
},
result: function (testname) {
checkActive(gMenuPopup, "a", testname);
}
},
{
testname: "two-down-keys",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "DOMMenuItemInactive a", "DOMMenuItemActive b" ],
test: () => synthesizeKey("VK_DOWN", {}),
result: function (testname) {
checkActive(gMenuPopup, "b", testname);
}
},
{
testname: "three-down-keys",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "DOMMenuItemInactive b", "DOMMenuItemActive c" ],
test: () => synthesizeKey("VK_DOWN", {}),
result: function (testname) {
checkActive(gMenuPopup, "c", testname);
}
},
{
testname: "three-down-keys-one-up-key",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "DOMMenuItemInactive c", "DOMMenuItemActive b" ],
test: () => synthesizeKey("VK_UP", {}),
result: function (testname) {
checkActive(gMenuPopup, "b", testname);
}
},
{
testname: "three-down-keys-two-up-keys",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "DOMMenuItemInactive b", "DOMMenuItemActive a" ],
test: () => synthesizeKey("VK_UP", {}),
result: function (testname) {
checkActive(gMenuPopup, "a", testname);
}
},
{
testname: "three-down-keys-three-up-key",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "DOMMenuItemInactive a", "DOMMenuItemActive c" ],
test: () => synthesizeKey("VK_UP", {}),
result: function (testname) {
checkActive(gMenuPopup, "c", testname);
}
},
];
SimpleTest.waitForFocus(function runTest() {
startPopupTests(popupTests);
});
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml"><p id="display"/></body>
</window>

View file

@ -0,0 +1,138 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Nested Context Menu Tests"
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="popup_shared.js"></script>
<menupopup id="outercontext">
<menuitem label="Context One"/>
<menu id="outercontextmenu" label="Sub">
<menupopup id="innercontext">
<menuitem id="innercontextmenu" label="Sub Context One"/>
</menupopup>
</menu>
</menupopup>
<menupopup id="outermain">
<menuitem label="One"/>
<menu id="outermenu" label="Sub">
<menupopup id="innermain">
<menuitem id="innermenu" label="Sub One" context="outercontext"/>
</menupopup>
</menu>
</menupopup>
<button label="Check"/>
<vbox id="popuparea" popup="outermain" width="20" height="20"/>
<script type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
var popupTests = [
{
testname: "open outer popup",
events: [ "popupshowing outermain", "popupshown outermain" ],
test: () => synthesizeMouse($("popuparea"), 4, 4, {}),
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname);
is(document.popupNode, $("popuparea"), testname + " document.popupNode");
}
},
{
testname: "open inner popup",
events: [ "DOMMenuItemActive outermenu", "popupshowing innermain", "popupshown innermain" ],
test: function () {
synthesizeMouse($("outermenu"), 4, 4, { type: "mousemove" });
synthesizeMouse($("outermenu"), 2, 2, { type: "mousemove" });
},
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, null, testname + " outer context");
is(document.popupNode, $("popuparea"), testname + " document.popupNode");
}
},
{
testname: "open outer context",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "popupshowing outercontext", "popupshown outercontext" ],
test: () => synthesizeMouse($("innermenu"), 4, 4, { type: "contextmenu", button: 2 }),
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, $("innermenu"), testname + " outer context");
is(document.popupNode, $("innermenu"), testname + " document.popupNode");
}
},
{
testname: "open inner context",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "DOMMenuItemActive outercontextmenu", "popupshowing innercontext", "popupshown innercontext" ],
test: function () {
synthesizeMouse($("outercontextmenu"), 4, 4, { type: "mousemove" });
setTimeout(function() {
synthesizeMouse($("outercontextmenu"), 2, 2, { type: "mousemove" });
}, 1000);
},
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, $("innermenu"), testname + " outer context");
is($("innercontext").triggerNode, $("innermenu"), testname + " inner context");
is(document.popupNode, $("innermenu"), testname + " document.popupNode");
}
},
{
testname: "close context",
condition: function() { return (navigator.platform.indexOf("Mac") == -1); },
events: [ "popuphiding innercontext", "popuphidden innercontext",
"popuphiding outercontext", "popuphidden outercontext",
"DOMMenuInactive innercontext",
"DOMMenuItemInactive outercontextmenu", "DOMMenuItemInactive outercontextmenu",
"DOMMenuInactive outercontext" ],
test: () => $("outercontext").hidePopup(),
result: function (testname) {
is($("outermain").triggerNode, $("popuparea"), testname + " outer");
is($("innermain").triggerNode, $("popuparea"), testname + " inner");
is($("outercontext").triggerNode, null, testname + " outer context");
is($("innercontext").triggerNode, null, testname + " inner context");
is(document.popupNode, $("popuparea"), testname + " document.popupNode");
}
},
{
testname: "hide menus",
events: [ "popuphiding innermain", "popuphidden innermain",
"popuphiding outermain", "popuphidden outermain",
"DOMMenuInactive innermain",
"DOMMenuItemInactive outermenu", "DOMMenuItemInactive outermenu",
"DOMMenuInactive outermain" ],
test: () => $("outermain").hidePopup(),
result: function (testname) {
is($("outermain").triggerNode, null, testname + " outer");
is($("innermain").triggerNode, null, testname + " inner");
is($("outercontext").triggerNode, null, testname + " outer context");
is($("innercontext").triggerNode, null, testname + " inner context");
is(document.popupNode, null, testname + " document.popupNode");
}
}
];
SimpleTest.waitForFocus(function runTest() {
return startPopupTests(popupTests);
});
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml"><p id="display"/></body>
</window>

View file

@ -0,0 +1,39 @@
<?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 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Editor currentURI Tests" onload="runTest();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<p/>
<editor xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="editor"
type="content"
editortype="html"
style="width: 400px; height: 100px;"/>
<p/>
<pre id="test">
</pre>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
function runTest() {
var editor = document.getElementById("editor");
// Check that currentURI is a property of editor.
var result = "currentURI" in editor;
is(result, true, "currentURI is a property of editor");
is(editor.currentURI.spec, "about:blank", "currentURI.spec is about:blank");
SimpleTest.finish();
}
]]>
</script>
</window>

View file

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Menubar Popup Tests"
onload="setTimeout(runTest, 0);"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Menubar Popup Tests</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
SimpleTest.waitForExplicitFinish();
function runTest()
{
window.open("window_menubar.xul", "_blank", "width=600,height=600");
}
</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>

View file

@ -0,0 +1,109 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Mouse capture on area elements tests</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<!-- The border="0" on the images is needed so that when we use
synthesizeMouse we don't accidentally target the border of the image and
miss the area because synthesizeMouse gets the rect of the primary frame
of the target (the area), which is the image due to bug 135040, which
includes the border, but the events targetted at the border aren't
targeted at the area. -->
<!-- 20x20 of red -->
<img id="image" border="0"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"
usemap="#Map"/>
<map name="Map">
<!-- area over the whole image -->
<area id="area" onmousedown="this.setCapture();" onmouseup="this.releaseCapture();"
shape="poly" coords="0,0, 0,20, 20,20, 20,0" href="javascript:void(0);"/>
</map>
<!-- 20x20 of red -->
<img id="img1" border="0"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"
usemap="#sharedMap"/>
<!-- 20x20 of red -->
<img id="img2" border="0"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"
usemap="#sharedMap"/>
<map name="sharedMap">
<!-- area over the whole image -->
<area id="sharedarea" onmousedown="this.setCapture();" onmouseup="this.releaseCapture();"
shape="poly" coords="0,0, 0,20, 20,20, 20,0" href="javascript:void(0);"/>
</map>
<div id="otherelement" style="width: 100px; height: 100px;"></div>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.expectAssertions(3);
SimpleTest.waitForExplicitFinish();
function runTests()
{
// XXX We send a useless click to each image to force it to setup its image
// map, because flushing layout won't do it. Hopefully bug 135040 will make
// this not suck.
synthesizeMouse($("image"), 5, 5, { type: "mousedown" });
synthesizeMouse($("image"), 5, 5, { type: "mouseup" });
synthesizeMouse($("img1"), 5, 5, { type: "mousedown" });
synthesizeMouse($("img1"), 5, 5, { type: "mouseup" });
synthesizeMouse($("img2"), 5, 5, { type: "mousedown" });
synthesizeMouse($("img2"), 5, 5, { type: "mouseup" });
// test that setCapture works on an area element (bug 517737)
var area = document.getElementById("area");
synthesizeMouse(area, 5, 5, { type: "mousedown" });
synthesizeMouseExpectEvent($("otherelement"), 5, 5, { type: "mousemove" },
area, "mousemove", "setCapture works on areas");
synthesizeMouse(area, 5, 5, { type: "mouseup" });
// test that setCapture works on an area element when it is part of an image
// map that is used by two images
var img1 = document.getElementById("img1");
var sharedarea = document.getElementById("sharedarea");
// synthesizeMouse just sends the event by coordinates, so this is really a click on the area
synthesizeMouse(img1, 5, 5, { type: "mousedown" });
synthesizeMouseExpectEvent($("otherelement"), 5, 5, { type: "mousemove" },
sharedarea, "mousemove", "setCapture works on areas with multiple images");
synthesizeMouse(img1, 5, 5, { type: "mouseup" });
var img2 = document.getElementById("img2");
// synthesizeMouse just sends the event by coordinates, so this is really a click on the area
synthesizeMouse(img2, 5, 5, { type: "mousedown" });
synthesizeMouseExpectEvent($("otherelement"), 5, 5, { type: "mousemove" },
sharedarea, "mousemove", "setCapture works on areas with multiple images");
synthesizeMouse(img2, 5, 5, { type: "mouseup" });
// Bug 862673 - nuke all content so assertions in this test are attributed to
// this test rather than the one which happens to follow.
var content = document.getElementById("content");
content.parentNode.removeChild(content);
SimpleTest.finish();
}
SimpleTest.waitForFocus(runTests);
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,430 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Popup Anchor Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<panel id="testPanel"
type="arrow"
animate="false"
noautohide="true">
</panel>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
<![CDATA[
var anchor, panel, arrow;
function is_close(got, exp, msg) {
// on some platforms we see differences of a fraction of a pixel - so
// allow any difference of < 1 pixels as being OK.
ok(Math.abs(got - exp) < 1, msg + ": " + got + " should be equal(-ish) to " + exp);
}
function isArrowPositionedOn(side, offset) {
var arrowRect = arrow.getBoundingClientRect();
var arrowMidX = (arrowRect.left + arrowRect.right) / 2;
var arrowMidY = (arrowRect.top + arrowRect.bottom) / 2;
var panelRect = panel.getBoundingClientRect();
var panelMidX = (panelRect.left + panelRect.right) / 2;
var panelMidY = (panelRect.top + panelRect.bottom) / 2;
// First check the "flip" of the panel is correct. If we are expecting the
// arrow to be pointing to the left side of the anchor, the arrow must
// also be on the left side of the panel (and vice-versa)
// XXX - on OSX, the arrow seems to always be exactly in the center, hence
// the 'equals' sign in the "<=" and ">=" comparisons. NFI why though...
switch (side) {
case "left":
ok(arrowMidX <= panelMidX, "arrow should be on the left of the panel");
break;
case "right":
ok(arrowMidX >= panelMidX, "arrow should be on the right of the panel");
break;
case "top":
ok(arrowMidY <= panelMidY, "arrow should be on the top of the panel");
break;
case "bottom":
ok(arrowMidY >= panelMidY, "arrow should be on the bottom of the panel");
break;
default:
ok(false, "invalid position " + where);
break;
}
// Now check the arrow really is pointing where we expect. The middle of
// the arrow should be pointing exactly to the left (or right) side of the
// anchor rect, +- any offsets.
if (offset === null) // special case - explicit 'null' means 'don't check offset'
return;
offset = offset || 0; // no param means no offset expected.
var anchorRect = anchor.getBoundingClientRect();
var anchorPos = anchorRect[side];
switch (side) {
case "left":
case "right":
is_close(arrowMidX - anchorPos, offset, "arrow should be " + offset + "px from " + side + " side of anchor");
is_close(panelRect.top, anchorRect.bottom, "top of panel should be at bottom of anchor");
break;
case "top":
case "bottom":
is_close(arrowMidY - anchorPos, offset, "arrow should be " + offset + "px from " + side + " side of anchor");
is_close(panelRect.right, anchorRect.left, "right of panel should be left of anchor");
break;
default:
ok(false, "unknown side " + side);
break;
}
}
function openSlidingPopup(position, callback) {
panel.setAttribute("flip", "slide");
_openPopup(position, callback);
}
function openPopup(position, callback) {
panel.setAttribute("flip", "both");
_openPopup(position, callback);
}
function waitForPopupPositioned(actionFn, callback)
{
panel.addEventListener("popuppositioned", function listener() {
panel.removeEventListener("popuppositioned", listener, false);
callback();
}, false);
actionFn();
}
function _openPopup(position, callback) {
// this is very ugly: the panel CSS sets the arrow's list-style-image based
// on the 'side' attribute. If the setting of the 'side' attribute causes
// the image to change, we may get the popupshown event before the new
// image has loaded - which causes the size of the arrow to be incorrect
// for a brief moment - right when we are measuring it!
// So we work around this in 2 steps:
// * Force the 'side' attribute to a value which causes the CSS to not
// specify an image - then when the popup gets shown, the correct image
// is set, causing a load() event on the image element.
// * Listen to *both* popupshown and the image load event. When both have
// fired (the order is indeterminate) we start the test.
panel.setAttribute("side", "noside");
var numEvents = 0;
function onEvent() {
if (++numEvents == 2) // after both panel 'popupshown' and image 'load'
callback();
};
panel.addEventListener("popupshown", function popupshown() {
panel.removeEventListener("popupshown", popupshown);
onEvent();
});
arrow.addEventListener("load", function imageload() {
arrow.removeEventListener("load", imageload);
onEvent();
});
panel.openPopup(anchor, position);
}
var tests = [
// A panel with the anchor after_end - the anchor should not move on resize
['simpleResizeHorizontal', 'middle', function(next) {
openPopup("after_end", function() {
isArrowPositionedOn("right");
var origPanelRect = panel.getBoundingClientRect();
panel.sizeTo(100, 100);
isArrowPositionedOn("right"); // should not have flipped, so still "right"
panel.sizeTo(origPanelRect.width, origPanelRect.height);
isArrowPositionedOn("right"); // should not have flipped, so still "right"
next();
});
}],
['simpleResizeVertical', 'middle', function(next) {
openPopup("start_after", function() {
isArrowPositionedOn("bottom");
var origPanelRect = panel.getBoundingClientRect();
panel.sizeTo(100, 100);
isArrowPositionedOn("bottom"); // should not have flipped
panel.sizeTo(origPanelRect.width, origPanelRect.height);
isArrowPositionedOn("bottom"); // should not have flipped
next();
});
}],
['flippingResizeHorizontal', 'middle', function(next) {
openPopup("after_end", function() {
isArrowPositionedOn("right");
panel.sizeTo(anchor.getBoundingClientRect().left + 50, 50);
isArrowPositionedOn("left"); // check it flipped and has zero offset.
next();
});
}],
['flippingResizeVertical', 'middle', function(next) {
openPopup("start_after", function() {
isArrowPositionedOn("bottom");
panel.sizeTo(50, anchor.getBoundingClientRect().top + 50);
isArrowPositionedOn("top"); // check it flipped and has zero offset.
next();
});
}],
['simpleMoveToAnchorHorizontal', 'middle', function(next) {
openPopup("after_end", function() {
isArrowPositionedOn("right");
panel.moveToAnchor(anchor, "after_end", 20, 0);
// the anchor and the panel should have moved 20px right without flipping.
isArrowPositionedOn("right", 20);
panel.moveToAnchor(anchor, "after_end", -20, 0);
// the anchor and the panel should have moved 20px left without flipping.
isArrowPositionedOn("right", -20);
next();
});
}],
['simpleMoveToAnchorVertical', 'middle', function(next) {
openPopup("start_after", function() {
isArrowPositionedOn("bottom");
panel.moveToAnchor(anchor, "start_after", 0, 20);
// the anchor and the panel should have moved 20px down without flipping.
isArrowPositionedOn("bottom", 20);
panel.moveToAnchor(anchor, "start_after", 0, -20);
// the anchor and the panel should have moved 20px up without flipping.
isArrowPositionedOn("bottom", -20);
next();
});
}],
// Do a moveToAnchor that causes the panel to flip horizontally
['flippingMoveToAnchorHorizontal', 'middle', function(next) {
var anchorRight = anchor.getBoundingClientRect().right;
// Size the panel such that it only just fits from the left-hand side of
// the window to the right of the anchor - thus, it will fit when
// anchored to the right-hand side of the anchor.
panel.sizeTo(anchorRight - 10, 100);
openPopup("after_end", function() {
isArrowPositionedOn("right");
// Ask for it to be anchored 1/2 way between the left edge of the window
// and the anchor right - it can't fit with the panel on the left/arrow
// on the right, so it must flip (arrow on the left, panel on the right)
var offset = Math.floor(-anchorRight / 2);
waitForPopupPositioned(
() => panel.moveToAnchor(anchor, "after_end", offset, 0),
() => {
isArrowPositionedOn("left", offset); // should have flipped and have the offset.
// resize back to original and move to a zero offset - it should flip back.
panel.sizeTo(anchorRight - 10, 100);
waitForPopupPositioned(
() => panel.moveToAnchor(anchor, "after_end", 0, 0),
() => {
isArrowPositionedOn("right"); // should have flipped back and no offset
next();
});
});
});
}],
// Do a moveToAnchor that causes the panel to flip vertically
['flippingMoveToAnchorVertical', 'middle', function(next) {
var anchorBottom = anchor.getBoundingClientRect().bottom;
// See comments above in flippingMoveToAnchorHorizontal, but read
// "top/bottom" instead of "left/right"
panel.sizeTo(100, anchorBottom - 10);
openPopup("start_after", function() {
isArrowPositionedOn("bottom");
var offset = Math.floor(-anchorBottom / 2);
waitForPopupPositioned(
() => panel.moveToAnchor(anchor, "start_after", 0, offset),
() => {
isArrowPositionedOn("top", offset);
panel.sizeTo(100, anchorBottom - 10);
waitForPopupPositioned(
() => panel.moveToAnchor(anchor, "start_after", 0, 0),
() => {
isArrowPositionedOn("bottom");
next();
});
});
});
}],
['veryWidePanel-after_end', 'middle', function(next) {
openSlidingPopup("after_end", function() {
var origArrowRect = arrow.getBoundingClientRect();
// Now move it such that the arrow can't be at either end of the panel but
// instead somewhere in the middle as that is the only way things fit,
// meaning the arrow should "slide" down the panel.
panel.sizeTo(window.innerWidth - 10, 60);
is(panel.getBoundingClientRect().width, window.innerWidth - 10, "width is what we requested.")
// the arrow should not have moved.
var curArrowRect = arrow.getBoundingClientRect();
is_close(curArrowRect.left, origArrowRect.left, "arrow should not have moved");
is_close(curArrowRect.top, origArrowRect.top, "arrow should not have moved up or down");
next();
});
}],
['veryWidePanel-before_start', 'middle', function(next) {
openSlidingPopup("before_start", function() {
var origArrowRect = arrow.getBoundingClientRect();
// Now size it such that the arrow can't be at either end of the panel but
// instead somewhere in the middle as that is the only way things fit.
panel.sizeTo(window.innerWidth - 10, 60);
is(panel.getBoundingClientRect().width, window.innerWidth - 10, "width is what we requested")
// the arrow should not have moved.
var curArrowRect = arrow.getBoundingClientRect();
is_close(curArrowRect.left, origArrowRect.left, "arrow should not have moved");
is_close(curArrowRect.top, origArrowRect.top, "arrow should not have moved up or down");
next();
});
}],
['veryTallPanel-start_after', 'middle', function(next) {
openSlidingPopup("start_after", function() {
var origArrowRect = arrow.getBoundingClientRect();
// Now move it such that the arrow can't be at either end of the panel but
// instead somewhere in the middle as that is the only way things fit,
// meaning the arrow should "slide" down the panel.
panel.sizeTo(100, window.innerHeight - 10);
is(panel.getBoundingClientRect().height, window.innerHeight - 10, "height is what we requested.")
// the arrow should not have moved.
var curArrowRect = arrow.getBoundingClientRect();
is_close(curArrowRect.left, origArrowRect.left, "arrow should not have moved");
is_close(curArrowRect.top, origArrowRect.top, "arrow should not have moved up or down");
next();
});
}],
['veryTallPanel-start_before', 'middle', function(next) {
openSlidingPopup("start_before", function() {
var origArrowRect = arrow.getBoundingClientRect();
// Now size it such that the arrow can't be at either end of the panel but
// instead somewhere in the middle as that is the only way things fit.
panel.sizeTo(100, window.innerHeight - 10);
is(panel.getBoundingClientRect().height, window.innerHeight - 10, "height is what we requested")
// the arrow should not have moved.
var curArrowRect = arrow.getBoundingClientRect();
is_close(curArrowRect.left, origArrowRect.left, "arrow should not have moved");
is_close(curArrowRect.top, origArrowRect.top, "arrow should not have moved up or down");
next();
});
}],
// Tests against the anchor at the right-hand side of the window
['afterend', 'right', function(next) {
openPopup("after_end", function() {
// when we request too far to the right/bottom, the panel gets shrunk
// and moved. The amount it is shrunk by is how far it is moved.
var panelRect = panel.getBoundingClientRect();
// panel was requested 100px wide - calc offset based on actual width.
var offset = panelRect.width - 100;
isArrowPositionedOn("right", offset);
next();
});
}],
['after_start', 'right', function(next) {
openPopup("after_start", function() {
// See above - we are still too far to the right, but the anchor is
// on the other side.
var panelRect = panel.getBoundingClientRect();
var offset = panelRect.width - 100;
isArrowPositionedOn("right", offset);
next();
});
}],
// Tests against the anchor at the left-hand side of the window
['after_start', 'left', function(next) {
openPopup("after_start", function() {
var panelRect = panel.getBoundingClientRect();
is(panelRect.left, 0, "panel remains within the screen");
// not sure how to determine the offset here, so given we have checked
// the panel is as left as possible while still being inside the window,
// we just don't check the offset.
isArrowPositionedOn("left", null);
next();
});
}],
]
function runTests() {
function runNextTest() {
let result = tests.shift();
if (!result) {
// out of tests
panel.hidePopup();
SimpleTest.finish();
return;
}
let [name, anchorPos, test] = result;
SimpleTest.info("sub-test " + anchorPos + "." + name + " starting");
// first arrange for the anchor to be where the test requires it.
panel.hidePopup();
panel.sizeTo(100, 50);
// hide all the anchors here, then later we make one of them visible.
document.getElementById("anchor-left-wrapper").style.display = "none";
document.getElementById("anchor-middle-wrapper").style.display = "none";
document.getElementById("anchor-right-wrapper").style.display = "none";
switch(anchorPos) {
case 'middle':
anchor = document.getElementById("anchor-middle");
document.getElementById("anchor-middle-wrapper").style.display = "block";
break;
case 'left':
anchor = document.getElementById("anchor-left");
document.getElementById("anchor-left-wrapper").style.display = "block";
break;
case 'right':
anchor = document.getElementById("anchor-right");
document.getElementById("anchor-right-wrapper").style.display = "block";
break;
default:
SimpleTest.ok(false, "Bad anchorPos: " + anchorPos);
runNextTest();
return;
}
try {
test(runNextTest);
} catch (ex) {
SimpleTest.ok(false, "sub-test " + anchorPos + "." + name + " failed: " + ex.toString() + "\n" + ex.stack);
runNextTest();
}
}
runNextTest();
}
SimpleTest.waitForExplicitFinish();
addEventListener("load", function() {
// anchor is set by the test runner above
panel = document.getElementById("testPanel");
arrow = SpecialPowers.wrap(document).getAnonymousElementByAttribute(panel, "anonid", "arrow");
runTests();
});
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<!-- Our tests assume at least 100px around the anchor on all sides, else the
panel may flip when we don't expect it to
-->
<div id="anchor-middle-wrapper" style="margin: 100px 100px 100px 100px;">
<p>The anchor --&gt; <span id="anchor-middle">v</span> &lt;--</p>
</div>
<div id="anchor-left-wrapper" style="text-align: left; display: none;">
<p><span id="anchor-left">v</span> &lt;-- The anchor;</p>
</div>
<div id="anchor-right-wrapper" style="text-align: right; display: none;">
<p>The anchor --&gt; <span id="anchor-right">v</span></p>
</div>
</body>
</window>

View file

@ -0,0 +1,111 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Popup Reflow Tests"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<panel id="testPanel"
type="arrow"
noautohide="true">
</panel>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
<![CDATA[
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
let panel, anchor, arrow;
// A reflow observer - it just remembers the stack trace of all sync reflows
// done by the panel.
let observer = {
reflows: [],
reflow: function (start, end) {
// Ignore reflows triggered by native code
// (Reflows from native code only have an empty stack after the first frame)
var path = (new Error().stack).split("\n").slice(1).join("");
if (path === "") {
return;
}
this.reflows.push(new Error().stack);
},
reflowInterruptible: function (start, end) {
// We're not interested in interruptible reflows. Why, you ask? Because
// we've simply cargo-culted this test from browser_tabopen_reflows.js!
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
Ci.nsISupportsWeakReference])
};
// A test utility that counts the reflows caused by a test function. If the
// count of reflows isn't what is expected, it causes a test failure and logs
// the stack trace of all seen reflows.
function countReflows(testfn, expected) {
let deferred = Promise.defer();
observer.reflows = [];
let docShell = panel.ownerDocument.defaultView
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShell);
docShell.addWeakReflowObserver(observer);
testfn().then(() => {
docShell.removeWeakReflowObserver(observer);
SimpleTest.is(observer.reflows.length, expected, "correct number of reflows");
if (observer.reflows.length != expected) {
SimpleTest.info("stack traces of reflows:\n" + observer.reflows.join("\n") + "\n");
}
deferred.resolve();
});
return deferred.promise
}
function openPopup() {
let deferred = Promise.defer();
panel.addEventListener("popupshown", function popupshown() {
panel.removeEventListener("popupshown", popupshown);
deferred.resolve();
});
panel.openPopup(anchor, "before_start");
return deferred.promise
}
// ********************
// The actual tests...
// We only have one atm - simply open a popup.
//
function testSimplePanel() {
return openPopup();
}
// ********************
// The test harness...
//
SimpleTest.waitForExplicitFinish();
addEventListener("load", function() {
anchor = document.getElementById("anchor");
panel = document.getElementById("testPanel");
arrow = document.getAnonymousElementByAttribute(panel, "anonid", "arrow");
// Cancel the arrow panel slide-in transition (bug 767133) - we are only
// testing reflows in the core panel implementation and not reflows that may
// or may not be caused by transitioning....
arrow.style.transition = "none";
// and off we go...
countReflows(testSimplePanel, 1).then(SimpleTest.finish);
});
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p>The anchor --&gt; <span id="anchor">v</span> &lt;--</p>
</body>
</window>

View file

@ -0,0 +1,76 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
XUL Widget Test for reordering tree columns
-->
<window title="Tree" width="500" height="600"
onload="setTimeout(testtag_tree_column_reorder, 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 type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script src="tree_shared.js"/>
<tree id="tree-column-reorder" rows="1" enableColumnDrag="true">
<treecols>
<treecol id="col_0" label="col_0" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_1" label="col_1" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_2" label="col_2" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_3" label="col_3" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_4" label="col_4" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_5" label="col_5" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_6" label="col_6" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_7" label="col_7" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_8" label="col_8" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_9" label="col_9" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_10" label="col_10" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_11" label="col_11" flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="col_12" label="col_12" flex="1"/>
</treecols>
<treechildren id="treechildren-column-reorder">
<treeitem>
<treerow>
<treecell label="col_0"/>
<treecell label="col_1"/>
<treecell label="col_2"/>
<treecell label="col_3"/>
<treecell label="col_4"/>
<treecell label="col_5"/>
<treecell label="col_6"/>
<treecell label="col_7"/>
<treecell label="col_8"/>
<treecell label="col_9"/>
<treecell label="col_10"/>
<treecell label="col_11"/>
<treecell label="col_12"/>
</treerow>
</treeitem>
</treechildren>
</tree>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
]]>
</script>
</window>

View file

@ -0,0 +1,411 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<video width="320" height="240" id="video" controls mozNoDynamicControls preload="auto"></video>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/*
* Positions of the UI elements, relative to the upper-left corner of the
* <video> box.
*/
const videoWidth = 320;
const videoHeight = 240;
const videoDuration = 3.8329999446868896;
const playButtonWidth = 28;
const playButtonHeight = 28;
const muteButtonWidth = 33;
const muteButtonHeight = 28;
const durationWidth = 34;
const fullscreenButtonWidth = 28;
const fullscreenButtonHeight = 28;
const volumeSliderWidth = 32;
const scrubberWidth = videoWidth - playButtonWidth - durationWidth - muteButtonWidth - volumeSliderWidth - fullscreenButtonWidth;
const scrubberHeight = 28;
// Play button is on the bottom-left
const playButtonCenterX = 0 + Math.round(playButtonWidth / 2);
const playButtonCenterY = videoHeight - Math.round(playButtonHeight / 2);
// Mute button is on the bottom-right before the full screen button and volume slider
const muteButtonCenterX = videoWidth - Math.round(muteButtonWidth / 2) - volumeSliderWidth - fullscreenButtonWidth;
const muteButtonCenterY = videoHeight - Math.round(muteButtonHeight / 2);
// Fullscreen button is on the bottom-right at the far end
const fullscreenButtonCenterX = videoWidth - Math.round(fullscreenButtonWidth / 2);
const fullscreenButtonCenterY = videoHeight - Math.round(fullscreenButtonHeight / 2);
// Scrubber bar is between the play and mute buttons. We don't need it's
// X center, just the offset of its box.
const scrubberOffsetX = 0 + playButtonWidth;
const scrubberCenterY = videoHeight - Math.round(scrubberHeight / 2);
var testnum = 1;
var video = document.getElementById("video");
const domUtil = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(SpecialPowers.Ci.inIDOMUtils);
function getButtonByAttribute(aName, aValue) {
var kids = domUtil.getChildrenForNode(video, true);
var videocontrols = kids[1];
return SpecialPowers.wrap(document)
.getAnonymousElementByAttribute(videocontrols, aName, aValue);
}
function isMuteButtonMuted() {
var muteButton = getButtonByAttribute('class', 'muteButton');
return muteButton.getAttribute('muted') === 'true';
}
function isVolumeSliderShowingCorrectVolume(expectedVolume) {
var volumeButton = getButtonByAttribute('anonid', 'volumeForeground');
let expectedPaddingRight = (1 - expectedVolume) * volumeSliderWidth + "px";
is(volumeButton.style.paddingRight, expectedPaddingRight,
"volume slider should match expected volume");
}
function forceReframe() {
// Setting display then getting the bounding rect to force a frame
// reconstruction on the video element.
video.style.display = "block";
video.getBoundingClientRect();
video.style.display = "";
video.getBoundingClientRect();
}
function runTest(event) {
ok(true, "----- test #" + testnum + " -----");
switch (testnum) {
/*
* Check operation of play/pause/mute/unmute buttons.
*/
case 1:
// Check initial state upon load
is(event.type, "canplaythrough", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, false, "checking video mute state");
// Click the play button
SimpleTest.executeSoon(() => {
synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { });
});
break;
case 2:
is(event.type, "play", "checking event type");
is(video.paused, false, "checking video play state");
is(video.muted, false, "checking video mute state");
// Click the pause button
SimpleTest.executeSoon(() => {
synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { });
});
break;
case 3:
is(event.type, "pause", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, false, "checking video mute state");
SimpleTest.executeSoon(() => {
synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { }); // Mute.
});
break;
case 4:
is(event.type, "volumechange", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, true, "checking video mute state");
SimpleTest.executeSoon(() => {
synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { }); // Unmute.
});
break;
/*
* Bug 470596: Make sure that having CSS border or padding doesn't
* break the controls (though it should move them)
*/
case 5:
is(event.type, "volumechange", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, false, "checking video mute state");
video.style.border = "medium solid purple";
video.style.borderWidth = "30px 40px 50px 60px";
video.style.padding = "10px 20px 30px 40px";
// totals: top: 40px, right: 60px, bottom: 80px, left: 100px
// Click the play button
SimpleTest.executeSoon(() => {
synthesizeMouse(video, 100 + playButtonCenterX, 40 + playButtonCenterY, { });
});
break;
case 6:
is(event.type, "play", "checking event type");
is(video.paused, false, "checking video play state");
is(video.muted, false, "checking video mute state");
video.pause();
break;
case 7:
is(event.type, "pause", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, false, "checking video mute state");
// Click the mute button
SimpleTest.executeSoon(() => {
synthesizeMouse(video, 100 + muteButtonCenterX, 40 + muteButtonCenterY, { });
});
break;
case 8:
is(event.type, "volumechange", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, true, "checking video mute state");
// Clear the style set in test 5.
video.style.border = "";
video.style.borderWidth = "";
video.style.padding = "";
video.muted = false;
break;
/*
* Previous tests have moved playback postion, reset it to 0.
*/
case 9:
is(event.type, "volumechange", "checking event type");
is(video.paused, true, "checking video play state");
is(video.muted, false, "checking video mute state");
ok(true, "video position is at " + video.currentTime);
video.currentTime = 0.0;
break;
case 10:
is(event.type, "seeking", "checking event type");
ok(true, "video position is at " + video.currentTime);
break;
/*
* Drag the slider's thumb to the halfway point with the mouse.
*/
case 11:
is(event.type, "seeked", "checking event type");
ok(true, "video position is at " + video.currentTime);
// Bug 477434 -- sometimes we get 0.098999 here instead of 0!
// is(video.currentTime, 0.0, "checking playback position");
SimpleTest.executeSoon(() => {
var beginDragX = scrubberOffsetX;
var endDragX = scrubberOffsetX + (scrubberWidth / 2);
synthesizeMouse(video, beginDragX, scrubberCenterY, { type: "mousedown", button: 0 });
synthesizeMouse(video, endDragX, scrubberCenterY, { type: "mousemove", button: 0 });
synthesizeMouse(video, endDragX, scrubberCenterY, { type: "mouseup", button: 0 });
});
break;
case 12:
is(event.type, "seeking", "checking event type");
ok(true, "video position is at " + video.currentTime);
break;
/*
* Click the slider at the 1/4 point with the mouse (jump backwards)
*/
case 13:
is(event.type, "seeked", "checking event type");
ok(true, "video position is at " + video.currentTime);
var expectedTime = videoDuration / 2;
ok(Math.abs(video.currentTime - expectedTime) < 0.1, "checking expected playback position");
SimpleTest.executeSoon(() => {
synthesizeMouse(video, scrubberOffsetX + (scrubberWidth / 4), scrubberCenterY, { });
});
break;
case 14:
is(event.type, "seeking", "checking event type");
ok(true, "video position is at " + video.currentTime);
break;
case 15:
is(event.type, "seeked", "checking event type");
ok(true, "video position is at " + video.currentTime);
// The scrubber currently just jumps towards the nearest pageIncrement point, not
// precisely to the point clicked. So, expectedTime isn't (videoDuration / 4).
// We should end up at 1.733, but sometimes we end up at 1.498. I guess
// it's timing depending if the <scale> things it's click-and-hold, or a
// single click. So, just make sure we end up less that the previous
// position.
lastPosition = (videoDuration / 2) - 0.1;
ok(video.currentTime < lastPosition, "checking expected playback position");
// Set volume to 0.1 so one down arrow hit will decrease it to 0.
video.volume = 0.1;
break;
// See bug 694696.
case 16:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.1, "Volume should be set.");
ok(!video.muted, "Video is not muted.");
video.focus();
SimpleTest.executeSoon(() => synthesizeKey("VK_DOWN", {}));
break;
case 17:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0, "Volume should be 0.");
ok(!video.muted, "Video is not muted.");
SimpleTest.executeSoon(() => {
ok(isMuteButtonMuted(), "Mute button says it's muted");
synthesizeKey("VK_UP", {});
});
break;
case 18:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.1, "Volume is increased.");
ok(!video.muted, "Video is not muted.");
SimpleTest.executeSoon(() => {
ok(!isMuteButtonMuted(), "Mute button says it's not muted");
synthesizeKey("VK_DOWN", {});
});
break;
case 19:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0, "Volume should be 0.");
ok(!video.muted, "Video is not muted.");
SimpleTest.executeSoon(() => {
ok(isMuteButtonMuted(), "Mute button says it's muted");
synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { });
});
break;
case 20:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.5, "Volume should be 0.5.");
ok(!video.muted, "Video is not muted.");
SimpleTest.executeSoon(() => synthesizeKey("VK_UP", {}));
break;
case 21:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.6, "Volume should be 0.6.");
ok(!video.muted, "Video is not muted.");
SimpleTest.executeSoon(() => {
synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { });
});
break;
case 22:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.6, "Volume should be 0.6.");
ok(video.muted, "Video is muted.");
SimpleTest.executeSoon(() => {
ok(isMuteButtonMuted(), "Mute button says it's muted");
synthesizeMouse(video, muteButtonCenterX, muteButtonCenterY, { });
});
break;
case 23:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.6, "Volume should be 0.6.");
ok(!video.muted, "Video is not muted.");
SimpleTest.executeSoon(() => {
ok(!isMuteButtonMuted(), "Mute button says it's not muted");
synthesizeMouse(video, fullscreenButtonCenterX, fullscreenButtonCenterY, { });
});
break;
case 24:
is(event.type, "mozfullscreenchange", "checking event type");
is(video.volume, 0.6, "Volume should still be 0.6");
SimpleTest.executeSoon(function() {
isVolumeSliderShowingCorrectVolume(video.volume);
synthesizeKey("VK_ESCAPE", {});
});
break;
case 25:
is(event.type, "mozfullscreenchange", "checking event type");
is(video.volume, 0.6, "Volume should still be 0.6");
SimpleTest.executeSoon(function() {
isVolumeSliderShowingCorrectVolume(video.volume);
forceReframe();
video.focus();
synthesizeKey("VK_DOWN", {});
});
break;
case 26:
is(event.type, "volumechange", "checking event type");
is(video.volume, 0.5, "Volume should be decreased by 0.1");
SimpleTest.executeSoon(function() {
isVolumeSliderShowingCorrectVolume(video.volume);
SimpleTest.finish();
});
break;
default:
throw "unexpected test #" + testnum + " w/ event " + event.type;
}
testnum++;
}
function canplaythroughevent(event) {
video.removeEventListener("canplaythrough", canplaythroughevent, false);
// Other events expected by the test.
video.addEventListener("play", runTest, false);
video.addEventListener("pause", runTest, false);
video.addEventListener("volumechange", runTest, false);
video.addEventListener("seeking", runTest, false);
video.addEventListener("seeked", runTest, false);
document.addEventListener("mozfullscreenchange", runTest, false);
// Begin the test.
runTest(event);
}
function startMediaLoad() {
// Kick off test once video has loaded, in its canplaythrough event handler.
video.src = "seek_with_sound.ogg";
video.addEventListener("canplaythrough", canplaythroughevent, false);
}
function loadevent(event) {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startMediaLoad);
}
window.addEventListener("load", loadevent, false);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls with Audio file test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<video id="video" controls preload="metadata"></video>
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.7">
var domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
getService(SpecialPowers.Ci.inIDOMUtils);
function findElementByAttribute(element, aName, aValue) {
if (!('getAttribute' in element)) {
return false;
}
if (element.getAttribute(aName) === aValue) {
return element;
}
let children = domUtils.getChildrenForNode(element, true);
for (let child of children) {
var result = findElementByAttribute(child, aName, aValue);
if (result) {
return result;
}
}
return false;
}
function loadedmetadata(event) {
SimpleTest.executeSoon(function() {
var controlBar = findElementByAttribute(video, "class", "controlBar");
is(controlBar.getAttribute("fullscreen-unavailable"), "true", "Fullscreen button is hidden");
SimpleTest.finish();
});
}
var video = document.getElementById("video");
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startTest);
function startTest() {
// Kick off test once audio has loaded.
video.addEventListener("loadedmetadata", loadedmetadata, false);
video.src = "audio.ogg";
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls directionality test</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var tests = [
{op: "==", test: "videocontrols_direction-2a.html", ref: "videocontrols_direction-2-ref.html"},
{op: "==", test: "videocontrols_direction-2b.html", ref: "videocontrols_direction-2-ref.html"},
{op: "==", test: "videocontrols_direction-2c.html", ref: "videocontrols_direction-2-ref.html"},
{op: "==", test: "videocontrols_direction-2d.html", ref: "videocontrols_direction-2-ref.html"},
{op: "==", test: "videocontrols_direction-2e.html", ref: "videocontrols_direction-2-ref.html"}
];
</script>
<script type="text/javascript" src="videocontrols_direction_test.js"></script>
</pre>
</body>
</html>

View file

@ -0,0 +1,64 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test - iframe</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<iframe id="ifr1"></iframe>
<iframe id="ifr2" allowfullscreen></iframe>
</div>
<pre id="test">
<script clas="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
const domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
getService(SpecialPowers.Ci.inIDOMUtils);
const iframe1 = SpecialPowers.wrap(document.getElementById("ifr1"));
const iframe2 = SpecialPowers.wrap(document.getElementById("ifr2"));
const testCases = [];
function checkIframeFullscreenAvailable(ifr) {
const available = ifr.hasAttribute("allowfullscreen");
let video;
return () => new Promise(resolve => {
ifr.srcdoc = `<video id="video" controls preload="auto"></video>`;
ifr.addEventListener("load", resolve, false);
}).then(() => new Promise(resolve => {
video = ifr.contentDocument.getElementById("video");
video.src = "seek_with_sound.ogg";
video.addEventListener("loadedmetadata", resolve, false);
})).then(() => new Promise(resolve => {
const videoControl = domUtils.getChildrenForNode(video, true)[1];
const controlBar = video.ownerDocument.getAnonymousElementByAttribute(
videoControl, "class", "controlBar");
is(controlBar.getAttribute("fullscreen-unavailable") == "true", !available, "The controlbar should have an attribute marking whether fullscreen is available that corresponds to if the iframe has the allowfullscreen attribute.");
resolve();
}));
}
function start() {
testCases.reduce((promise, task) => promise.then(task), Promise.resolve());
}
function load() {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, start);
}
testCases.push(checkIframeFullscreenAvailable(iframe1));
testCases.push(checkIframeFullscreenAvailable(iframe2));
testCases.push(SimpleTest.finish);
window.addEventListener("load", load, false);
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,70 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
function runTest(event) {
info(true, "----- test #" + testnum + " -----");
switch (testnum) {
case 1:
is(event.type, "timeupdate", "checking event type");
is(video.paused, false, "checking video play state");
video.removeEventListener("timeupdate", runTest);
// Click to toggle play/pause (now pausing)
synthesizeMouseAtCenter(video, {}, win);
break;
case 2:
is(event.type, "pause", "checking event type");
is(video.paused, true, "checking video play state");
win.close();
SimpleTest.finish();
break;
default:
ok(false, "unexpected test #" + testnum + " w/ event " + event.type);
throw "unexpected test #" + testnum + " w/ event " + event.type;
}
testnum++;
}
SpecialPowers.pushPrefEnv({"set": [["javascript.enabled", false]]}, startTest);
var testnum = 1;
var video;
function loadevent(event) {
is(win["testExpando"], undefined, "expando shouldn't exist because js is disabled");
video = win.document.querySelector("video");
// Other events expected by the test.
video.addEventListener("timeupdate", runTest, false);
video.addEventListener("pause", runTest, false);
}
var win;
function startTest() {
var videoURL = new URL("seek_with_sound.ogg", document.documentURI).href;
var url = "data:text/html,<video src=" + videoURL + " controls autoplay=true></video><script>window.testExpando = true;</scr" + "ipt>";
win = window.open(url);
win.addEventListener("load", loadevent, false);
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,74 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<video id="video" controls mozNoDynamicControls preload="auto"></video>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var video = document.getElementById("video");
function startMediaLoad() {
// Kick off test once video has loaded, in its canplaythrough event handler.
video.src = "seek_with_sound.ogg";
video.addEventListener("canplaythrough", runTest, false);
}
function loadevent(event) {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startMediaLoad);
}
window.addEventListener("load", loadevent, false);
function runTest() {
video.addEventListener("click", function() {
this.play();
});
ok(video.paused, "video should be paused initially");
new Promise(resolve => {
let timeupdates = 0;
video.addEventListener("timeupdate", function timeupdate() {
ok(!video.paused, "video should not get paused after clicking in middle");
if (++timeupdates == 3) {
video.removeEventListener("timeupdate", timeupdate);
resolve();
}
});
synthesizeMouseAtCenter(video, {}, window);
}).then(function() {
new Promise(resolve => {
video.addEventListener("pause", function onpause() {
setTimeout(() => {
ok(video.paused, "video should still be paused 200ms after pause request");
// When the video reaches the end of playback it is automatically paused.
// Check during the pause event that the video has not reachd the end
// of playback.
ok(!video.ended, "video should not have paused due to playback ending");
resolve();
}, 200);
});
synthesizeMouse(video, 10, video.clientHeight - 10, {}, window);
}).then(SimpleTest.finish);
});
}
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,90 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<pre id="test">
<script class="testbody" type="text/javascript">
const videoWidth = 320;
const videoHeight = 240;
function getMediaElement(aWindow) {
return aWindow.document.getElementsByTagName("video")[0];
}
var popup = window.open("seek_with_sound.ogg");
popup.addEventListener("load", function onLoad() {
popup.removeEventListener("load", onLoad);
var video = getMediaElement(popup);
if (!video.paused)
runTestVideo(video);
else {
video.addEventListener("play", function onPlay() {
video.removeEventListener("play", onPlay);
runTestVideo(video);
});
}
});
function runTestVideo(aVideo) {
var condition = function() {
var boundingRect = aVideo.getBoundingClientRect();
return boundingRect.width == videoWidth &&
boundingRect.height == videoHeight;
};
waitForCondition(condition, function() {
var boundingRect = aVideo.getBoundingClientRect();
is(boundingRect.width, videoWidth, "Width of the video should match expectation");
is(boundingRect.height, videoHeight, "Height of video should match expectation");
popup.close();
runTestAudioPre();
}, "The media element should eventually be resized to match the intrinsic size of the video.");
}
function runTestAudioPre() {
popup = window.open("audio.ogg");
popup.addEventListener("load", function onLoad() {
popup.removeEventListener("load", onLoad);
var audio = getMediaElement(popup);
if (!audio.paused)
runTestAudio(audio);
else {
audio.addEventListener("play", function onPlay() {
audio.removeEventListener("play", onPlay);
runTestAudio(audio);
})
}
})
}
function runTestAudio(aAudio) {
info("User agent (help diagnose bug #943556): " + navigator.userAgent);
var isAndroid = navigator.userAgent.includes("Android");
var expectedHeight = isAndroid ? 103 : 28;
var condition = function () {
var boundingRect = aAudio.getBoundingClientRect();
return boundingRect.height == expectedHeight;
};
waitForCondition(condition, function () {
var boundingRect = aAudio.getBoundingClientRect();
is(boundingRect.height, expectedHeight,
"Height of audio element should be " + expectedHeight + ", which is equal to the controls bar.");
popup.close();
SimpleTest.finish();
}, "The media element should eventually be resized to match the height of the audio controls.");
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls directionality test</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var tests = [
{op: "==", test: "videocontrols_direction-1a.html", ref: "videocontrols_direction-1-ref.html"},
{op: "==", test: "videocontrols_direction-1b.html", ref: "videocontrols_direction-1-ref.html"},
{op: "==", test: "videocontrols_direction-1c.html", ref: "videocontrols_direction-1-ref.html"},
{op: "==", test: "videocontrols_direction-1d.html", ref: "videocontrols_direction-1-ref.html"},
{op: "==", test: "videocontrols_direction-1e.html", ref: "videocontrols_direction-1-ref.html"},
];
</script>
<script type="text/javascript" src="videocontrols_direction_test.js"></script>
</pre>
</body>
</html>

View file

@ -0,0 +1,133 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test - VTT</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<video id="video" controls preload="auto"></video>
</div>
<pre id="test">
<script clas="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
const domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
getService(SpecialPowers.Ci.inIDOMUtils);
const video = document.getElementById("video");
const ccBtn = getElementByAttribute("class", "closedCaptionButton");
const ttList = getElementByAttribute("class", "textTrackList");
const testCases = [];
testCases.push(() => new Promise(resolve => {
is(ccBtn.getAttribute("hidden"), "true", "CC button should hide");
resolve();
}));
testCases.push(() => new Promise(resolve => {
video.addTextTrack("descriptions", "English", "en");
video.addTextTrack("chapters", "English", "en");
video.addTextTrack("metadata", "English", "en");
SimpleTest.executeSoon(() => {
is(ccBtn.getAttribute("hidden"), "true", "CC button should hide if no supported tracks provided");
resolve();
});
}));
testCases.push(() => new Promise(resolve => {
const sub = video.addTextTrack("subtitles", "English", "en");
sub.mode = "disabled";
SimpleTest.executeSoon(() => {
is(ccBtn.getAttribute("hidden"), "", "CC button should show");
is(ccBtn.getAttribute("enabled"), "", "CC button should be disabled");
resolve();
});
}));
testCases.push(() => new Promise(resolve => {
const subtitle = video.addTextTrack("subtitles", "English", "en");
subtitle.mode = "showing";
SimpleTest.executeSoon(() => {
is(ccBtn.getAttribute("enabled"), "true", "CC button should be enabled");
subtitle.mode = "disabled";
resolve();
});
}));
testCases.push(() => new Promise(resolve => {
const caption = video.addTextTrack("captions", "English", "en");
caption.mode = "showing";
SimpleTest.executeSoon(() => {
is(ccBtn.getAttribute("enabled"), "true", "CC button should be enabled");
resolve();
});
}));
testCases.push(() => new Promise(resolve => {
synthesizeMouseAtCenter(ccBtn, {});
SimpleTest.executeSoon(() => {
is(ttList.hasAttribute("hidden"), false, "Texttrack menu should show up");
is(ttList.lastChild.getAttribute("on"), "true", "The last added item should be highlighted");
resolve();
});
}));
testCases.push(() => new Promise(resolve => {
const tt = ttList.children[1];
isnot(tt.getAttribute("on"), "true", "Item should be off before click");
synthesizeMouseAtCenter(tt, {});
SimpleTest.executeSoon(() => {
is(tt.getAttribute("on"), "true", "Selected item should be enabled");
is(ttList.getAttribute("hidden"), "true", "Should hide texttrack menu once clicked on an item");
resolve();
});
}));
function executeTestCases(tasks) {
return tasks.reduce((promise, task) => promise.then(task), Promise.resolve());
}
function getElementByAttribute(aName, aValue) {
const videoControl = domUtils.getChildrenForNode(video, true)[1];
return SpecialPowers.wrap(document)
.getAnonymousElementByAttribute(videoControl, aName, aValue);
}
function loadedmetadata() {
executeTestCases(testCases).then(SimpleTest.finish);
}
function startMediaLoad() {
video.src = "seek_with_sound.ogg";
video.addEventListener("loadedmetadata", loadedmetadata, false);
}
function loadevent() {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startMediaLoad);
}
window.addEventListener("load", loadevent, false);
</script>
</pre>
</body>
</html>

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="text-align: right;">
<video controls preload="none" id="av" source="audio.wav"></video>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html dir="rtl">
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body>
<video controls preload="none" id="av" source="audio.wav"></video>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html style="direction: rtl">
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body>
<video controls preload="none" id="av" source="audio.wav"></video>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="direction: rtl">
<video controls preload="none" id="av" source="audio.wav"></video>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="text-align: right;">
<video controls preload="none" id="av" source="audio.wav" dir="rtl"></video>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="text-align: right;">
<video controls preload="none" id="av" source="audio.wav" style="direction: rtl;"></video>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="text-align: right;">
<audio controls preload="none" id="av" source="audio.wav"></audio>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html dir="rtl">
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body>
<audio controls preload="none" id="av" source="audio.wav"></audio>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html style="direction: rtl">
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body>
<audio controls preload="none" id="av" source="audio.wav"></audio>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="direction: rtl">
<audio controls preload="none" id="av" source="audio.wav"></audio>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="text-align: right;">
<audio controls preload="none" id="av" source="audio.wav" dir="rtl"></audio>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="videomask.css">
</head>
<body style="text-align: right;">
<audio controls preload="none" id="av" source="audio.wav" style="direction: rtl;"></audio>
<div id="mask"></div>
</body>
</html>

View file

@ -0,0 +1,90 @@
var RemoteCanvas = function(url, id) {
this.url = url;
this.id = id;
this.snapshot = null;
};
RemoteCanvas.CANVAS_WIDTH = 200;
RemoteCanvas.CANVAS_HEIGHT = 200;
RemoteCanvas.prototype.compare = function(otherCanvas, expected) {
return compareSnapshots(this.snapshot, otherCanvas.snapshot, expected)[0];
}
RemoteCanvas.prototype.load = function(callback) {
var iframe = document.createElement("iframe");
iframe.id = this.id + "-iframe";
iframe.width = RemoteCanvas.CANVAS_WIDTH + "px";
iframe.height = RemoteCanvas.CANVAS_HEIGHT + "px";
iframe.src = this.url;
var me = this;
iframe.addEventListener("load", function() {
info("iframe loaded");
var m = iframe.contentDocument.getElementById("av");
m.addEventListener("suspend", function(aEvent) {
m.removeEventListener("suspend", arguments.callee, false);
setTimeout(function() {
me.remotePageLoaded(callback);
}, 0);
}, false);
m.src = m.getAttribute("source");
}, false);
window.document.body.appendChild(iframe);
};
RemoteCanvas.prototype.remotePageLoaded = function(callback) {
var ldrFrame = document.getElementById(this.id + "-iframe");
this.snapshot = snapshotWindow(ldrFrame.contentWindow);
this.snapshot.id = this.id + "-canvas";
window.document.body.appendChild(this.snapshot);
callback(this);
};
RemoteCanvas.prototype.cleanup = function() {
var iframe = document.getElementById(this.id + "-iframe");
iframe.parentNode.removeChild(iframe);
var canvas = document.getElementById(this.id + "-canvas");
canvas.parentNode.removeChild(canvas);
};
function runTest(index) {
var canvases = [];
function testCallback(canvas) {
canvases.push(canvas);
if (canvases.length == 2) { // when both canvases are loaded
var expectedEqual = currentTest.op == "==";
var result = canvases[0].compare(canvases[1], expectedEqual);
ok(result, "Rendering of reftest " + currentTest.test + " should " +
(expectedEqual ? "not " : "") + "be different to the reference");
if (result) {
canvases[0].cleanup();
canvases[1].cleanup();
}
else {
info("Snapshot of canvas 1: " + canvases[0].snapshot.toDataURL());
info("Snapshot of canvas 2: " + canvases[1].snapshot.toDataURL());
}
if (index < tests.length - 1)
runTest(index + 1);
else
SimpleTest.finish();
}
}
var currentTest = tests[index];
var testCanvas = new RemoteCanvas(currentTest.test, "test-" + index);
testCanvas.load(testCallback);
var refCanvas = new RemoteCanvas(currentTest.ref, "ref-" + index);
refCanvas.load(testCallback);
}
SimpleTest.waitForExplicitFinish();
SimpleTest.requestCompleteLog();
window.addEventListener("load", function() {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, function() { runTest(0); });
}, true);

View file

@ -0,0 +1,23 @@
html, body {
margin: 0;
padding: 0;
}
audio, video {
width: 140px;
height: 100px;
background-color: black;
}
/**
* Create a mask for the video direction tests which covers up the throbber.
*/
#mask {
position: absolute;
z-index: 3;
width: 140px;
height: 72px;
background-color: green;
top: 0;
right: 0;
}

View file

@ -0,0 +1,820 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<!-- the condition in the focus event handler is because pressing Tab
unfocuses and refocuses the window on Windows -->
<window title="Popup Tests"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="popup_shared.js"></script>
<!--
Need to investigate these tests a bit more. Some of the accessibility events
are firing multiple times or in different orders in different circumstances.
Note that this was also the case before bug 279703.
-->
<hbox style="margin-left: 275px; margin-top: 275px;">
<menubar id="menubar">
<menu id="filemenu" label="File" accesskey="F">
<menupopup id="filepopup">
<menuitem id="item1" label="Open" accesskey="O"/>
<menuitem id="item2" label="Save" accesskey="S"/>
<menuitem id="item3" label="Close" accesskey="C"/>
</menupopup>
</menu>
<menu id="secretmenu" label="Secret Menu" accesskey="S" disabled="true">
<menupopup>
<menuitem label="Secret Command" accesskey="S"/>
</menupopup>
</menu>
<menu id="editmenu" label="Edit" accesskey="E">
<menupopup id="editpopup">
<menuitem id="cut" label="Cut" accesskey="t" disabled="true"/>
<menuitem id="copy" label="Copy" accesskey="C"/>
<menuitem id="paste" label="Paste" accesskey="P"/>
</menupopup>
</menu>
<menu id="viewmenu" label="View" accesskey="V">
<menupopup id="viewpopup">
<menu id="toolbar" label="Toolbar" accesskey="T">
<menupopup id="toolbarpopup">
<menuitem id="navigation" label="Navigation" accesskey="N" disabled="true"/>
<menuitem label="Bookmarks" accesskey="B" disabled="true"/>
</menupopup>
</menu>
<menuitem label="Status Bar" accesskey="S"/>
<menu label="Sidebar" accesskey="d">
<menupopup>
<menuitem label="Bookmarks" accesskey="B"/>
<menuitem label="History" accesskey="H"/>
</menupopup>
</menu>
</menupopup>
</menu>
<menu id="helpmenu" label="Help" accesskey="H">
<menupopup id="helppopup" >
<label value="Unselectable"/>
<menuitem id="contents" label="Contents" accesskey="C"/>
<menuitem label="More Info" accesskey="I"/>
<menuitem id="amenu" label="A Menu" accesskey="M"/>
<menuitem label="Another Menu"/>
<menuitem id="one" label="One"/>
<menu id="only" label="Only Menu">
<menupopup>
<menuitem label="Test Submenu"/>
</menupopup>
</menu>
<menuitem label="Second Menu"/>
<menuitem id="other" disabled="true" label="Other Menu"/>
<menuitem id="third" label="Third Menu"/>
<menuitem label="One Other Menu"/>
<label value="Unselectable"/>
<menuitem id="about" label="About" accesskey="A"/>
</menupopup>
</menu>
</menubar>
</hbox>
<script class="testbody" type="application/javascript">
<![CDATA[
window.opener.SimpleTest.waitForFocus(function () {
gFilePopup = document.getElementById("filepopup");
var filemenu = document.getElementById("filemenu");
filemenu.focus();
is(filemenu.openedWithKey, false, "initial openedWithKey");
startPopupTests(popupTests);
}, window);
// On Linux, the first menu opens when F10 is pressed, but on other platforms
// the menubar is focused but no menu is opened. This means that different events
// fire.
function pressF10Events()
{
return navigator.platform.indexOf("Linux") >= 0 ?
[ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu", "popupshowing filepopup", "DOMMenuItemActive item1", "popupshown filepopup"] :
[ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ];
}
function closeAfterF10Events(extraInactive)
{
if (navigator.platform.indexOf("Linux") >= 0) {
var events = [ "popuphiding filepopup", "popuphidden filepopup", "DOMMenuItemInactive item1",
"DOMMenuInactive filepopup", "DOMMenuBarInactive menubar",
"DOMMenuItemInactive filemenu" ];
if (extraInactive)
events.push("DOMMenuItemInactive filemenu");
return events;
}
return [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ];
}
var popupTests = [
{
testname: "press on menu",
events: [ "popupshowing filepopup", "DOMMenuBarActive menubar",
"DOMMenuItemActive filemenu", "popupshown filepopup" ],
test: function() { synthesizeMouse(document.getElementById("filemenu"), 8, 8, { }); },
result: function (testname) {
checkActive(gFilePopup, "", testname);
checkOpen("filemenu", testname);
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
// check that pressing cursor down while there is no selection
// highlights the first item
testname: "cursor down no selection",
events: [ "DOMMenuItemActive item1" ],
test: function() { sendKey("DOWN"); },
result: function(testname) { checkActive(gFilePopup, "item1", testname); }
},
{
// check that pressing cursor up wraps and highlights the last item
testname: "cursor up wrap",
events: [ "DOMMenuItemInactive item1", "DOMMenuItemActive item3" ],
test: function() { sendKey("UP"); },
result: function(testname) { checkActive(gFilePopup, "item3", testname); }
},
{
// check that pressing cursor down wraps and highlights the first item
testname: "cursor down wrap",
events: [ "DOMMenuItemInactive item3", "DOMMenuItemActive item1" ],
test: function() { sendKey("DOWN"); },
result: function(testname) { checkActive(gFilePopup, "item1", testname); }
},
{
// check that pressing cursor down highlights the second item
testname: "cursor down",
events: [ "DOMMenuItemInactive item1", "DOMMenuItemActive item2" ],
test: function() { sendKey("DOWN"); },
result: function(testname) { checkActive(gFilePopup, "item2", testname); }
},
{
// check that pressing cursor up highlights the second item
testname: "cursor up",
events: [ "DOMMenuItemInactive item2", "DOMMenuItemActive item1" ],
test: function() { sendKey("UP"); },
result: function(testname) { checkActive(gFilePopup, "item1", testname); }
},
{
// cursor right should skip the disabled menu and move to the edit menu
testname: "cursor right skip disabled",
events: function() {
var elist = [
// the file menu gets deactivated, the file menu gets hidden, then
// the edit menu is activated
"DOMMenuItemInactive filemenu", "DOMMenuItemActive editmenu",
"popuphiding filepopup", "popuphidden filepopup",
// the popupshowing event gets fired when showing the edit menu.
// The item from the file menu doesn't get deactivated until the
// next item needs to be selected
"popupshowing editpopup", "DOMMenuItemInactive item1",
// not sure why the menu inactivated event is firing so late
"DOMMenuInactive filepopup"
];
// finally, the first item is activated and popupshown is fired.
// On Windows, don't skip disabled items.
if (navigator.platform.indexOf("Win") == 0)
elist.push("DOMMenuItemActive cut");
else
elist.push("DOMMenuItemActive copy");
elist.push("popupshown editpopup");
return elist;
},
test: function() { sendKey("RIGHT"); },
result: function(testname) {
var expected = (navigator.platform.indexOf("Win") == 0) ? "cut" : "copy";
checkActive(document.getElementById("editpopup"), expected, testname);
checkClosed("filemenu", testname);
checkOpen("editmenu", testname);
is(document.getElementById("editmenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
// on Windows, a disabled item is selected, so pressing RETURN should close
// the menu but not fire a command event
testname: "enter on disabled",
events: function() {
if (navigator.platform.indexOf("Win") == 0)
return [ "popuphiding editpopup", "popuphidden editpopup",
"DOMMenuItemInactive cut", "DOMMenuInactive editpopup",
"DOMMenuBarInactive menubar",
"DOMMenuItemInactive editmenu", "DOMMenuItemInactive editmenu" ];
else
return [ "DOMMenuItemInactive copy", "DOMMenuInactive editpopup",
"DOMMenuBarInactive menubar",
"DOMMenuItemInactive editmenu", "DOMMenuItemInactive editmenu",
"command copy", "popuphiding editpopup", "popuphidden editpopup",
"DOMMenuItemInactive copy" ];
},
test: function() { sendKey("RETURN"); },
result: function(testname) {
checkClosed("editmenu", testname);
is(document.getElementById("editmenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
// pressing Alt + a key should open the corresponding menu
testname: "open with accelerator",
events: function() {
return [ "DOMMenuBarActive menubar",
"popupshowing viewpopup", "DOMMenuItemActive viewmenu",
"DOMMenuItemActive toolbar", "popupshown viewpopup" ];
},
test: function() { synthesizeKey("V", { altKey: true }); },
result: function(testname) {
checkOpen("viewmenu", testname);
is(document.getElementById("viewmenu").openedWithKey, true, testname + " openedWithKey");
}
},
{
// open the submenu with the cursor right key
testname: "open submenu with cursor right",
events: function() {
// on Windows, the disabled 'navigation' item can stll be highlihted
if (navigator.platform.indexOf("Win") == 0)
return [ "popupshowing toolbarpopup", "DOMMenuItemActive navigation",
"popupshown toolbarpopup" ];
else
return [ "popupshowing toolbarpopup", "popupshown toolbarpopup" ];
},
test: function() { sendKey("RIGHT"); },
result: function(testname) {
checkOpen("viewmenu", testname);
checkOpen("toolbar", testname);
}
},
{
// close the submenu with the cursor left key
testname: "close submenu with cursor left",
events: function() {
if (navigator.platform.indexOf("Win") == 0)
return [ "popuphiding toolbarpopup", "popuphidden toolbarpopup",
"DOMMenuItemInactive navigation", "DOMMenuInactive toolbarpopup",
"DOMMenuItemActive toolbar" ];
else
return [ "popuphiding toolbarpopup", "popuphidden toolbarpopup",
"DOMMenuInactive toolbarpopup",
"DOMMenuItemActive toolbar" ];
},
test: function() { sendKey("LEFT"); },
result: function(testname) {
checkOpen("viewmenu", testname);
checkClosed("toolbar", testname);
}
},
{
// open the submenu with the enter key
testname: "open submenu with enter",
events: function() {
// on Windows, the disabled 'navigation' item can stll be highlighted
if (navigator.platform.indexOf("Win") == 0)
return [ "popupshowing toolbarpopup", "DOMMenuItemActive navigation",
"popupshown toolbarpopup" ];
else
return [ "popupshowing toolbarpopup", "popupshown toolbarpopup" ];
},
test: function() { sendKey("RETURN"); },
result: function(testname) {
checkOpen("viewmenu", testname);
checkOpen("toolbar", testname);
},
},
{
// close the submenu with the escape key
testname: "close submenu with escape",
events: function() {
if (navigator.platform.indexOf("Win") == 0)
return [ "popuphiding toolbarpopup", "popuphidden toolbarpopup",
"DOMMenuItemInactive navigation", "DOMMenuInactive toolbarpopup",
"DOMMenuItemActive toolbar" ];
else
return [ "popuphiding toolbarpopup", "popuphidden toolbarpopup",
"DOMMenuInactive toolbarpopup",
"DOMMenuItemActive toolbar" ];
},
test: function() { sendKey("ESCAPE"); },
result: function(testname) {
checkOpen("viewmenu", testname);
checkClosed("toolbar", testname);
},
},
{
// open the submenu with the enter key again
testname: "open submenu with enter again",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: function() {
// on Windows, the disabled 'navigation' item can stll be highlighted
if (navigator.platform.indexOf("Win") == 0)
return [ "popupshowing toolbarpopup", "DOMMenuItemActive navigation",
"popupshown toolbarpopup" ];
else
return [ "popupshowing toolbarpopup", "popupshown toolbarpopup" ];
},
test: function() { sendKey("RETURN"); },
result: function(testname) {
checkOpen("viewmenu", testname);
checkOpen("toolbar", testname);
},
},
{
// while a submenu is open, switch to the next toplevel menu with the cursor right key
testname: "while a submenu is open, switch to the next menu with the cursor right",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "DOMMenuItemInactive viewmenu", "DOMMenuItemActive helpmenu",
"popuphiding toolbarpopup", "popuphidden toolbarpopup",
"popuphiding viewpopup", "popuphidden viewpopup",
"popupshowing helppopup", "DOMMenuItemInactive navigation",
"DOMMenuInactive toolbarpopup", "DOMMenuItemInactive toolbar",
"DOMMenuInactive viewpopup", "DOMMenuItemActive contents",
"popupshown helppopup" ],
test: function() { sendKey("RIGHT"); },
result: function(testname) {
checkOpen("helpmenu", testname);
checkClosed("toolbar", testname);
checkClosed("viewmenu", testname);
}
},
{
// close the main menu with the escape key
testname: "close menubar menu with escape",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "popuphiding helppopup", "popuphidden helppopup",
"DOMMenuItemInactive contents", "DOMMenuInactive helppopup",
"DOMMenuBarInactive menubar", "DOMMenuItemInactive helpmenu" ],
test: function() { sendKey("ESCAPE"); },
result: function(testname) { checkClosed("viewmenu", testname); },
},
{
// close the main menu with the escape key
testname: "close menubar menu with escape",
condition: function() { return (navigator.platform.indexOf("Win") != 0) },
events: [ "popuphiding viewpopup", "popuphidden viewpopup",
"DOMMenuItemInactive toolbar", "DOMMenuInactive viewpopup",
"DOMMenuBarInactive menubar",
"DOMMenuItemInactive viewmenu" ],
test: function() { sendKey("ESCAPE"); },
result: function(testname) { checkClosed("viewmenu", testname); },
},
{
// Pressing Alt should highlight the first menu but not open it,
// but it should be ignored if the alt keydown event is consumed.
testname: "alt shouldn't activate menubar if keydown event is consumed",
test: function() {
document.addEventListener("keydown", function (aEvent) {
document.removeEventListener("keydown", arguments.callee, true);
aEvent.preventDefault();
}, true);
sendKey("ALT");
},
result: function(testname) {
ok(!document.getElementById("filemenu").openedWithKey, testname);
checkClosed("filemenu", testname);
},
},
{
// Pressing Alt should highlight the first menu but not open it,
// but it should be ignored if the alt keyup event is consumed.
testname: "alt shouldn't activate menubar if keyup event is consumed",
test: function() {
document.addEventListener("keyup", function (aEvent) {
document.removeEventListener("keyup", arguments.callee, true);
aEvent.preventDefault();
}, true);
sendKey("ALT");
},
result: function(testname) {
ok(!document.getElementById("filemenu").openedWithKey, testname);
checkClosed("filemenu", testname);
},
},
{
// Pressing Alt should highlight the first menu but not open it.
testname: "alt to activate menubar",
events: [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ],
test: function() { sendKey("ALT"); },
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
testname: "cursor left on active menubar",
events: [ "DOMMenuItemInactive filemenu", "DOMMenuItemActive helpmenu" ],
test: function() { sendKey("LEFT"); },
result: function(testname) { checkClosed("helpmenu", testname); },
},
{
// pressing cursor right should select the previous menu but not open it
testname: "cursor right on active menubar",
events: [ "DOMMenuItemInactive helpmenu", "DOMMenuItemActive filemenu" ],
test: function() { sendKey("RIGHT"); },
result: function(testname) { checkClosed("filemenu", testname); },
},
{
// pressing a character should act as an accelerator and open the menu
testname: "accelerator on active menubar",
events: [ "popupshowing helppopup",
"DOMMenuItemInactive filemenu", "DOMMenuItemActive helpmenu",
"DOMMenuItemActive contents", "popupshown helppopup" ],
test: function() { sendChar("h"); },
result: function(testname) {
checkOpen("helpmenu", testname);
is(document.getElementById("helpmenu").openedWithKey, true, testname + " openedWithKey");
},
},
{
// check that pressing cursor up skips non menuitems
testname: "cursor up wrap",
events: [ "DOMMenuItemInactive contents", "DOMMenuItemActive about" ],
test: function() { sendKey("UP"); },
result: function(testname) { }
},
{
// check that pressing cursor down skips non menuitems
testname: "cursor down wrap",
events: [ "DOMMenuItemInactive about", "DOMMenuItemActive contents" ],
test: function() { sendKey("DOWN"); },
result: function(testname) { }
},
{
// check that pressing a menuitem's accelerator selects it
testname: "menuitem accelerator",
events: [ "DOMMenuItemInactive contents", "DOMMenuItemActive amenu",
"DOMMenuItemInactive amenu", "DOMMenuInactive helppopup",
"DOMMenuBarInactive menubar", "DOMMenuItemInactive helpmenu",
"DOMMenuItemInactive helpmenu",
"command amenu", "popuphiding helppopup", "popuphidden helppopup",
"DOMMenuItemInactive amenu",
],
test: function() { sendChar("m"); },
result: function(testname) { checkClosed("helpmenu", testname); }
},
{
// pressing F10 should highlight the first menu. On Linux, the menu is opened.
testname: "F10 to activate menubar",
events: pressF10Events(),
test: function() { sendKey("F10"); },
result: function(testname) {
is(document.getElementById("filemenu").openedWithKey, true, testname + " openedWithKey");
if (navigator.platform.indexOf("Linux") >= 0)
checkOpen("filemenu", testname);
else
checkClosed("filemenu", testname);
},
},
{
// pressing cursor left then down should open a menu
testname: "cursor down on menu",
events: (navigator.platform.indexOf("Linux") >= 0) ?
[ "DOMMenuItemInactive filemenu", "DOMMenuItemActive helpmenu",
// This is in a different order than the
// "accelerator on active menubar" because menus opened from a
// shortcut key are fired asynchronously
"popuphiding filepopup", "popuphidden filepopup",
"popupshowing helppopup", "DOMMenuItemInactive item1",
"DOMMenuItemActive item2", "DOMMenuItemInactive item2",
"DOMMenuInactive filepopup", "DOMMenuItemActive contents",
"popupshown helppopup" ] :
[ "popupshowing helppopup", "DOMMenuItemInactive filemenu",
"DOMMenuItemActive helpmenu",
// This is in a different order than the
// "accelerator on active menubar" because menus opened from a
// shortcut key are fired asynchronously
"DOMMenuItemActive contents", "popupshown helppopup" ],
test: function() { sendKey("LEFT"); sendKey("DOWN"); },
result: function(testname) {
is(document.getElementById("helpmenu").openedWithKey, true, testname + " openedWithKey");
}
},
{
// pressing a letter that doesn't correspond to an accelerator. The menu
// should not close because there is more than one item corresponding to
// that letter
testname: "menuitem with no accelerator",
events: [ "DOMMenuItemInactive contents", "DOMMenuItemActive one" ],
test: function() { sendChar("o"); },
result: function(testname) { checkOpen("helpmenu", testname); }
},
{
// pressing the letter again should select the next one that starts with
// that letter
testname: "menuitem with no accelerator again",
events: [ "DOMMenuItemInactive one", "DOMMenuItemActive only" ],
test: function() { sendChar("o"); },
result: function(testname) {
// 'only' is a menu but it should not be open
checkOpen("helpmenu", testname);
checkClosed("only", testname);
}
},
{
// pressing the letter again when the next item is disabled should still
// select the disabled item
testname: "menuitem with no accelerator disabled",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "DOMMenuItemInactive only", "DOMMenuItemActive other" ],
test: function() { sendChar("o"); },
result: function(testname) { }
},
{
// when only one menuitem starting with that letter exists, it should be
// selected and the menu closed
testname: "menuitem with no accelerator single",
events: function() {
var elist = [ "DOMMenuItemInactive other", "DOMMenuItemActive third",
"DOMMenuItemInactive third", "DOMMenuInactive helppopup",
"DOMMenuBarInactive menubar",
"DOMMenuItemInactive helpmenu",
"DOMMenuItemInactive helpmenu",
"command third", "popuphiding helppopup",
"popuphidden helppopup", "DOMMenuItemInactive third",
];
if (navigator.platform.indexOf("Win") == -1)
elist[0] = "DOMMenuItemInactive only";
return elist;
},
test: function() { sendChar("t"); },
result: function(testname) { checkClosed("helpmenu", testname); }
},
{
// pressing F10 should highlight the first menu but not open it
testname: "F10 to activate menubar again",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ],
test: function() { sendKey("F10"); },
result: function(testname) { checkClosed("filemenu", testname); },
},
{
// pressing an accelerator for a disabled item should deactivate the menubar
testname: "accelerator for disabled menu",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "DOMMenuItemInactive filemenu", "DOMMenuBarInactive menubar" ],
test: function() { sendChar("s"); },
result: function(testname) {
checkClosed("secretmenu", testname);
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
},
},
{
testname: "press on disabled menu",
test: function() {
synthesizeMouse(document.getElementById("secretmenu"), 8, 8, { });
},
result: function (testname) {
checkClosed("secretmenu", testname);
}
},
{
testname: "press on second menu with shift",
events: [ "popupshowing editpopup", "DOMMenuBarActive menubar",
"DOMMenuItemActive editmenu", "popupshown editpopup" ],
test: function() {
synthesizeMouse(document.getElementById("editmenu"), 8, 8, { shiftKey : true });
},
result: function (testname) {
checkOpen("editmenu", testname);
checkActive(document.getElementById("menubar"), "editmenu", testname);
}
},
{
testname: "press on disabled menuitem",
test: function() {
synthesizeMouse(document.getElementById("cut"), 8, 8, { });
},
result: function (testname) {
checkOpen("editmenu", testname);
}
},
{
testname: "press on menuitem",
events: [ "DOMMenuInactive editpopup",
"DOMMenuBarInactive menubar",
"DOMMenuItemInactive editmenu",
"DOMMenuItemInactive editmenu",
"command copy", "popuphiding editpopup", "popuphidden editpopup",
"DOMMenuItemInactive copy",
],
test: function() {
synthesizeMouse(document.getElementById("copy"), 8, 8, { });
},
result: function (testname) {
checkClosed("editmenu", testname);
}
},
{
// this test ensures that the menu can still be opened by clicking after selecting
// a menuitem from the menu. See bug 399350.
testname: "press on menu after menuitem selected",
events: [ "popupshowing editpopup", "DOMMenuBarActive menubar",
"DOMMenuItemActive editmenu", "popupshown editpopup" ],
test: function() { synthesizeMouse(document.getElementById("editmenu"), 8, 8, { }); },
result: function (testname) {
checkActive(document.getElementById("editpopup"), "", testname);
checkOpen("editmenu", testname);
}
},
{ // try selecting a different command
testname: "press on menuitem again",
events: [ "DOMMenuInactive editpopup",
"DOMMenuBarInactive menubar",
"DOMMenuItemInactive editmenu",
"DOMMenuItemInactive editmenu",
"command paste", "popuphiding editpopup", "popuphidden editpopup",
"DOMMenuItemInactive paste",
],
test: function() {
synthesizeMouse(document.getElementById("paste"), 8, 8, { });
},
result: function (testname) {
checkClosed("editmenu", testname);
}
},
{
testname: "F10 to activate menubar for tab deactivation",
events: pressF10Events(),
test: function() { sendKey("F10"); },
},
{
testname: "Deactivate menubar with tab key",
events: closeAfterF10Events(true),
test: function() { sendKey("TAB"); },
result: function(testname) {
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
testname: "F10 to activate menubar for escape deactivation",
events: pressF10Events(),
test: function() { sendKey("F10"); },
},
{
testname: "Deactivate menubar with escape key",
events: closeAfterF10Events(false),
test: function() { sendKey("ESCAPE"); },
result: function(testname) {
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
testname: "F10 to activate menubar for f10 deactivation",
events: pressF10Events(),
test: function() { sendKey("F10"); },
},
{
testname: "Deactivate menubar with f10 key",
events: closeAfterF10Events(true),
test: function() { sendKey("F10"); },
result: function(testname) {
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
testname: "F10 to activate menubar for alt deactivation",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ],
test: function() { sendKey("F10"); },
},
{
testname: "Deactivate menubar with alt key",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ],
test: function() { sendKey("ALT"); },
result: function(testname) {
is(document.getElementById("filemenu").openedWithKey, false, testname + " openedWithKey");
}
},
{
testname: "Don't activate menubar with mousedown during alt key auto-repeat",
test: function() {
synthesizeKey("VK_ALT", { type: "keydown" });
synthesizeMouse(document.getElementById("menubar"), 8, -30, { type: "mousedown", altKey: true });
synthesizeKey("VK_ALT", { type: "keydown" });
synthesizeMouse(document.getElementById("menubar"), 8, -30, { type: "mouseup", altKey: true });
synthesizeKey("VK_ALT", { type: "keydown" });
synthesizeKey("VK_ALT", { type: "keyup" });
},
result: function (testname) {
checkActive(document.getElementById("menubar"), "", testname);
}
},
{
testname: "Open menu and press alt key by itself - open menu",
events: [ "DOMMenuBarActive menubar",
"popupshowing filepopup", "DOMMenuItemActive filemenu",
"DOMMenuItemActive item1", "popupshown filepopup" ],
test: function() { synthesizeKey("F", { altKey: true }); },
result: function (testname) {
checkOpen("filemenu", testname);
}
},
{
testname: "Open menu and press alt key by itself - close menu",
events: [ "popuphiding filepopup", "popuphidden filepopup",
"DOMMenuItemInactive item1", "DOMMenuInactive filepopup",
"DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu",
"DOMMenuItemInactive filemenu" ],
test: function() {
synthesizeKey("VK_ALT", { });
},
result: function (testname) {
checkClosed("filemenu", testname);
}
},
// Fllowing 4 tests are a test of bug 616797, don't insert any new tests
// between them.
{
testname: "Open file menu by accelerator",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: function() {
return [ "DOMMenuBarActive menubar", "popupshowing filepopup",
"DOMMenuItemActive filemenu", "DOMMenuItemActive item1",
"popupshown filepopup" ];
},
test: function() {
synthesizeKey("VK_ALT", { type: "keydown" });
synthesizeKey("F", { altKey: true });
synthesizeKey("VK_ALT", { type: "keyup" });
}
},
{
testname: "Close file menu by click at outside of popup menu",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: function() {
return [ "popuphiding filepopup", "popuphidden filepopup",
"DOMMenuItemInactive item1", "DOMMenuInactive filepopup",
"DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu",
"DOMMenuItemInactive filemenu" ];
},
test: function() {
// XXX hidePopup() causes DOMMenuItemInactive event to be fired twice.
document.getElementById("filepopup").hidePopup();
}
},
{
testname: "Alt keydown set focus the menubar",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: function() {
return [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ];
},
test: function() {
sendKey("ALT");
},
result: function (testname) {
checkClosed("filemenu", testname);
}
},
{
testname: "unset focus the menubar",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: function() {
return [ "DOMMenuBarInactive menubar", "DOMMenuItemInactive filemenu" ];
},
test: function() {
sendKey("ALT");
}
},
// bug 625151
{
testname: "Alt key state before deactivating the window shouldn't prevent " +
"next Alt key handling",
condition: function() { return (navigator.platform.indexOf("Win") == 0) },
events: function() {
return [ "DOMMenuBarActive menubar", "DOMMenuItemActive filemenu" ];
},
test: function() {
synthesizeKey("VK_ALT", { type: "keydown" });
synthesizeKey("VK_TAB", { type: "keydown" }); // cancels the Alt key
var thisWindow = window;
var newWindow =
window.open("data:text/html,", "_blank", "width=100,height=100");
newWindow.addEventListener("focus", function () {
newWindow.removeEventListener("focus", arguments.callee, false);
thisWindow.addEventListener("focus", function () {
thisWindow.removeEventListener("focus", arguments.callee, false);
setTimeout(function () {
sendKey("ALT", thisWindow);
}, 0);
}, false);
newWindow.close();
thisWindow.focus();
}, false);
}
}
];
]]>
</script>
</window>