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 |