| // Copyright 2008 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| /** |
| * @fileoverview Unit tests for goog.position. |
| * |
| * @author eae@google.com (Emil A Eklund) |
| */ |
| |
| /** @suppress {extraProvide} */ |
| goog.provide('goog.positioningTest'); |
| |
| goog.require('goog.dom'); |
| goog.require('goog.dom.DomHelper'); |
| goog.require('goog.math.Box'); |
| goog.require('goog.math.Coordinate'); |
| goog.require('goog.math.Size'); |
| goog.require('goog.positioning'); |
| goog.require('goog.positioning.Corner'); |
| goog.require('goog.positioning.Overflow'); |
| goog.require('goog.positioning.OverflowStatus'); |
| goog.require('goog.style'); |
| goog.require('goog.testing.ExpectedFailures'); |
| goog.require('goog.testing.jsunit'); |
| goog.require('goog.userAgent'); |
| goog.require('goog.userAgent.product'); |
| |
| goog.setTestOnly('goog.positioningTest'); |
| |
| // Allow positions to be off by one in gecko as it reports scrolling |
| // offsets in steps of 2. Otherwise, allow for subpixel difference |
| // as seen in IE10+ |
| var ALLOWED_OFFSET = goog.userAgent.GECKO ? 1 : 0.1; |
| // Error bar for positions since some browsers are not super accurate |
| // in reporting them. |
| var EPSILON = 2; |
| |
| var expectedFailures = new goog.testing.ExpectedFailures(); |
| |
| var corner = goog.positioning.Corner; |
| var overflow = goog.positioning.Overflow; |
| var testArea; |
| |
| function setUp() { |
| window.scrollTo(0, 0); |
| |
| var viewportSize = goog.dom.getViewportSize(); |
| // Some tests need enough size viewport. |
| if (viewportSize.width < 600 || viewportSize.height < 600) { |
| window.moveTo(0, 0); |
| window.resizeTo(640, 640); |
| } |
| |
| testArea = goog.dom.getElement('test-area'); |
| } |
| |
| function tearDown() { |
| expectedFailures.handleTearDown(); |
| testArea.setAttribute('style', ''); |
| testArea.innerHTML = ''; |
| } |
| |
| |
| /** |
| * This is used to round pixel values on FF3 Mac. |
| */ |
| function assertRoundedEquals(a, b, c) { |
| function round(x) { |
| return goog.userAgent.GECKO && (goog.userAgent.MAC || goog.userAgent.X11) && |
| goog.userAgent.isVersionOrHigher('1.9') ? Math.round(x) : x; |
| } |
| if (arguments.length == 3) { |
| assertRoughlyEquals(a, round(b), round(c), ALLOWED_OFFSET); |
| } else { |
| assertRoughlyEquals(round(a), round(b), ALLOWED_OFFSET); |
| } |
| } |
| |
| function testPositionAtAnchorLeftToRight() { |
| var anchor = document.getElementById('anchor1'); |
| var popup = document.getElementById('popup1'); |
| |
| // Anchor top left to top left. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Left edge of popup should line up with left edge ' + |
| 'of anchor.', |
| anchorRect.left, |
| popupRect.left); |
| assertRoundedEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top); |
| |
| // Anchor top left to bottom left. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_LEFT, |
| popup, corner.TOP_LEFT); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Left edge of popup should line up with left edge ' + |
| 'of anchor.', |
| anchorRect.left, |
| popupRect.left); |
| assertRoundedEquals('Popup should be positioned just below the anchor.', |
| anchorRect.top + anchorRect.height, |
| popupRect.top); |
| |
| // Anchor top left to top right. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_RIGHT, |
| popup, corner.TOP_LEFT); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Popup should be positioned just right of the anchor.', |
| anchorRect.left + anchorRect.width, |
| popupRect.left); |
| assertRoundedEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top); |
| |
| // Anchor top right to bottom right. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_RIGHT, |
| popup, corner.TOP_RIGHT); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Right edge of popup should line up with right edge ' + |
| 'of anchor.', |
| anchorRect.left + anchorRect.width, |
| popupRect.left + popupRect.width); |
| assertRoundedEquals('Popup should be positioned just below the anchor.', |
| anchorRect.top + anchorRect.height, |
| popupRect.top); |
| |
| // Anchor top start to bottom start. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_START, |
| popup, corner.TOP_START); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Left edge of popup should line up with left edge ' + |
| 'of anchor.', |
| anchorRect.left, |
| popupRect.left); |
| assertRoundedEquals('Popup should be positioned just below the anchor.', |
| anchorRect.top + anchorRect.height, |
| popupRect.top); |
| } |
| |
| |
| function testPositionAtAnchorWithOffset() { |
| var anchor = document.getElementById('anchor1'); |
| var popup = document.getElementById('popup1'); |
| |
| // Anchor top left to top left with an offset moving the popup away from the |
| // anchor. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT, |
| newCoord(-15, -20)); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Left edge of popup should be fifteen pixels from ' + |
| 'anchor.', |
| anchorRect.left, |
| popupRect.left + 15); |
| assertRoundedEquals('Top edge of popup should be twenty pixels from anchor.', |
| anchorRect.top, |
| popupRect.top + 20); |
| |
| // Anchor top left to top left with an offset moving the popup towards the |
| // anchor. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT, |
| newCoord(3, 1)); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Left edge of popup should be three pixels right of ' + |
| 'the anchor\'s left edge', |
| anchorRect.left, |
| popupRect.left - 3); |
| assertRoundedEquals('Top edge of popup should be one pixel below of the ' + |
| 'anchor\'s top edge', |
| anchorRect.top, |
| popupRect.top - 1); |
| } |
| |
| |
| function testPositionAtAnchorOverflowLeftEdgeRightToLeft() { |
| var anchor = document.getElementById('anchor5'); |
| var popup = document.getElementById('popup5'); |
| |
| var status = goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.FAIL_X); |
| assertFalse('Positioning operation should have failed.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| |
| // Change overflow strategy to ADJUST. |
| status = goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.ADJUST_X); |
| |
| // Fails in Chrome because of infrastructure issues, temporarily disabled. |
| // See b/4274723. |
| expectedFailures.expectFailureFor(goog.userAgent.product.CHROME); |
| try { |
| assertTrue('Positioning operation should have been successful.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| assertTrue('Positioning operation should have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_X) != 0); |
| } catch (e) { |
| expectedFailures.handleException(e); |
| } |
| |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| var parentRect = goog.style.getBounds(anchor.parentNode); |
| assertTrue('Position should have been adjusted so that the left edge of ' + |
| 'the popup is left of the anchor but still within the bounding ' + |
| 'box of the parent container.', |
| anchorRect.left <= popupRect.left <= parentRect.left); |
| |
| } |
| |
| |
| function testPositionAtAnchorWithMargin() { |
| var anchor = document.getElementById('anchor1'); |
| var popup = document.getElementById('popup1'); |
| |
| // Anchor top left to top left. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT, undefined, |
| new goog.math.Box(1, 2, 3, 4)); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Left edge of popup should be four pixels from anchor.', |
| anchorRect.left, |
| popupRect.left - 4); |
| assertRoundedEquals('Top edge of popup should be one pixels from anchor.', |
| anchorRect.top, |
| popupRect.top - 1); |
| |
| // Anchor top right to bottom right. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_RIGHT, |
| popup, corner.TOP_RIGHT, undefined, |
| new goog.math.Box(1, 2, 3, 4)); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| |
| var visibleAnchorRect = goog.positioning.getVisiblePart_(anchor); |
| |
| assertRoundedEquals('Right edge of popup should line up with right edge ' + |
| 'of anchor.', |
| visibleAnchorRect.left + visibleAnchorRect.width, |
| popupRect.left + popupRect.width + 2); |
| |
| assertRoundedEquals('Popup should be positioned just below the anchor.', |
| visibleAnchorRect.top + visibleAnchorRect.height, |
| popupRect.top - 1); |
| |
| } |
| |
| |
| function testPositionAtAnchorRightToLeft() { |
| if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher('6')) { |
| // These tests fails with IE6. |
| // TODO(user): Investigate the reason. |
| return; |
| } |
| |
| var anchor = document.getElementById('anchor2'); |
| var popup = document.getElementById('popup2'); |
| |
| // Anchor top left to top left. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| |
| assertRoundedEquals('Left edge of popup should line up with left edge ' + |
| 'of anchor.', |
| anchorRect.left, |
| popupRect.left); |
| assertRoundedEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top); |
| |
| // Anchor top start to bottom start. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_START, |
| popup, corner.TOP_START); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Right edge of popup should line up with right edge ' + |
| 'of anchor.', |
| anchorRect.left + anchorRect.width, |
| popupRect.left + popupRect.width); |
| assertRoundedEquals('Popup should be positioned just below the anchor.', |
| anchorRect.top + anchorRect.height, |
| popupRect.top); |
| } |
| |
| function testPositionAtAnchorRightToLeftWithScroll() { |
| if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher('6')) { |
| // These tests fails with IE6. |
| // TODO(user): Investigate the reason. |
| return; |
| } |
| |
| var anchor = document.getElementById('anchor8'); |
| var popup = document.getElementById('popup8'); |
| |
| // Anchor top left to top left. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| |
| assertRoundedEquals('Left edge of popup should line up with left edge ' + |
| 'of anchor.', |
| anchorRect.left, |
| popupRect.left); |
| assertRoundedEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top); |
| |
| // Anchor top start to bottom start. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_START, |
| popup, corner.TOP_START); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| |
| var visibleAnchorRect = goog.positioning.getVisiblePart_(anchor); |
| var visibleAnchorBox = visibleAnchorRect.toBox(); |
| |
| assertRoundedEquals('Right edge of popup should line up with right edge ' + |
| 'of anchor.', |
| anchorRect.left + anchorRect.width, |
| popupRect.left + popupRect.width); |
| assertRoundedEquals('Popup should be positioned just below the anchor.', |
| visibleAnchorBox.bottom, |
| popupRect.top); |
| } |
| |
| function testPositionAtAnchorBodyViewport() { |
| var anchor = document.getElementById('anchor1'); |
| var popup = document.getElementById('popup3'); |
| |
| // Anchor top left to top left. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_LEFT); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| assertEquals('Left edge of popup should line up with left edge of anchor.', |
| anchorRect.left, |
| popupRect.left); |
| assertRoughlyEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top, |
| 1); |
| |
| // Anchor top start to bottom right. |
| goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_RIGHT, |
| popup, corner.TOP_RIGHT); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertEquals('Right edge of popup should line up with right edge of anchor.', |
| anchorRect.left + anchorRect.width, |
| popupRect.left + popupRect.width); |
| assertRoughlyEquals('Popup should be positioned just below the anchor.', |
| anchorRect.top + anchorRect.height, |
| popupRect.top, |
| 1); |
| |
| // Anchor top right to top left. |
| goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertEquals('Right edge of popup should line up with left edge of anchor.', |
| anchorRect.left, |
| popupRect.left + popupRect.width); |
| assertRoughlyEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top, |
| 1); |
| } |
| |
| function testPositionAtAnchorSpecificViewport() { |
| var anchor = document.getElementById('anchor1'); |
| var popup = document.getElementById('popup3'); |
| |
| // Anchor top right to top left within outerbox. |
| var status = goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.FAIL_X); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertTrue('Positioning operation should have been successful.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| assertTrue('X position should not have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_X) == 0); |
| assertTrue('Y position should not have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_Y) == 0); |
| assertEquals('Right edge of popup should line up with left edge of anchor.', |
| anchorRect.left, |
| popupRect.left + popupRect.width); |
| assertRoughlyEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top, |
| 1); |
| |
| // position again within box1. |
| var box = document.getElementById('box1'); |
| var viewport = goog.style.getBounds(box); |
| status = goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.FAIL_X, undefined, |
| viewport); |
| assertFalse('Positioning operation should have failed.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| |
| // Change overflow strategy to adjust. |
| status = goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.ADJUST_X, undefined, |
| viewport); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertTrue('Positioning operation should have been successful.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| assertFalse('X position should have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_X) == 0); |
| assertTrue('Y position should not have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_Y) == 0); |
| assertRoughlyEquals( |
| 'Left edge of popup should line up with left edge of viewport.', |
| viewport.left, popupRect.left, EPSILON); |
| assertRoughlyEquals('Popup should have the same y position as the anchor.', |
| anchorRect.top, |
| popupRect.top, |
| 1); |
| } |
| |
| function testPositionAtAnchorOutsideViewport() { |
| var anchor = document.getElementById('anchor4'); |
| var popup = document.getElementById('popup1'); |
| |
| var status = goog.positioning.positionAtAnchor(anchor, corner.TOP_LEFT, |
| popup, corner.TOP_RIGHT); |
| var anchorRect = goog.style.getBounds(anchor); |
| var popupRect = goog.style.getBounds(popup); |
| assertTrue('Positioning operation should have been successful.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| assertTrue('X position should not have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_X) == 0); |
| assertTrue('Y position should not have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_Y) == 0); |
| |
| assertEquals('Right edge of popup should line up with left edge of anchor.', |
| anchorRect.left, |
| popupRect.left + popupRect.width); |
| |
| // Change overflow strategy to fail. |
| status = goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_RIGHT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.FAIL_X); |
| assertFalse('Positioning operation should have failed.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| |
| // Change overflow strategy to adjust. |
| status = goog.positioning.positionAtAnchor(anchor, corner.BOTTOM_RIGHT, |
| popup, corner.TOP_RIGHT, |
| undefined, undefined, |
| overflow.ADJUST_X); |
| anchorRect = goog.style.getBounds(anchor); |
| popupRect = goog.style.getBounds(popup); |
| assertTrue('Positioning operation should have been successful.', |
| (status & goog.positioning.OverflowStatus.FAILED) == 0); |
| assertFalse('X position should have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_X) == 0); |
| assertTrue('Y position should not have been adjusted.', |
| (status & goog.positioning.OverflowStatus.ADJUSTED_Y) == 0); |
| assertRoughlyEquals( |
| 'Left edge of popup should line up with left edge of viewport.', |
| 0, popupRect.left, EPSILON); |
| assertEquals('Popup should be positioned just below the anchor.', |
| anchorRect.top + anchorRect.height, |
| popupRect.top); |
| } |
| |
| |
| function testAdjustForViewportFailIgnore() { |
| var f = goog.positioning.adjustForViewport_; |
| var viewport = new goog.math.Box(100, 200, 200, 100); |
| var overflow = goog.positioning.Overflow.IGNORE; |
| |
| var pos = newCoord(150, 150); |
| var size = newSize(50, 50); |
| assertEquals('Viewport overflow should be ignored.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(150, 150); |
| size = newSize(100, 50); |
| assertEquals('Viewport overflow should be ignored.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(50, 50); |
| size = newSize(50, 50); |
| assertEquals('Viewport overflow should be ignored.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| } |
| |
| |
| function testAdjustForViewportFailXY() { |
| var f = goog.positioning.adjustForViewport_; |
| var viewport = new goog.math.Box(100, 200, 200, 100); |
| var overflow = goog.positioning.Overflow.FAIL_X | |
| goog.positioning.Overflow.FAIL_Y; |
| |
| var pos = newCoord(150, 150); |
| var size = newSize(50, 50); |
| assertEquals('Element should not overflow viewport.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(150, 150); |
| size = newSize(100, 50); |
| assertEquals('Element should overflow the right edge of viewport.', |
| goog.positioning.OverflowStatus.FAILED_RIGHT, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(150, 150); |
| size = newSize(50, 100); |
| assertEquals('Element should overflow the bottom edge of viewport.', |
| goog.positioning.OverflowStatus.FAILED_BOTTOM, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(50, 150); |
| size = newSize(50, 50); |
| assertEquals('Element should overflow the left edge of viewport.', |
| goog.positioning.OverflowStatus.FAILED_LEFT, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(150, 50); |
| size = newSize(50, 50); |
| assertEquals('Element should overflow the top edge of viewport.', |
| goog.positioning.OverflowStatus.FAILED_TOP, |
| f(pos, size, viewport, overflow)); |
| |
| pos = newCoord(50, 50); |
| size = newSize(50, 50); |
| assertEquals('Element should overflow the left & top edges of viewport.', |
| goog.positioning.OverflowStatus.FAILED_LEFT | |
| goog.positioning.OverflowStatus.FAILED_TOP, |
| f(pos, size, viewport, overflow)); |
| } |
| |
| |
| function testAdjustForViewportAdjustXFailY() { |
| var f = goog.positioning.adjustForViewport_; |
| var viewport = new goog.math.Box(100, 200, 200, 100); |
| var overflow = goog.positioning.Overflow.ADJUST_X | |
| goog.positioning.Overflow.FAIL_Y; |
| |
| var pos = newCoord(150, 150); |
| var size = newSize(50, 50); |
| assertEquals('Element should not overflow viewport.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| assertEquals('X Position should not have been changed.', 150, pos.x); |
| assertEquals('Y Position should not have been changed.', 150, pos.y); |
| |
| pos = newCoord(150, 150); |
| size = newSize(100, 50); |
| assertEquals('Element position should be adjusted not to overflow right ' + |
| 'edge of viewport.', |
| goog.positioning.OverflowStatus.ADJUSTED_X, |
| f(pos, size, viewport, overflow)); |
| assertEquals('X Position should be adjusted to 100.', 100, pos.x); |
| assertEquals('Y Position should not have been changed.', 150, pos.y); |
| |
| pos = newCoord(50, 150); |
| size = newSize(100, 50); |
| assertEquals('Element position should be adjusted not to overflow left ' + |
| 'edge of viewport.', |
| goog.positioning.OverflowStatus.ADJUSTED_X, |
| f(pos, size, viewport, overflow)); |
| assertEquals('X Position should be adjusted to 100.', 100, pos.x); |
| assertEquals('Y Position should not have been changed.', 150, pos.y); |
| |
| |
| pos = newCoord(50, 50); |
| size = newSize(100, 50); |
| assertEquals('Element position should be adjusted not to overflow left ' + |
| 'edge of viewport, should overflow bottom edge.', |
| goog.positioning.OverflowStatus.ADJUSTED_X | |
| goog.positioning.OverflowStatus.FAILED_TOP, |
| f(pos, size, viewport, overflow)); |
| assertEquals('X Position should be adjusted to 100.', 100, pos.x); |
| assertEquals('Y Position should not have been changed.', 50, pos.y); |
| } |
| |
| |
| function testAdjustForViewportResizeHeight() { |
| var f = goog.positioning.adjustForViewport_; |
| var viewport = new goog.math.Box(0, 200, 200, 0); |
| var overflow = goog.positioning.Overflow.RESIZE_HEIGHT; |
| |
| var pos = newCoord(150, 150); |
| var size = newSize(25, 100); |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Height should be resized to 50.', |
| 50, size.height); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var pos = newCoord(0, 0); |
| var size = newSize(50, 250); |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Height should be resized to 200.', |
| 200, size.height); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var pos = newCoord(0, -50); |
| var size = newSize(50, 240); |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Height should be resized to 190.', |
| 190, size.height); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var pos = newCoord(0, -50); |
| var size = newSize(50, 300); |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Height should be resized to 200.', |
| 200, size.height); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| pos = newCoord(150, 150); |
| size = newSize(50, 50); |
| assertEquals('No Viewport overflow.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var offsetViewport = new goog.math.Box(100, 200, 300, 0); |
| var pos = newCoord(0, 50); |
| var size = newSize(50, 240); |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED, |
| f(pos, size, offsetViewport, overflow)); |
| assertEquals('Height should be resized to 190.', |
| 190, size.height); |
| assertTrue('Output box is within viewport', |
| offsetViewport.contains(new goog.math.Box(pos.y, |
| pos.x + size.width, |
| pos.y + size.height, |
| pos.x))); |
| } |
| |
| |
| |
| function testAdjustForViewportResizeWidth() { |
| var f = goog.positioning.adjustForViewport_; |
| var viewport = new goog.math.Box(0, 200, 200, 0); |
| var overflow = goog.positioning.Overflow.RESIZE_WIDTH; |
| |
| var pos = newCoord(150, 150); |
| var size = newSize(100, 25); |
| assertEquals('Viewport width should be resized.', |
| goog.positioning.OverflowStatus.WIDTH_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Width should be resized to 50.', |
| 50, size.width); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var pos = newCoord(0, 0); |
| var size = newSize(250, 50); |
| assertEquals('Viewport width should be resized.', |
| goog.positioning.OverflowStatus.WIDTH_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Width should be resized to 200.', |
| 200, size.width); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var pos = newCoord(-50, 0); |
| var size = newSize(240, 50); |
| assertEquals('Viewport width should be resized.', |
| goog.positioning.OverflowStatus.WIDTH_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Width should be resized to 190.', |
| 190, size.width); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var pos = newCoord(-50, 0); |
| var size = newSize(300, 50); |
| assertEquals('Viewport width should be resized.', |
| goog.positioning.OverflowStatus.WIDTH_ADJUSTED, |
| f(pos, size, viewport, overflow)); |
| assertEquals('Width should be resized to 200.', |
| 200, size.width); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| pos = newCoord(150, 150); |
| size = newSize(50, 50); |
| assertEquals('No Viewport overflow.', |
| goog.positioning.OverflowStatus.NONE, |
| f(pos, size, viewport, overflow)); |
| assertTrue('Output box is within viewport', |
| viewport.contains(new goog.math.Box(pos.y, pos.x + size.width, |
| pos.y + size.height, pos.x))); |
| |
| var offsetViewport = new goog.math.Box(0, 300, 200, 100); |
| var pos = newCoord(50, 0); |
| var size = newSize(240, 50); |
| assertEquals('Viewport width should be resized.', |
| goog.positioning.OverflowStatus.WIDTH_ADJUSTED, |
| f(pos, size, offsetViewport, overflow)); |
| assertEquals('Width should be resized to 190.', |
| 190, size.width); |
| assertTrue('Output box is within viewport', |
| offsetViewport.contains(new goog.math.Box(pos.y, |
| pos.x + size.width, |
| pos.y + size.height, |
| pos.x))); |
| } |
| |
| |
| function testPositionAtAnchorWithResizeHeight() { |
| var anchor = document.getElementById('anchor9'); |
| var popup = document.getElementById('popup9'); |
| var box = document.getElementById('box9'); |
| var viewport = goog.style.getBounds(box); |
| |
| var status = goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_START, popup, corner.TOP_START, |
| new goog.math.Coordinate(0, -20), null, |
| goog.positioning.Overflow.RESIZE_HEIGHT, null, |
| viewport.toBox()); |
| assertEquals('Status should be HEIGHT_ADJUSTED.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED, status); |
| |
| var TOLERANCE = 0.1; |
| // Adjust the viewport to allow some tolerance for subpixel positioning, |
| // this is required for this test to pass on IE10,11 |
| viewport.top -= TOLERANCE; |
| viewport.left -= TOLERANCE; |
| |
| assertTrue('Popup ' + goog.style.getBounds(popup) + |
| ' not is within viewport' + viewport, |
| viewport.contains(goog.style.getBounds(popup))); |
| } |
| |
| |
| function testPositionAtCoordinateResizeHeight() { |
| var f = goog.positioning.positionAtCoordinate; |
| var viewport = new goog.math.Box(0, 50, 50, 0); |
| var overflow = goog.positioning.Overflow.RESIZE_HEIGHT | |
| goog.positioning.Overflow.ADJUST_Y; |
| var popup = document.getElementById('popup1'); |
| var corner = goog.positioning.Corner.BOTTOM_LEFT; |
| |
| var pos = newCoord(100, 100); |
| |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED | |
| goog.positioning.OverflowStatus.ADJUSTED_Y, |
| f(pos, popup, corner, undefined, viewport, overflow)); |
| var bounds = goog.style.getSize(popup); |
| assertEquals('Height should be resized to the size of the viewport.', |
| 50, bounds.height); |
| } |
| |
| |
| function testGetPositionAtCoordinateResizeHeight() { |
| var f = goog.positioning.getPositionAtCoordinate; |
| var viewport = new goog.math.Box(0, 50, 50, 0); |
| var overflow = goog.positioning.Overflow.RESIZE_HEIGHT | |
| goog.positioning.Overflow.ADJUST_Y; |
| var popup = document.getElementById('popup1'); |
| var corner = goog.positioning.Corner.BOTTOM_LEFT; |
| |
| var pos = newCoord(100, 100); |
| var size = goog.style.getSize(popup); |
| |
| var result = f(pos, size, corner, undefined, viewport, overflow); |
| assertEquals('Viewport height should be resized.', |
| goog.positioning.OverflowStatus.HEIGHT_ADJUSTED | |
| goog.positioning.OverflowStatus.ADJUSTED_Y, |
| result.status); |
| assertEquals('Height should be resized to the size of the viewport.', |
| 50, result.rect.height); |
| } |
| |
| |
| function testGetEffectiveCornerLeftToRight() { |
| var f = goog.positioning.getEffectiveCorner; |
| var el = document.getElementById('ltr'); |
| |
| assertEquals('TOP_LEFT should be unchanged for ltr.', |
| corner.TOP_LEFT, |
| f(el, corner.TOP_LEFT)); |
| assertEquals('TOP_RIGHT should be unchanged for ltr.', |
| corner.TOP_RIGHT, |
| f(el, corner.TOP_RIGHT)); |
| assertEquals('BOTTOM_LEFT should be unchanged for ltr.', |
| corner.BOTTOM_LEFT, |
| f(el, corner.BOTTOM_LEFT)); |
| assertEquals('BOTTOM_RIGHT should be unchanged for ltr.', |
| corner.BOTTOM_RIGHT, |
| f(el, corner.BOTTOM_RIGHT)); |
| |
| assertEquals('TOP_START should be TOP_LEFT for ltr.', |
| corner.TOP_LEFT, |
| f(el, corner.TOP_START)); |
| assertEquals('TOP_END should be TOP_RIGHT for ltr.', |
| corner.TOP_RIGHT, |
| f(el, corner.TOP_END)); |
| assertEquals('BOTTOM_START should be BOTTOM_LEFT for ltr.', |
| corner.BOTTOM_LEFT, |
| f(el, corner.BOTTOM_START)); |
| assertEquals('BOTTOM_END should be BOTTOM_RIGHT for ltr.', |
| corner.BOTTOM_RIGHT, |
| f(el, corner.BOTTOM_END)); |
| } |
| |
| |
| function testGetEffectiveCornerRightToLeft() { |
| var f = goog.positioning.getEffectiveCorner; |
| var el = document.getElementById('rtl'); |
| |
| assertEquals('TOP_LEFT should be unchanged for rtl.', |
| corner.TOP_LEFT, |
| f(el, corner.TOP_LEFT)); |
| assertEquals('TOP_RIGHT should be unchanged for rtl.', |
| corner.TOP_RIGHT, |
| f(el, corner.TOP_RIGHT)); |
| assertEquals('BOTTOM_LEFT should be unchanged for rtl.', |
| corner.BOTTOM_LEFT, |
| f(el, corner.BOTTOM_LEFT)); |
| assertEquals('BOTTOM_RIGHT should be unchanged for rtl.', |
| corner.BOTTOM_RIGHT, |
| f(el, corner.BOTTOM_RIGHT)); |
| |
| assertEquals('TOP_START should be TOP_RIGHT for rtl.', |
| corner.TOP_RIGHT, |
| f(el, corner.TOP_START)); |
| assertEquals('TOP_END should be TOP_LEFT for rtl.', |
| corner.TOP_LEFT, |
| f(el, corner.TOP_END)); |
| assertEquals('BOTTOM_START should be BOTTOM_RIGHT for rtl.', |
| corner.BOTTOM_RIGHT, |
| f(el, corner.BOTTOM_START)); |
| assertEquals('BOTTOM_END should be BOTTOM_LEFT for rtl.', |
| corner.BOTTOM_LEFT, |
| f(el, corner.BOTTOM_END)); |
| } |
| |
| |
| function testFlipCornerHorizontal() { |
| var f = goog.positioning.flipCornerHorizontal; |
| |
| assertEquals('TOP_LEFT should be flipped to TOP_RIGHT.', |
| corner.TOP_RIGHT, |
| f(corner.TOP_LEFT)); |
| assertEquals('TOP_RIGHT should be flipped to TOP_LEFT.', |
| corner.TOP_LEFT, |
| f(corner.TOP_RIGHT)); |
| assertEquals('BOTTOM_LEFT should be flipped to BOTTOM_RIGHT.', |
| corner.BOTTOM_RIGHT, |
| f(corner.BOTTOM_LEFT)); |
| assertEquals('BOTTOM_RIGHT should be flipped to BOTTOM_LEFT.', |
| corner.BOTTOM_LEFT, |
| f(corner.BOTTOM_RIGHT)); |
| |
| assertEquals('TOP_START should be flipped to TOP_END.', |
| corner.TOP_END, |
| f(corner.TOP_START)); |
| assertEquals('TOP_END should be flipped to TOP_START.', |
| corner.TOP_START, |
| f(corner.TOP_END)); |
| assertEquals('BOTTOM_START should be flipped to BOTTOM_END.', |
| corner.BOTTOM_END, |
| f(corner.BOTTOM_START)); |
| assertEquals('BOTTOM_END should be flipped to BOTTOM_START.', |
| corner.BOTTOM_START, |
| f(corner.BOTTOM_END)); |
| } |
| |
| |
| function testFlipCornerVertical() { |
| var f = goog.positioning.flipCornerVertical; |
| |
| assertEquals('TOP_LEFT should be flipped to BOTTOM_LEFT.', |
| corner.BOTTOM_LEFT, |
| f(corner.TOP_LEFT)); |
| assertEquals('TOP_RIGHT should be flipped to BOTTOM_RIGHT.', |
| corner.BOTTOM_RIGHT, |
| f(corner.TOP_RIGHT)); |
| assertEquals('BOTTOM_LEFT should be flipped to TOP_LEFT.', |
| corner.TOP_LEFT, |
| f(corner.BOTTOM_LEFT)); |
| assertEquals('BOTTOM_RIGHT should be flipped to TOP_RIGHT.', |
| corner.TOP_RIGHT, |
| f(corner.BOTTOM_RIGHT)); |
| |
| assertEquals('TOP_START should be flipped to BOTTOM_START.', |
| corner.BOTTOM_START, |
| f(corner.TOP_START)); |
| assertEquals('TOP_END should be flipped to BOTTOM_END.', |
| corner.BOTTOM_END, |
| f(corner.TOP_END)); |
| assertEquals('BOTTOM_START should be flipped to TOP_START.', |
| corner.TOP_START, |
| f(corner.BOTTOM_START)); |
| assertEquals('BOTTOM_END should be flipped to TOP_END.', |
| corner.TOP_END, |
| f(corner.BOTTOM_END)); |
| } |
| |
| |
| function testFlipCorner() { |
| var f = goog.positioning.flipCorner; |
| |
| assertEquals('TOP_LEFT should be flipped to BOTTOM_RIGHT.', |
| corner.BOTTOM_RIGHT, |
| f(corner.TOP_LEFT)); |
| assertEquals('TOP_RIGHT should be flipped to BOTTOM_LEFT.', |
| corner.BOTTOM_LEFT, |
| f(corner.TOP_RIGHT)); |
| assertEquals('BOTTOM_LEFT should be flipped to TOP_RIGHT.', |
| corner.TOP_RIGHT, |
| f(corner.BOTTOM_LEFT)); |
| assertEquals('BOTTOM_RIGHT should be flipped to TOP_LEFT.', |
| corner.TOP_LEFT, |
| f(corner.BOTTOM_RIGHT)); |
| |
| assertEquals('TOP_START should be flipped to BOTTOM_END.', |
| corner.BOTTOM_END, |
| f(corner.TOP_START)); |
| assertEquals('TOP_END should be flipped to BOTTOM_START.', |
| corner.BOTTOM_START, |
| f(corner.TOP_END)); |
| assertEquals('BOTTOM_START should be flipped to TOP_END.', |
| corner.TOP_END, |
| f(corner.BOTTOM_START)); |
| assertEquals('BOTTOM_END should be flipped to TOP_START.', |
| corner.TOP_START, |
| f(corner.BOTTOM_END)); |
| } |
| |
| function testPositionAtAnchorFrameViewportStandard() { |
| var iframe = document.getElementById('iframe-standard'); |
| var iframeDoc = goog.dom.getFrameContentDocument(iframe); |
| assertTrue(new goog.dom.DomHelper(iframeDoc).isCss1CompatMode()); |
| |
| new goog.dom.DomHelper(iframeDoc).getDocumentScrollElement().scrollTop = 100; |
| var anchor = iframeDoc.getElementById('anchor1'); |
| var popup = document.getElementById('popup6'); |
| |
| var status = goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_RIGHT, popup, corner.BOTTOM_RIGHT); |
| var iframeRect = goog.style.getBounds(iframe); |
| var popupRect = goog.style.getBounds(popup); |
| assertEquals('Status should not have any ADJUSTED and FAILED.', |
| goog.positioning.OverflowStatus.NONE, status); |
| assertRoundedEquals('Popup should be positioned just above the iframe, ' + |
| 'not above the anchor element inside the iframe', |
| iframeRect.top, |
| popupRect.top + popupRect.height); |
| } |
| |
| function testPositionAtAnchorFrameViewportQuirk() { |
| var iframe = document.getElementById('iframe-quirk'); |
| var iframeDoc = goog.dom.getFrameContentDocument(iframe); |
| assertFalse(new goog.dom.DomHelper(iframeDoc).isCss1CompatMode()); |
| |
| window.scrollTo(0, 100); |
| new goog.dom.DomHelper(iframeDoc).getDocumentScrollElement().scrollTop = 100; |
| var anchor = iframeDoc.getElementById('anchor1'); |
| var popup = document.getElementById('popup6'); |
| |
| var status = goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_RIGHT, popup, corner.BOTTOM_RIGHT); |
| var iframeRect = goog.style.getBounds(iframe); |
| var popupRect = goog.style.getBounds(popup); |
| assertEquals('Status should not have any ADJUSTED and FAILED.', |
| goog.positioning.OverflowStatus.NONE, status); |
| assertRoundedEquals('Popup should be positioned just above the iframe, ' + |
| 'not above the anchor element inside the iframe', |
| iframeRect.top, |
| popupRect.top + popupRect.height); |
| } |
| |
| function testPositionAtAnchorFrameViewportWithPopupInScroller() { |
| var iframe = document.getElementById('iframe-standard'); |
| var iframeDoc = goog.dom.getFrameContentDocument(iframe); |
| |
| new goog.dom.DomHelper(iframeDoc).getDocumentScrollElement().scrollTop = 100; |
| var anchor = iframeDoc.getElementById('anchor1'); |
| var popup = document.getElementById('popup7'); |
| popup.offsetParent.scrollTop = 50; |
| |
| var status = goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_RIGHT, popup, corner.BOTTOM_RIGHT); |
| var iframeRect = goog.style.getBounds(iframe); |
| var popupRect = goog.style.getBounds(popup); |
| assertEquals('Status should not have any ADJUSTED and FAILED.', |
| goog.positioning.OverflowStatus.NONE, status); |
| assertRoughlyEquals('Popup should be positioned just above the iframe, ' + |
| 'not above the anchor element inside the iframe', |
| iframeRect.top, |
| popupRect.top + popupRect.height, |
| ALLOWED_OFFSET); |
| } |
| |
| function testPositionAtAnchorNestedFrames() { |
| var outerIframe = document.getElementById('nested-outer'); |
| var outerDoc = goog.dom.getFrameContentDocument(outerIframe); |
| var popup = outerDoc.getElementById('popup1'); |
| var innerIframe = outerDoc.getElementById('inner-frame'); |
| var innerDoc = goog.dom.getFrameContentDocument(innerIframe); |
| var anchor = innerDoc.getElementById('anchor1'); |
| |
| var status = goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.BOTTOM_LEFT); |
| assertEquals('Status should not have any ADJUSTED and FAILED.', |
| goog.positioning.OverflowStatus.NONE, status); |
| var innerIframeRect = goog.style.getBounds(innerIframe); |
| var popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Top of frame should align with bottom of the popup', |
| innerIframeRect.top, popupRect.top + popupRect.height); |
| |
| // The anchor is scrolled up by 10px. |
| // Popup position should be the same as above. |
| goog.dom.getWindow(innerDoc).scrollTo(0, 10); |
| status = goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.BOTTOM_LEFT); |
| assertEquals('Status should not have any ADJUSTED and FAILED.', |
| goog.positioning.OverflowStatus.NONE, status); |
| innerIframeRect = goog.style.getBounds(innerIframe); |
| popupRect = goog.style.getBounds(popup); |
| assertRoundedEquals('Top of frame should align with bottom of the popup', |
| innerIframeRect.top, popupRect.top + popupRect.height); |
| } |
| |
| function testPositionAtAnchorOffscreen() { |
| var offset = 0; |
| var anchor = goog.dom.getElement('offscreen-anchor'); |
| var popup = goog.dom.getElement('popup3'); |
| |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_LEFT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectEquals( |
| newCoord(offset, offset), goog.style.getPageOffset(popup)); |
| |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_LEFT, null, null, |
| overflow.ADJUST_X_EXCEPT_OFFSCREEN | overflow.ADJUST_Y); |
| assertObjectEquals( |
| newCoord(-1000, offset), goog.style.getPageOffset(popup)); |
| |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_LEFT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y_EXCEPT_OFFSCREEN); |
| assertObjectEquals( |
| newCoord(offset, -1000), goog.style.getPageOffset(popup)); |
| |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_LEFT, null, null, |
| overflow.ADJUST_X_EXCEPT_OFFSCREEN | overflow.ADJUST_Y_EXCEPT_OFFSCREEN); |
| assertObjectEquals( |
| newCoord(-1000, -1000), |
| goog.style.getPageOffset(popup)); |
| } |
| |
| function testPositionAtAnchorWithOverflowScrollOffsetParent() { |
| var testAreaOffset = goog.style.getPageOffset(testArea); |
| var scrollbarWidth = goog.style.getScrollbarWidth(); |
| window.scrollTo(testAreaOffset.x, testAreaOffset.y); |
| |
| var overflowDiv = goog.dom.createElement('div'); |
| overflowDiv.style.overflow = 'scroll'; |
| overflowDiv.style.position = 'relative'; |
| goog.style.setSize(overflowDiv, 200 /* width */, 100 /* height */); |
| |
| var anchor = goog.dom.createElement('div'); |
| anchor.style.position = 'absolute'; |
| goog.style.setSize(anchor, 50 /* width */, 50 /* height */); |
| goog.style.setPosition(anchor, 300 /* left */, 300 /* top */); |
| |
| var popup = createPopupDiv(75 /* width */, 50 /* height */); |
| |
| goog.dom.append(testArea, overflowDiv, anchor); |
| goog.dom.append(overflowDiv, popup); |
| |
| // Popup should always be positioned within the overflowDiv |
| goog.style.setPosition(overflowDiv, 0 /* left */, 0 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_RIGHT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 200 - 75 - scrollbarWidth, |
| testAreaOffset.y + 100 - 50 - scrollbarWidth), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| goog.style.setPosition(overflowDiv, 400 /* left */, 0 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_RIGHT, popup, corner.TOP_LEFT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 400, testAreaOffset.y + 100 - 50 - scrollbarWidth), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| goog.style.setPosition(overflowDiv, 0 /* left */, 400 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.BOTTOM_LEFT, popup, corner.BOTTOM_RIGHT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 200 - 75 - scrollbarWidth, testAreaOffset.y + 400), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| goog.style.setPosition(overflowDiv, 400 /* left */, 400 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.BOTTOM_RIGHT, popup, corner.BOTTOM_LEFT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 400, testAreaOffset.y + 400), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| // No overflow. |
| goog.style.setPosition(overflowDiv, 300 - 50 /* left */, 300 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_RIGHT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 300 - 50, testAreaOffset.y + 300), |
| goog.style.getPageOffset(popup), |
| 1); |
| } |
| |
| function testPositionAtAnchorWithOverflowHiddenParent() { |
| var testAreaOffset = goog.style.getPageOffset(testArea); |
| window.scrollTo(testAreaOffset.x, testAreaOffset.y); |
| |
| var overflowDiv = goog.dom.createElement('div'); |
| overflowDiv.style.overflow = 'hidden'; |
| overflowDiv.style.position = 'relative'; |
| goog.style.setSize(overflowDiv, 200 /* width */, 100 /* height */); |
| |
| var anchor = goog.dom.createElement('div'); |
| anchor.style.position = 'absolute'; |
| goog.style.setSize(anchor, 50 /* width */, 50 /* height */); |
| goog.style.setPosition(anchor, 300 /* left */, 300 /* top */); |
| |
| var popup = createPopupDiv(75 /* width */, 50 /* height */); |
| |
| goog.dom.append(testArea, overflowDiv, anchor); |
| goog.dom.append(overflowDiv, popup); |
| |
| // Popup should always be positioned within the overflowDiv |
| goog.style.setPosition(overflowDiv, 0 /* left */, 0 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_RIGHT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 200 - 75, testAreaOffset.y + 100 - 50), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| goog.style.setPosition(overflowDiv, 400 /* left */, 0 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_RIGHT, popup, corner.TOP_LEFT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 400, testAreaOffset.y + 100 - 50), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| goog.style.setPosition(overflowDiv, 0 /* left */, 400 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.BOTTOM_LEFT, popup, corner.BOTTOM_RIGHT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 200 - 75, testAreaOffset.y + 400), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| goog.style.setPosition(overflowDiv, 400 /* left */, 400 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.BOTTOM_RIGHT, popup, corner.BOTTOM_LEFT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 400, testAreaOffset.y + 400), |
| goog.style.getPageOffset(popup), |
| 1); |
| |
| // No overflow. |
| goog.style.setPosition(overflowDiv, 300 - 50 /* left */, 300 /* top */); |
| goog.positioning.positionAtAnchor( |
| anchor, corner.TOP_LEFT, popup, corner.TOP_RIGHT, null, null, |
| overflow.ADJUST_X | overflow.ADJUST_Y); |
| assertObjectRoughlyEquals( |
| new goog.math.Coordinate( |
| testAreaOffset.x + 300 - 50, testAreaOffset.y + 300), |
| goog.style.getPageOffset(popup), |
| 1); |
| } |
| |
| function createPopupDiv(width, height) { |
| var popupDiv = goog.dom.createElement('div'); |
| popupDiv.style.position = 'absolute'; |
| goog.style.setSize(popupDiv, width, height); |
| goog.style.setPosition(popupDiv, 0 /* left */, 250 /* top */); |
| return popupDiv; |
| } |
| |
| function newCoord(x, y) { |
| return new goog.math.Coordinate(x, y); |
| } |
| |
| function newSize(w, h) { |
| return new goog.math.Size(w, h); |
| } |
| |
| function newBox(coord, size) { |
| } |