| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND | |
| 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE | |
| 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| 20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 23 * SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 #include "config.h" | |
| 27 #include "web/PopupContainer.h" | |
| 28 | |
| 29 #include <gtest/gtest.h> | |
| 30 | |
| 31 using namespace blink; | |
| 32 using namespace blink; | |
| 33 | |
| 34 class MockPopupContent : public PopupContent { | |
| 35 public: | |
| 36 virtual void setMaxHeight(int max) OVERRIDE { maxHeight = max; } | |
| 37 virtual int popupContentHeight() const OVERRIDE { return height; } | |
| 38 virtual ~MockPopupContent() { } | |
| 39 | |
| 40 virtual void layout() OVERRIDE | |
| 41 { | |
| 42 layoutCount++; | |
| 43 width = std::min(maxWidth, width); | |
| 44 height = std::min(maxHeight, height); | |
| 45 height -= height % 16; | |
| 46 } | |
| 47 | |
| 48 virtual void setMaxWidthAndLayout(int max) OVERRIDE | |
| 49 { | |
| 50 maxWidth = max; | |
| 51 layout(); | |
| 52 } | |
| 53 | |
| 54 MockPopupContent(const IntSize& widgetSize) | |
| 55 : width(widgetSize.width() - borderSize * 2) | |
| 56 , height(widgetSize.height() - borderSize * 2) | |
| 57 , maxWidth(width) | |
| 58 , maxHeight(height) | |
| 59 , layoutCount(0) | |
| 60 { | |
| 61 } | |
| 62 | |
| 63 int width; | |
| 64 int height; | |
| 65 int maxWidth; | |
| 66 int maxHeight; | |
| 67 unsigned layoutCount; | |
| 68 | |
| 69 static const int borderSize = 1; // Should match to kBorderSize in PopupCont
ainer.cpp. | |
| 70 }; | |
| 71 | |
| 72 const int screenMaxX = 1024; | |
| 73 const int screenMaxY = 768; | |
| 74 const int targetControlWidth = 130; | |
| 75 | |
| 76 static IntRect calculatePositionWithTransformAndRTL(const IntRect& initialRect,
const IntSize& transformOffset, int verticalOffset, PopupContent* content) | |
| 77 { | |
| 78 const bool isRTL = true; | |
| 79 const int targetControlHeight = 20; | |
| 80 const FloatRect screenRect(0, 0, screenMaxX, screenMaxY); | |
| 81 const FloatRect windowRect(0, 0, 512, 512); | |
| 82 int rtlOffset = targetControlWidth - initialRect.width(); | |
| 83 bool needToResizeView = false; | |
| 84 return PopupContainer::layoutAndCalculateWidgetRectInternal(initialRect, tar
getControlHeight, windowRect, screenRect, !isRTL, rtlOffset, verticalOffset, tra
nsformOffset, content, needToResizeView); | |
| 85 } | |
| 86 | |
| 87 static IntRect calculatePosition(const IntRect& initialRect, PopupContent* conte
nt, FloatRect windowRect = FloatRect(0, 0, 512, 512), bool isRTL = true) | |
| 88 { | |
| 89 const int targetControlHeight = 20; | |
| 90 const FloatRect screenRect(0, 0, screenMaxX, screenMaxY); | |
| 91 int rtlOffset = (targetControlWidth - initialRect.width()) * (isRTL ? 1 : -1
); | |
| 92 bool needToResizeView = false; | |
| 93 return PopupContainer::layoutAndCalculateWidgetRectInternal(initialRect, tar
getControlHeight, windowRect, screenRect, !isRTL, rtlOffset, 0, IntSize(), conte
nt, needToResizeView); | |
| 94 } | |
| 95 | |
| 96 TEST(PopupContainerTest, PopupPosition) | |
| 97 { | |
| 98 // Suppose that initialRect.location is the bottom-left corner of the target | |
| 99 // control such as <select>. | |
| 100 | |
| 101 { | |
| 102 // If initialRect is in the screen, nothing should happen. | |
| 103 IntRect initialRect(100, 100, 256, 258); | |
| 104 MockPopupContent content(initialRect.size()); | |
| 105 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 106 EXPECT_EQ(initialRect, resultRect); | |
| 107 EXPECT_EQ(0u, content.layoutCount); | |
| 108 } | |
| 109 | |
| 110 { | |
| 111 // If the left edge of the control is projecting from the screen, making | |
| 112 // the widget aligned to the right edge of the control. | |
| 113 IntRect initialRect(-10, 100, 100, 258); | |
| 114 MockPopupContent content(initialRect.size()); | |
| 115 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 116 EXPECT_EQ(IntRect(20, 100, 100, 258), resultRect); | |
| 117 } | |
| 118 | |
| 119 { | |
| 120 // Made the widget aligned to the right edge. But it's still projecting | |
| 121 // from the screen. | |
| 122 IntRect initialRect(-10, 100, targetControlWidth, 258); | |
| 123 MockPopupContent content(initialRect.size()); | |
| 124 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 125 EXPECT_EQ(IntRect(0, 100, 120, 258), resultRect); | |
| 126 EXPECT_EQ(118, content.width); | |
| 127 EXPECT_TRUE(content.layoutCount); | |
| 128 } | |
| 129 | |
| 130 { | |
| 131 // If the right edge of the control is projecting from the screen, | |
| 132 // shrink the width of the widget. | |
| 133 IntRect initialRect(screenMaxX - 100, 100, targetControlWidth, 258); | |
| 134 MockPopupContent content(initialRect.size()); | |
| 135 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 136 EXPECT_EQ(IntRect(screenMaxX - 100, 100, 100, 258), resultRect); | |
| 137 EXPECT_EQ(98, content.width); | |
| 138 EXPECT_TRUE(content.layoutCount); | |
| 139 } | |
| 140 | |
| 141 { | |
| 142 // If there is no enough room below, move the widget upwards. | |
| 143 IntRect initialRect(100, 700, targetControlWidth, 258); | |
| 144 MockPopupContent content(initialRect.size()); | |
| 145 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 146 EXPECT_EQ(IntRect(100, 422, targetControlWidth, 258), resultRect); | |
| 147 EXPECT_EQ(0u, content.layoutCount); | |
| 148 } | |
| 149 | |
| 150 { | |
| 151 // There is no enough room below and above, and the below space is large
r. | |
| 152 IntRect initialRect(100, 300, targetControlWidth, 514); | |
| 153 MockPopupContent content(initialRect.size()); | |
| 154 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 155 EXPECT_EQ(IntRect(100, 300, targetControlWidth, 466), resultRect); | |
| 156 EXPECT_TRUE(content.layoutCount); | |
| 157 EXPECT_EQ(464, content.height); | |
| 158 } | |
| 159 | |
| 160 { | |
| 161 // There is no enough room below and above, and the above space is large
r. | |
| 162 IntRect initialRect(100, 400, targetControlWidth, 514); | |
| 163 MockPopupContent content(initialRect.size()); | |
| 164 IntRect resultRect = calculatePosition(initialRect, &content); | |
| 165 EXPECT_EQ(IntRect(100, 10, targetControlWidth, 370), resultRect); | |
| 166 EXPECT_TRUE(content.layoutCount); | |
| 167 EXPECT_EQ(368, content.height); | |
| 168 } | |
| 169 | |
| 170 { | |
| 171 // There is not enough room to the right, so open the popup menu to the
left. | |
| 172 IntRect initialRect(screenMaxX - targetControlWidth - 6, 100, targetCont
rolWidth * 2, 100); | |
| 173 MockPopupContent content(initialRect.size()); | |
| 174 IntRect resultRect = calculatePosition(initialRect, &content, FloatRect(
0, 0, screenMaxX, screenMaxY), false); | |
| 175 EXPECT_EQ(IntRect(758, 100, 260, 100), resultRect); | |
| 176 } | |
| 177 | |
| 178 { | |
| 179 // Test for --webkit-transform:rotate(53deg). | |
| 180 IntRect initialRect(100, 700, targetControlWidth, 258); | |
| 181 MockPopupContent content(initialRect.size()); | |
| 182 IntSize transformOffset(-4, -8); | |
| 183 IntRect resultRect = calculatePositionWithTransformAndRTL(initialRect, t
ransformOffset, -104, &content); | |
| 184 EXPECT_EQ(IntRect(104, 430, targetControlWidth, 258), resultRect); | |
| 185 EXPECT_EQ(0u, content.layoutCount); | |
| 186 } | |
| 187 | |
| 188 { | |
| 189 // Test for --webkit-transform:rotate(-53deg). | |
| 190 IntRect initialRect(100, 700, targetControlWidth, 258); | |
| 191 MockPopupContent content(initialRect.size()); | |
| 192 IntSize transformOffset(4, -8); | |
| 193 IntRect resultRect = calculatePositionWithTransformAndRTL(initialRect, t
ransformOffset, 104, &content); | |
| 194 EXPECT_EQ(IntRect(96, 430, targetControlWidth, 258), resultRect); | |
| 195 EXPECT_EQ(0u, content.layoutCount); | |
| 196 } | |
| 197 } | |
| OLD | NEW |