382 lines
11 KiB
HTML
382 lines
11 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<!--
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=565541
|
|
-->
|
|
<head>
|
|
<title>Test for Bug 565541</title>
|
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
</head>
|
|
<body>
|
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=565541">Mozilla Bug 565541</a>
|
|
<p id="display"></p>
|
|
<div id="content" style="display: none">
|
|
|
|
</div>
|
|
<pre id="test">
|
|
<script type="application/javascript">
|
|
|
|
/** Test for Bug 565541 **/
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
|
|
var previousX, previousY, previousWidth, previousHeight;
|
|
|
|
["innerWidth", "innerHeight", "screenX", "screenY", "outerWidth",
|
|
"outerHeight"].map(function(name) {
|
|
window[name+"Getter"] = Object.getOwnPropertyDescriptor(window, name).get;
|
|
});
|
|
|
|
function backValues()
|
|
{
|
|
previousX = window.screenX;
|
|
previousY = window.screenY;
|
|
previousWidth = window.innerWidth;
|
|
previousHeight = window.innerHeight;
|
|
}
|
|
|
|
function restoreValues()
|
|
{
|
|
window.screenX = previousX;
|
|
window.screenY = previousY;
|
|
window.innerWidth = previousWidth;
|
|
window.innerHeight = previousHeight;
|
|
}
|
|
|
|
function getNewWidth(aWindow)
|
|
{
|
|
return (aWindow.innerWidth > (screen.width / 2)) ? 100 : screen.width;
|
|
}
|
|
|
|
function getNewHeight(aWindow)
|
|
{
|
|
return (aWindow.innerHeight > (screen.height / 2)) ? 100 : screen.height;
|
|
}
|
|
|
|
function getNewX(aWindow)
|
|
{
|
|
return (aWindow.screenX > ((screen.width - aWindow.outerWidth) / 2))
|
|
? 0 : screen.width - aWindow.outerWidth;
|
|
}
|
|
|
|
function getNewY(aWindow)
|
|
{
|
|
return (aWindow.screenY > ((screen.height - aWindow.outerHeight) / 2))
|
|
? 0 : screen.height - aWindow.outerHeight;
|
|
}
|
|
|
|
/**
|
|
* hitEventLoop is called when we want to check something but we can't rely on
|
|
* an event or a specific number of event loop hiting.
|
|
* This method can be called by specifying a condition, a test (using SimpleTest
|
|
* API), how many times the event loop has to be hitten and what to call next.
|
|
* If times < 0, the event loop will be hitten as long as the condition isn't
|
|
* true or the test doesn't time out.
|
|
*/
|
|
function hitEventLoop(condition, test, times) {
|
|
return new Promise(function(resolve, reject) {
|
|
function doMagic() {
|
|
if (condition() || times == 0) {
|
|
test();
|
|
resolve();
|
|
return;
|
|
}
|
|
|
|
setTimeout(doMagic, 0, condition, test, times - 1);
|
|
}
|
|
|
|
doMagic();
|
|
});
|
|
}
|
|
|
|
function checkChangeIsDisabled(aWindow) {
|
|
// We want to check that nothing has changed. Having a high value would take
|
|
// too much time. Worse thing that could happen is random green.
|
|
var hits = 5;
|
|
|
|
function getProp(propName) {
|
|
return window[propName + "Getter"].call(aWindow);
|
|
}
|
|
|
|
var originalWidth = getProp("innerWidth");
|
|
var originalHeight = getProp("innerHeight");
|
|
|
|
var originalX = getProp("screenX");
|
|
var originalY = getProp("screenY");
|
|
|
|
var oWidth = getProp("outerWidth");
|
|
var oHeight = getProp("outerHeight");
|
|
|
|
function changeCondition() {
|
|
return aWindow.innerWidth != originalWidth ||
|
|
aWindow.innerHeight != originalHeight ||
|
|
aWindow.screenX != originalX || aWindow.screenY != originalY ||
|
|
aWindow.outerWidth != oWidth || aWindow.outerHeight != oHeight;
|
|
}
|
|
|
|
function changeTest() {
|
|
is(getProp("innerWidth"), originalWidth,
|
|
"Window width shouldn't have changed");
|
|
is(getProp("innerHeight"), originalHeight,
|
|
"Window height shouldn't have changed");
|
|
is(getProp("screenX"), originalX,
|
|
"Window x position shouldn't have changed");
|
|
is(getProp("screenY"), originalY,
|
|
"Window y position shouldn't have changed");
|
|
is(getProp("outerWidth"), oWidth,
|
|
"Window outerWidth shouldn't have changed");
|
|
is(getProp("outerHeight"), oHeight,
|
|
"Window outerHeight shouldn't have changed");
|
|
}
|
|
|
|
/**
|
|
* Size changes.
|
|
*/
|
|
var newWidth = getNewWidth(aWindow);
|
|
var newHeight = getNewHeight(aWindow);
|
|
|
|
aWindow.innerWidth = newWidth;
|
|
aWindow.innerHeight = newHeight;
|
|
|
|
aWindow.resizeTo(newWidth, newHeight);
|
|
|
|
aWindow.resizeBy(newWidth - aWindow.innerWidth,
|
|
newHeight - aWindow.innerHeight);
|
|
|
|
aWindow.sizeToContent();
|
|
|
|
/**
|
|
* Position checks.
|
|
*/
|
|
var newX = getNewX(aWindow);
|
|
var newY = getNewY(aWindow);
|
|
|
|
aWindow.screenX = newX;
|
|
aWindow.screenY = newY;
|
|
|
|
aWindow.moveTo(newX, newY);
|
|
|
|
aWindow.moveBy(newX - aWindow.screenX,
|
|
newY - aWindow.screenY);
|
|
|
|
/**
|
|
* Outer width/height checks.
|
|
*/
|
|
aWindow.outerWidth *= 2;
|
|
aWindow.outerHeight *= 2;
|
|
|
|
// We did a lot of changes. Now, we are going to wait and see if something
|
|
// happens.
|
|
// NOTE: if this happens to fail, you will have to check manually which
|
|
// operation has been accepted.
|
|
return hitEventLoop(changeCondition, changeTest, hits);
|
|
}
|
|
|
|
function checkChangeIsEnabled(aWindow, aNext)
|
|
{
|
|
// Something should happen. We are not going to go to the next test until
|
|
// it does.
|
|
var hits = -1;
|
|
|
|
var prevWidth;
|
|
var prevHeight;
|
|
|
|
var prevX;
|
|
var prevY;
|
|
|
|
var oWidth;
|
|
var oHeight;
|
|
|
|
function sizeChangeCondition() {
|
|
return aWindow.innerWidth != prevWidth && aWindow.innerHeight != prevHeight;
|
|
}
|
|
|
|
function sizeChangeTest() {
|
|
isnot(aWindow.innerWidth, prevWidth, "Window width should have changed");
|
|
isnot(aWindow.innerHeight, prevHeight, "Window height should have changed");
|
|
|
|
prevWidth = aWindow.innerWidth;
|
|
prevHeight = aWindow.innerHeight;
|
|
}
|
|
|
|
function posChangeCondition() {
|
|
// With GTK, sometimes, only one dimension changes.
|
|
if (navigator.platform.indexOf('Linux') != -1) {
|
|
return aWindow.screenX != prevX || aWindow.screenY != prevY;
|
|
}
|
|
return aWindow.screenX != prevX && aWindow.screenY != prevY;
|
|
}
|
|
|
|
function posChangeTest() {
|
|
// With GTK, sometimes, only one dimension changes.
|
|
if (navigator.platform.indexOf('Linux') != -1) {
|
|
// With GTK, sometimes, aWindow.screenX changes during two calls.
|
|
// So we call it once and save the returned value.
|
|
var x = aWindow.screenX;
|
|
var y = aWindow.screenY;
|
|
if (x != prevX) {
|
|
isnot(x, prevX, "Window x position should have changed");
|
|
}
|
|
if (y != prevY) {
|
|
isnot(y, prevY, "Window y position should have changed");
|
|
}
|
|
} else {
|
|
isnot(aWindow.screenX, prevX, "Window x position should have changed");
|
|
isnot(aWindow.screenY, prevY, "Window y position should have changed");
|
|
}
|
|
|
|
prevX = aWindow.screenX;
|
|
prevY = aWindow.screenY;
|
|
}
|
|
|
|
function outerChangeCondition() {
|
|
return aWindow.outerWidth != oWidth && aWindow.outerHeight != oHeight;
|
|
}
|
|
|
|
function outerChangeTest() {
|
|
isnot(aWindow.outerWidth, oWidth, "Window outerWidth should have changed");
|
|
isnot(aWindow.outerHeight, oHeight, "Window outerHeight should have changed");
|
|
}
|
|
|
|
/**
|
|
* Size checks.
|
|
*/
|
|
prevWidth = aWindow.innerWidth;
|
|
prevHeight = aWindow.innerHeight;
|
|
aWindow.innerWidth = getNewWidth(aWindow);
|
|
aWindow.innerHeight = getNewHeight(aWindow);
|
|
|
|
hitEventLoop(sizeChangeCondition, sizeChangeTest, hits)
|
|
.then(function() {
|
|
aWindow.resizeTo(getNewWidth(aWindow), getNewHeight(aWindow));
|
|
return hitEventLoop(sizeChangeCondition, sizeChangeTest, hits);
|
|
})
|
|
.then(function () {
|
|
aWindow.resizeBy(getNewWidth(aWindow) - aWindow.innerWidth,
|
|
getNewHeight(aWindow) - aWindow.innerHeight);
|
|
return hitEventLoop(sizeChangeCondition, sizeChangeTest, hits);
|
|
})
|
|
.then(function() {
|
|
aWindow.sizeToContent();
|
|
return hitEventLoop(sizeChangeCondition, sizeChangeTest, hits);
|
|
})
|
|
.then(function() {
|
|
/**
|
|
* Position checks.
|
|
*/
|
|
prevX = aWindow.screenX;
|
|
prevY = aWindow.screenY;
|
|
|
|
aWindow.screenX = getNewX(aWindow);
|
|
aWindow.screenY = getNewY(aWindow);
|
|
return hitEventLoop(posChangeCondition, posChangeTest, hits);
|
|
})
|
|
.then(function() {
|
|
prevX = aWindow.screenX;
|
|
prevY = aWindow.screenY;
|
|
|
|
aWindow.moveTo(getNewX(aWindow), getNewY(aWindow));
|
|
return hitEventLoop(posChangeCondition, posChangeTest, hits);
|
|
})
|
|
.then(function() {
|
|
prevX = aWindow.screenX;
|
|
prevY = aWindow.screenY;
|
|
|
|
aWindow.moveBy(getNewX(aWindow) - aWindow.screenX,
|
|
getNewY(aWindow) - aWindow.screenY);
|
|
return hitEventLoop(posChangeCondition, posChangeTest, hits);
|
|
})
|
|
.then(function() {
|
|
/**
|
|
* Outer width/height checks.
|
|
*/
|
|
oWidth = aWindow.outerWidth;
|
|
oHeight = aWindow.outerHeight;
|
|
|
|
aWindow.outerWidth = oWidth * 2;
|
|
aWindow.outerHeight = oHeight * 2;
|
|
return hitEventLoop(outerChangeCondition, outerChangeTest, hits);
|
|
})
|
|
.then(function() {
|
|
let origWidth = oWidth;
|
|
let origHeight = oHeight;
|
|
|
|
oWidth = aWindow.outerWidth;
|
|
oHeight = aWindow.outerHeight;
|
|
|
|
aWindow.outerWidth = origWidth;
|
|
aWindow.outerHeight = origHeight;
|
|
return hitEventLoop(outerChangeCondition, outerChangeTest, hits);
|
|
})
|
|
.then(aNext);
|
|
}
|
|
|
|
SpecialPowers.pushPrefEnv({
|
|
"set": [["dom.disable_window_move_resize", false],
|
|
["security.data_uri.block_toplevel_data_uri_navigations", false],]},
|
|
function() {
|
|
SimpleTest.waitForFocus(function() {
|
|
if (screen.width <= 200 || screen.height <= 200) {
|
|
todo(false, "The screen needs to be bigger than 200px*200px to run this test.");
|
|
SimpleTest.finish();
|
|
return;
|
|
}
|
|
|
|
backValues();
|
|
|
|
// The current window can't change it's own size and position.
|
|
checkChangeIsDisabled(window).then(function() {
|
|
// We create a window and check that it can change its own size and position.
|
|
// However, passing size/position parameters to window.open should work.
|
|
var w = window.open("data:text/html,<script>" +
|
|
"function check(next) {" +
|
|
" var is_range = function(aTest, aValue, aRange, aMsg) {" +
|
|
" window.opener.ok(aTest < aValue + aRange && aTest > aValue - aRange, aMsg);" +
|
|
" };" +
|
|
" is_range(window.innerWidth, 170, 5, 'parameter width should be taken into account');" +
|
|
" is_range(window.innerHeight, 170, 5, 'parameter height should be taken into account');" +
|
|
" is_range(window.screenX, 65, 5, 'parameter screenX should be taken into account');" +
|
|
" is_range(window.screenY, 65, 5, 'parameter screenY should be taken into account');" +
|
|
" window.opener.checkChangeIsEnabled(window, next);" +
|
|
"} <\/script>", '',
|
|
'width=170,height=170,screenX=65,screenY=65');
|
|
|
|
SimpleTest.waitForFocus(function() {
|
|
w.check(function() {
|
|
// The current window can change the size and position of the created one.
|
|
checkChangeIsEnabled(w, function() {
|
|
w.close();
|
|
|
|
// If we call window.open with an empty string as a third parameter,
|
|
// by default, it will create a new tab instead of a new window.
|
|
// In that case, we shouldn't allow the caller to change the size/position.
|
|
w = window.open("data:text/html,<script>" +
|
|
"function check(next) {" +
|
|
" window.opener.checkChangeIsDisabled(window).then(next);" +
|
|
"} <\/script>", '', '');
|
|
|
|
SimpleTest.waitForFocus(function() {
|
|
w.check(function() {
|
|
|
|
// The current window can't change the size and position of the new tab.
|
|
checkChangeIsDisabled(w).then(function() {
|
|
w.close();
|
|
|
|
restoreValues();
|
|
SimpleTest.finish();
|
|
});
|
|
});
|
|
}, w, false);
|
|
});
|
|
})
|
|
}, w, false);
|
|
});
|
|
});
|
|
}); // SpecialPowers.pushPrefEnv()
|
|
|
|
</script>
|
|
</pre>
|
|
</body>
|
|
</html>
|