blob: 6c98b4cd04d9a74059033cb756be7e74c5b48ec8 [file] [log] [blame] [edit]
<!DOCTYPE html>
<html>
<head>
<title>overflow_test.html</title>
<script src="test_bootstrap.js"></script>
<script type="text/javascript">
goog.require('bot.dom');
goog.require('bot.userAgent');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.testing.jsunit');
goog.require('goog.userAgent');
</script>
<script type="text/javascript">
var NONE = bot.dom.OverflowState.NONE;
var HIDDEN = bot.dom.OverflowState.HIDDEN;
var SCROLL = bot.dom.OverflowState.SCROLL;
function tearDown() {
document.documentElement.style.position = '';
}
function testElemHiddenByParent() {
// Column 1: position style of the element
// Column 2: position style of the element's parent
// Column 3: expected overflow state of the element
var positionStylesToOverflowStateTable = [
['absolute', 'absolute', HIDDEN],
['absolute', 'fixed', HIDDEN],
['absolute', 'relative', HIDDEN],
['absolute', 'static', NONE ],
['fixed' , 'absolute', NONE ],
['fixed' , 'fixed', NONE ],
['fixed' , 'relative', NONE ],
['fixed' , 'static', NONE ],
['relative', 'absolute', HIDDEN],
['relative', 'fixed', HIDDEN],
['relative', 'relative', HIDDEN],
['relative', 'static', HIDDEN],
['static' , 'absolute', HIDDEN],
['static' , 'fixed', HIDDEN],
['static' , 'relative', HIDDEN],
['static' , 'static', HIDDEN]
];
goog.array.forEach(positionStylesToOverflowStateTable, function(test) {
var position = test[0];
var parentPosition = test[1];
var expectedState = test[2];
var elem = document.createElement('DIV');
elem.style['position'] = position;
elem.innerHTML = position + ' in ' + parentPosition;
var parent = document.createElement('DIV');
parent.style['overflow'] = 'hidden';
parent.style['height'] = '0px';
parent.style['position'] = parentPosition;
parent.appendChild(elem);
document.body.appendChild(parent);
assertEquals('position: ' + position + '; parent position: ' +
parentPosition, expectedState, bot.dom.getOverflowState(elem));
});
}
function testElemHiddenByGrandparent() {
// Column 1: position style of the element
// Column 2: position style of the element's parent
// Column 3: position style of the element's grandparent
// Column 4: expected overflow state of the element
var positionStylesToOverflowStateTable = [
['absolute', 'absolute', 'absolute', HIDDEN],
['absolute', 'absolute', 'fixed' , HIDDEN],
['absolute', 'absolute', 'relative', HIDDEN],
['absolute', 'absolute', 'static' , NONE ],
['absolute', 'fixed' , 'absolute', NONE ],
['absolute', 'fixed' , 'fixed' , NONE ],
['absolute', 'fixed' , 'relative', NONE ],
['absolute', 'fixed' , 'static' , NONE ],
['absolute', 'relative', 'absolute', HIDDEN],
['absolute', 'relative', 'fixed' , HIDDEN],
['absolute', 'relative', 'relative', HIDDEN],
['absolute', 'relative', 'static' , HIDDEN],
['absolute', 'static' , 'absolute', HIDDEN],
['absolute', 'static' , 'fixed' , HIDDEN],
['absolute', 'static' , 'relative', HIDDEN],
['absolute', 'static' , 'static' , NONE ],
['fixed' , 'absolute', 'absolute', NONE ],
['fixed' , 'absolute', 'fixed' , NONE ],
['fixed' , 'absolute', 'relative', NONE ],
['fixed' , 'absolute', 'static' , NONE ],
['fixed' , 'fixed' , 'absolute', NONE ],
['fixed' , 'fixed' , 'fixed' , NONE ],
['fixed' , 'fixed' , 'relative', NONE ],
['fixed' , 'fixed' , 'static' , NONE ],
['fixed' , 'relative', 'absolute', NONE ],
['fixed' , 'relative', 'fixed' , NONE ],
['fixed' , 'relative', 'relative', NONE ],
['fixed' , 'relative', 'static' , NONE ],
['fixed' , 'static' , 'absolute', NONE ],
['fixed' , 'static' , 'fixed' , NONE ],
['fixed' , 'static' , 'relative', NONE ],
['fixed' , 'static' , 'static' , NONE ],
['relative', 'absolute', 'absolute', HIDDEN],
['relative', 'absolute', 'fixed' , HIDDEN],
['relative', 'absolute', 'relative', HIDDEN],
['relative', 'absolute', 'static' , NONE ],
['relative', 'fixed' , 'absolute', NONE ],
['relative', 'fixed' , 'fixed' , NONE ],
['relative', 'fixed' , 'relative', NONE ],
['relative', 'fixed' , 'static' , NONE ],
['relative', 'relative', 'absolute', HIDDEN],
['relative', 'relative', 'fixed' , HIDDEN],
['relative', 'relative', 'relative', HIDDEN],
['relative', 'relative', 'static' , HIDDEN],
['relative', 'static' , 'absolute', HIDDEN],
['relative', 'static' , 'fixed' , HIDDEN],
['relative', 'static' , 'relative', HIDDEN],
['relative', 'static' , 'static' , HIDDEN],
['static' , 'absolute', 'absolute', HIDDEN],
['static' , 'absolute', 'fixed' , HIDDEN],
['static' , 'absolute', 'relative', HIDDEN],
['static' , 'absolute', 'static' , NONE ],
['static' , 'fixed' , 'absolute', NONE ],
['static' , 'fixed' , 'fixed' , NONE ],
['static' , 'fixed' , 'relative', NONE ],
['static' , 'fixed' , 'static' , NONE ],
['static' , 'relative', 'absolute', HIDDEN],
['static' , 'relative', 'fixed' , HIDDEN],
['static' , 'relative', 'relative', HIDDEN],
['static' , 'relative', 'static' , HIDDEN],
['static' , 'static' , 'absolute', HIDDEN],
['static' , 'static' , 'fixed' , HIDDEN],
['static' , 'static' , 'relative', HIDDEN],
['static' , 'static' , 'static' , HIDDEN]
];
goog.array.forEach(positionStylesToOverflowStateTable, function(test) {
var position = test[0];
var parentPosition = test[1];
var grandparentPosition = test[2];
var expectedState = test[3];
var elem = document.createElement('DIV');
elem.style['position'] = position;
elem.innerHTML =
position + ' in ' + parentPosition + ' in ' + grandparentPosition;
var parent = document.createElement('DIV');
parent.style['position'] = parentPosition;
var grandparent = document.createElement('DIV');
grandparent.style['overflow'] = 'hidden';
grandparent.style['height'] = '0px';
grandparent.style['position'] = grandparentPosition;
parent.appendChild(elem);
grandparent.appendChild(parent);
document.body.appendChild(grandparent);
assertEquals('position: ' + position + '; parent position: ' +
parentPosition + '; grandparent position: ' + grandparentPosition,
expectedState, bot.dom.getOverflowState(elem));
});
}
function testChildOfScrollStyleHasScrollStatus() {
var e = document.getElementById('overflowScroll');
assertEquals(SCROLL, bot.dom.getOverflowState(e));
}
function testChildOfAutoStyleHasScrollStatus() {
var e = document.getElementById('overflowAuto');
assertEquals(SCROLL, bot.dom.getOverflowState(e));
}
function testChildOfScrollStyleInHiddenHasScrollStatusWhenParentNotInOverflow() {
var e = document.getElementById('overflowScrollInHiddenIsScroll');
assertEquals(SCROLL, bot.dom.getOverflowState(e));
}
function testChildOfScrollStyleInHiddenHasHiddenStatusWhenParentInOverflow() {
var e = document.getElementById('overflowScrollInHiddenIsHidden');
assertEquals(HIDDEN, bot.dom.getOverflowState(e));
}
function testOverflowOfHtmlAndBodyElements() {
if (bot.userAgent.ANDROID_PRE_GINGERBREAD) {
return;
}
// Column 1: overflow style of the <html> element
// Column 2: overflow style of the <body> element
// Column 3: expected overflow state of the overflowsBodyNotDoc element
// Column 4: expected overflow state of the overflowsBodyAndDoc element
var overflowStylesToOverflowStateTable = [
['auto' , 'auto' , SCROLL, SCROLL],
['auto' , 'hidden' , HIDDEN, HIDDEN],
['auto' , 'scroll' , SCROLL, SCROLL],
['auto' , 'visible', NONE , SCROLL],
['hidden' , 'auto' , SCROLL, SCROLL],
['hidden' , 'hidden' , HIDDEN, HIDDEN],
['hidden' , 'scroll' , SCROLL, SCROLL],
['hidden' , 'visible', NONE , HIDDEN],
['scroll' , 'auto' , SCROLL, SCROLL],
['scroll' , 'hidden' , HIDDEN, HIDDEN],
['scroll' , 'scroll' , SCROLL, SCROLL],
['scroll' , 'visible', NONE , SCROLL],
['visible', 'auto' , NONE , SCROLL],
['visible', 'hidden' , NONE , HIDDEN],
['visible', 'scroll' , NONE , SCROLL],
['visible', 'visible', NONE , SCROLL]
];
var iframe = document.getElementById('iframe');
var iframeDoc = goog.dom.getFrameContentDocument(iframe);
var overflowsNothing = iframeDoc.getElementById('overflowsNothing');
var overflowsBodyNotDoc = iframeDoc.getElementById('overflowsBodyNotDoc');
var overflowsBodyAndDoc = iframeDoc.getElementById('overflowsBodyAndDoc');
goog.array.forEach(overflowStylesToOverflowStateTable, function(test) {
var htmlOverflowStyle = test[0];
var bodyOverflowStyle = test[1];
var expectedOverflowsBodyNotDocState = test[2];
var expectedOverflowsBodyAndDocState = test[3];
iframeDoc.documentElement.style['overflow'] = htmlOverflowStyle;
iframeDoc.body.style['overflow'] = bodyOverflowStyle;
var msg = 'html overflow style: ' + htmlOverflowStyle + '; ' +
'body overflow style: ' + bodyOverflowStyle;
overflowsNothing.innerHTML = msg;
assertEquals(msg, NONE,
bot.dom.getOverflowState(overflowsNothing));
assertEquals(msg, expectedOverflowsBodyNotDocState,
bot.dom.getOverflowState(overflowsBodyNotDoc));
assertEquals(msg, expectedOverflowsBodyAndDocState,
bot.dom.getOverflowState(overflowsBodyAndDoc));
});
}
function testChildOfAnElementWithZeroHeightAndWidthAndOverflowHiddenIsNotVisible() {
var child = document.getElementById('bug5140-1-child');
assertEquals(HIDDEN, bot.dom.getOverflowState(child));
}
function testFarShiftedChildOfAnElementWitOverflowHiddenIsNotVisible() {
var child = document.getElementById('bug5140-2-child');
assertEquals(HIDDEN, bot.dom.getOverflowState(child));
}
function testNotFarShiftedChildOfAnElementWithOverflowHiddenIsVisible() {
var child = document.getElementById('bug5140-3-child');
assertEquals(NONE, bot.dom.getOverflowState(child));
}
function testFarShiftedGrandchildOfAnElementWitOverflowHiddenIsNotVisible() {
var child = document.getElementById('bug5140-4-grandchild');
assertEquals(HIDDEN, bot.dom.getOverflowState(child));
}
function testFloatingElemHiddenByBlockParent() {
var elem = document.getElementById('floatingInsideBlockParent');
assertEquals(HIDDEN, bot.dom.getOverflowState(elem));
}
function testFloatingElemNotHiddenByInlineParent() {
var elem = document.getElementById('floatingInsideInlineParent');
assertEquals(NONE, bot.dom.getOverflowState(elem));
}
function testNegativePositionInOverflowVisibleParent() {
// IE 6 does not support fixed-position elements properly.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
return;
}
// Column 1: position style of the element
// Column 2: position style of the element's parent
// Column 3: expected overflow state of element
var positionStylesToOverflowStateTable = [
['absolute', 'absolute', NONE ],
['absolute', 'fixed', NONE ],
['absolute', 'relative', NONE ],
['absolute', 'static', NONE ],
['fixed' , 'absolute', HIDDEN],
['fixed' , 'fixed', HIDDEN],
['fixed' , 'relative', HIDDEN],
['fixed' , 'static', HIDDEN],
['relative', 'absolute', NONE ],
['relative', 'fixed', NONE ],
['relative', 'relative', NONE ],
['relative', 'static', NONE ],
['static' , 'absolute', NONE ],
['static' , 'fixed', NONE ],
['static' , 'relative', NONE ],
['static' , 'static', NONE ]
];
var parentContainer = document.getElementById(
'negativePositionInOverflowVisible');
goog.array.forEach(positionStylesToOverflowStateTable, function(test) {
var position = test[0];
var parentPosition = test[1];
var expectedState = test[2];
var elem = document.createElement('DIV');
elem.style['position'] = position;
elem.style['height'] = '50px';
elem.style['width'] = '50px';
elem.style['left'] = '-100px';
elem.style['top'] = '-100px';
elem.innerHTML = position + ' in ' + parentPosition;
var parent = document.createElement('DIV');
parent.style['height'] = '50px';
parent.style['width'] = '50px';
parent.style['position'] = parentPosition;
parent.appendChild(elem);
parentContainer.appendChild(parent);
assertEquals('position: ' + position + '; parent position: ' +
parentPosition, expectedState, bot.dom.getOverflowState(elem));
});
}
function testNegativePositionNotInOverflowVisibleParent() {
// IE 6 does not support fixed-position elements properly.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
return;
}
// Column 1: position style of the element
// Column 2: position style of the element's parent
// Column 3: expected overflow state
var positionStylesToOverflowStateTable = [
['absolute', 'absolute', HIDDEN],
['absolute', 'fixed', HIDDEN],
['absolute', 'relative', HIDDEN],
['absolute', 'static', NONE ],
['fixed' , 'absolute', HIDDEN],
['fixed' , 'fixed', HIDDEN],
['fixed' , 'relative', HIDDEN],
['fixed' , 'static', HIDDEN],
['relative', 'absolute', HIDDEN],
['relative', 'fixed', HIDDEN],
['relative', 'relative', HIDDEN],
['relative', 'static', HIDDEN],
['static' , 'absolute', NONE ],
['static' , 'fixed', NONE ],
['static' , 'relative', NONE ],
['static' , 'static', NONE ]
];
var parentContainer = document.getElementById(
'negativePositionNotInOverflowVisible');
var nonVisibleOverflowStyles = ['auto', 'hidden', 'scroll'];
goog.array.forEach(positionStylesToOverflowStateTable, function(test) {
var position = test[0];
var parentPosition = test[1];
var expectedState = test[2];
var elem = document.createElement('DIV');
elem.style['position'] = position;
elem.style['height'] = '50px';
elem.style['width'] = '50px';
elem.style['left'] = '-100px';
elem.style['top'] = '-100px';
elem.innerHTML = position + ' in ' + parentPosition;
var parent = document.createElement('DIV');
parent.style['height'] = '50px';
parent.style['width'] = '50px';
parent.style['position'] = parentPosition;
parent.appendChild(elem);
parentContainer.appendChild(parent);
goog.array.forEach(nonVisibleOverflowStyles, function(parentOverflowStyle) {
parent.style['overflow'] = parentOverflowStyle;
assertEquals('position: ' + position + '; parent position: ' +
parentPosition, expectedState, bot.dom.getOverflowState(elem));
});
});
}
function testScrollingInAndOutOfView() {
var line1 = document.getElementById('line1');
var line5 = document.getElementById('line5');
assertEquals(NONE, bot.dom.getOverflowState(line1));
assertEquals(SCROLL, bot.dom.getOverflowState(line5));
line5.scrollIntoView();
assertEquals(SCROLL, bot.dom.getOverflowState(line1));
assertEquals(NONE, bot.dom.getOverflowState(line5));
line1.scrollIntoView();
assertEquals(NONE, bot.dom.getOverflowState(line1));
assertEquals(SCROLL, bot.dom.getOverflowState(line5));
}
function testInOverflowHiddenByTransform() {
// IE versions < 9 do not support CSS transform styles.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(9)) {
return;
}
var hiddenTransformX = document.getElementById('hidden-transformX');
assertEquals(HIDDEN, bot.dom.getOverflowState(hiddenTransformX));
var hiddenTransformY = document.getElementById('hidden-transformY');
assertEquals(HIDDEN, bot.dom.getOverflowState(hiddenTransformY));
}
function testOverflowStateOfRelativeCoordinate() {
// IE 6 does not support overflow state properly.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
return;
}
var elem = document.getElementById('halfHidden');
assertEquals(NONE, bot.dom.getOverflowState(elem,
new goog.math.Coordinate(1, 1)));
assertEquals(HIDDEN, bot.dom.getOverflowState(elem,
new goog.math.Coordinate(60, 60)));
}
function testOverflowStateOfRelativeRectangle() {
// IE 6 does not support overflow state properly.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
return;
}
var elem = document.getElementById('halfHidden');
assertEquals(NONE, bot.dom.getOverflowState(elem,
new goog.math.Rect(25, 25, 50, 50)));
assertEquals(HIDDEN, bot.dom.getOverflowState(elem,
new goog.math.Coordinate(60, 60, 50, 50)));
}
function testFixedPositionOffscreenIsHidden() {
// IE 6 does not support fixed-position elements properly.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
return;
}
var fixedOffscreen = document.getElementById('fixed-offscreen');
assertEquals(HIDDEN, bot.dom.getOverflowState(fixedOffscreen));
}
function testChildOfFixedTreatedAsFixed() {
// IE 6 does not support fixed-position elements properly.
if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
return;
}
var fixedParent = document.getElementById('fixed-parent');
assertEquals(NONE, bot.dom.getOverflowState(fixedParent));
var childOfFixed = document.getElementById('child-of-fixed');
assertEquals(HIDDEN, bot.dom.getOverflowState(childOfFixed));
}
function testElementHiddenByZeroSizedContainer() {
var elem = document.getElementById('hasZeroSizedContainer');
assertEquals(HIDDEN, bot.dom.getOverflowState(elem));
}
function testElementWithHtmlElementFixed() {
document.documentElement.style.position = 'fixed';
var elem = document.getElementById('line1');
assertEquals(NONE, bot.dom.getOverflowState(elem));
}
</script>
<style>
#hidden-transformX {
transform: translateX(-10000px);
-webkit-transform: translateX(-10000px);
-ms-transform: translateX(-10000px);
-o-transform: translateX(-10000px);
-moz-transform: translateX(-10000px);
}
#hidden-transformY {
transform: translateY(-10000px);
-webkit-transform: translateY(-10000px);
-ms-transform: translateY(-10000px);
-o-transform: translateY(-10000px);
-moz-transform: translateY(-10000px);
}
</style>
</head>
<body>
<div style="overflow:scroll; height:40px">
<div>scroll down to see element</div>
<br><br><br><br><br><br><br><br><br>
<div id="overflowScroll">in overflow scroll</div>
</div>
<div style="overflow:auto; height:40px">
<div>scroll down to see element</div>
<br><br><br><br><br><br><br><br><br>
<div id="overflowAuto">in overflow scroll</div>
</div>
<div style="overflow:hidden; height:40px;">
<div style="overflow:scroll; height:40px">
<div>scroll down to see element</div>
<br><br><br><br><br><br><br><br><br>
<div id="overflowScrollInHiddenIsScroll">in overflow scroll</div>
</div>
</div>
<div style="overflow:hidden; height:0px;">
<div style="overflow:scroll; height:40px">
<div>scroll down to see element</div>
<br><br><br><br><br><br><br><br><br>
<div id="overflowScrollInHiddenIsHidden">in overflow hidden</div>
</div>
</div>
<iframe src="testdata/overflow_hidden.html" id="iframe" width="75%" height="100"></iframe>
<div id="bug5140-1" style="overflow:hidden; height:0; width:0;">
<div id="bug5140-1-child" style="height:25px; width:25px;">.</div>
</div>
<div id="bug5140-2" style="overflow:hidden; height:50px; width:50px;">
<div id="bug5140-2-child" style="height:25px; width:25px; margin:50px; background-color:red;">.</div>
</div>
<div id="bug5140-3" style="overflow:hidden; height:50px; width:50px;">
<div id="bug5140-3-child" style="height:25px; width:25px; margin:49px; background-color:red;">.</div>
</div>
<div id="bug5140-4" style="overflow:hidden; height:50px; width:50px;">
<div id="bug5140-4-child" style="overflow:hidden; height:25px; width:25px; margin:50px; background-color:red;">
<div id="bug5140-4-grandchild">.</div>
</div>
</div>
<div style="overflow:hidden;height:0;width:0;">
<div id="floatingInsideBlockParent" style="float:left">floating inside block parent</div>
</div>
<span style="overflow:hidden;height:0;width:0;">
<div id="floatingInsideInlineParent" style="float:left">floating inside inline parent</div>
</span>
<div id="negativePositionInOverflowVisible" style="position:fixed; left:400px; top:110px"></div>
<div id="negativePositionNotInOverflowVisible" style="position:fixed; left:400px; top:150px"></div>
<ul style="overflow:auto; height:50px; width:80px; position:fixed; left:200px; top:200px">
<li id="line1">line1</li>
<li id="line2">line2</li>
<li id="line3">line3</li>
<li id="line4">line4</li>
<li id="line5">line5</li>
</ul>
<div id="hidden-transformX">will never be shown</div>
<div id="hidden-transformY">will never be shown</div>
<div style="position:fixed; left:0px; top:200px; width:100px; height:100px; overflow:hidden">
<div id="halfHidden" style="position:absolute; left:50px; top:50px; width:100px; height:100px">
half-visible, half-hidden
</div>
</div>
<div id="fixed-offscreen" style="position:fixed; left:10000px;top:0px">fixed offscreen</div>
<div id="fixed-parent" style="position:fixed; left:10px;top:10px">
<div id="child-of-fixed" style="position:absolute; left:10000px;top:0px">fixed offscreen</div>
</div>
<!-- div deliberately only has zero width but hidden in y dimension -->
<div style="height:25px;width:0px;position:absolute;overflow-y:hidden;">
<div id="hasZeroSizedContainer" style="position:absolute;height:100px;width:100px;">
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</div>
</div>
</body>
</html>