OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) | 2 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) |
3 * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org> | 3 * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org> |
4 * | 4 * |
5 * All rights reserved. | 5 * All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "core/html/HTMLImageElement.h" | 38 #include "core/html/HTMLImageElement.h" |
39 #include "core/page/FrameTree.h" | 39 #include "core/page/FrameTree.h" |
40 #include "core/page/Page.h" | 40 #include "core/page/Page.h" |
41 #include "core/rendering/RenderLayer.h" | 41 #include "core/rendering/RenderLayer.h" |
42 #include "platform/geometry/IntRect.h" | 42 #include "platform/geometry/IntRect.h" |
43 | 43 |
44 namespace blink { | 44 namespace blink { |
45 | 45 |
46 using namespace HTMLNames; | 46 using namespace HTMLNames; |
47 | 47 |
48 static RectsAlignment alignmentForRects(FocusType, const LayoutRect&, const Layo
utRect&, const LayoutSize& viewSize); | 48 static RectsAlignment alignmentForRects(WebFocusType, const LayoutRect&, const L
ayoutRect&, const LayoutSize& viewSize); |
49 static bool areRectsFullyAligned(FocusType, const LayoutRect&, const LayoutRect&
); | 49 static bool areRectsFullyAligned(WebFocusType, const LayoutRect&, const LayoutRe
ct&); |
50 static bool areRectsPartiallyAligned(FocusType, const LayoutRect&, const LayoutR
ect&); | 50 static bool areRectsPartiallyAligned(WebFocusType, const LayoutRect&, const Layo
utRect&); |
51 static bool areRectsMoreThanFullScreenApart(FocusType, const LayoutRect& curRect
, const LayoutRect& targetRect, const LayoutSize& viewSize); | 51 static bool areRectsMoreThanFullScreenApart(WebFocusType, const LayoutRect& curR
ect, const LayoutRect& targetRect, const LayoutSize& viewSize); |
52 static bool isRectInDirection(FocusType, const LayoutRect&, const LayoutRect&); | 52 static bool isRectInDirection(WebFocusType, const LayoutRect&, const LayoutRect&
); |
53 static void deflateIfOverlapped(LayoutRect&, LayoutRect&); | 53 static void deflateIfOverlapped(LayoutRect&, LayoutRect&); |
54 static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const Layo
utRect&); | 54 static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const Layo
utRect&); |
55 static bool isScrollableNode(const Node*); | 55 static bool isScrollableNode(const Node*); |
56 | 56 |
57 FocusCandidate::FocusCandidate(Node* node, FocusType type) | 57 FocusCandidate::FocusCandidate(Node* node, WebFocusType type) |
58 : visibleNode(nullptr) | 58 : visibleNode(nullptr) |
59 , focusableNode(nullptr) | 59 , focusableNode(nullptr) |
60 , enclosingScrollableBox(nullptr) | 60 , enclosingScrollableBox(nullptr) |
61 , distance(maxDistance()) | 61 , distance(maxDistance()) |
62 , alignment(None) | 62 , alignment(None) |
63 , isOffscreen(true) | 63 , isOffscreen(true) |
64 , isOffscreenAfterScrolling(true) | 64 , isOffscreenAfterScrolling(true) |
65 { | 65 { |
66 ASSERT(node); | 66 ASSERT(node); |
67 ASSERT(node->isElementNode()); | 67 ASSERT(node->isElementNode()); |
(...skipping 17 matching lines...) Expand all Loading... |
85 focusableNode = node; | 85 focusableNode = node; |
86 isOffscreen = hasOffscreenRect(visibleNode); | 86 isOffscreen = hasOffscreenRect(visibleNode); |
87 isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, type); | 87 isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, type); |
88 } | 88 } |
89 | 89 |
90 bool isSpatialNavigationEnabled(const LocalFrame* frame) | 90 bool isSpatialNavigationEnabled(const LocalFrame* frame) |
91 { | 91 { |
92 return (frame && frame->settings() && frame->settings()->spatialNavigationEn
abled()); | 92 return (frame && frame->settings() && frame->settings()->spatialNavigationEn
abled()); |
93 } | 93 } |
94 | 94 |
95 static RectsAlignment alignmentForRects(FocusType type, const LayoutRect& curRec
t, const LayoutRect& targetRect, const LayoutSize& viewSize) | 95 static RectsAlignment alignmentForRects(WebFocusType type, const LayoutRect& cur
Rect, const LayoutRect& targetRect, const LayoutSize& viewSize) |
96 { | 96 { |
97 // If we found a node in full alignment, but it is too far away, ignore it. | 97 // If we found a node in full alignment, but it is too far away, ignore it. |
98 if (areRectsMoreThanFullScreenApart(type, curRect, targetRect, viewSize)) | 98 if (areRectsMoreThanFullScreenApart(type, curRect, targetRect, viewSize)) |
99 return None; | 99 return None; |
100 | 100 |
101 if (areRectsFullyAligned(type, curRect, targetRect)) | 101 if (areRectsFullyAligned(type, curRect, targetRect)) |
102 return Full; | 102 return Full; |
103 | 103 |
104 if (areRectsPartiallyAligned(type, curRect, targetRect)) | 104 if (areRectsPartiallyAligned(type, curRect, targetRect)) |
105 return Partial; | 105 return Partial; |
106 | 106 |
107 return None; | 107 return None; |
108 } | 108 } |
109 | 109 |
110 static inline bool isHorizontalMove(FocusType type) | 110 static inline bool isHorizontalMove(WebFocusType type) |
111 { | 111 { |
112 return type == FocusTypeLeft || type == FocusTypeRight; | 112 return type == WebFocusTypeLeft || type == WebFocusTypeRight; |
113 } | 113 } |
114 | 114 |
115 static inline LayoutUnit start(FocusType type, const LayoutRect& rect) | 115 static inline LayoutUnit start(WebFocusType type, const LayoutRect& rect) |
116 { | 116 { |
117 return isHorizontalMove(type) ? rect.y() : rect.x(); | 117 return isHorizontalMove(type) ? rect.y() : rect.x(); |
118 } | 118 } |
119 | 119 |
120 static inline LayoutUnit middle(FocusType type, const LayoutRect& rect) | 120 static inline LayoutUnit middle(WebFocusType type, const LayoutRect& rect) |
121 { | 121 { |
122 LayoutPoint center(rect.center()); | 122 LayoutPoint center(rect.center()); |
123 return isHorizontalMove(type) ? center.y(): center.x(); | 123 return isHorizontalMove(type) ? center.y(): center.x(); |
124 } | 124 } |
125 | 125 |
126 static inline LayoutUnit end(FocusType type, const LayoutRect& rect) | 126 static inline LayoutUnit end(WebFocusType type, const LayoutRect& rect) |
127 { | 127 { |
128 return isHorizontalMove(type) ? rect.maxY() : rect.maxX(); | 128 return isHorizontalMove(type) ? rect.maxY() : rect.maxX(); |
129 } | 129 } |
130 | 130 |
131 // This method checks if rects |a| and |b| are fully aligned either vertically o
r | 131 // This method checks if rects |a| and |b| are fully aligned either vertically o
r |
132 // horizontally. In general, rects whose central point falls between the top or | 132 // horizontally. In general, rects whose central point falls between the top or |
133 // bottom of each other are considered fully aligned. | 133 // bottom of each other are considered fully aligned. |
134 // Rects that match this criteria are preferable target nodes in move focus chan
ging | 134 // Rects that match this criteria are preferable target nodes in move focus chan
ging |
135 // operations. | 135 // operations. |
136 // * a = Current focused node's rect. | 136 // * a = Current focused node's rect. |
137 // * b = Focus candidate node's rect. | 137 // * b = Focus candidate node's rect. |
138 static bool areRectsFullyAligned(FocusType type, const LayoutRect& a, const Layo
utRect& b) | 138 static bool areRectsFullyAligned(WebFocusType type, const LayoutRect& a, const L
ayoutRect& b) |
139 { | 139 { |
140 LayoutUnit aStart, bStart, aEnd, bEnd; | 140 LayoutUnit aStart, bStart, aEnd, bEnd; |
141 | 141 |
142 switch (type) { | 142 switch (type) { |
143 case FocusTypeLeft: | 143 case WebFocusTypeLeft: |
144 aStart = a.x(); | 144 aStart = a.x(); |
145 bEnd = b.x(); | 145 bEnd = b.x(); |
146 break; | 146 break; |
147 case FocusTypeRight: | 147 case WebFocusTypeRight: |
148 aStart = b.x(); | 148 aStart = b.x(); |
149 bEnd = a.x(); | 149 bEnd = a.x(); |
150 break; | 150 break; |
151 case FocusTypeUp: | 151 case WebFocusTypeUp: |
152 aStart = a.y(); | 152 aStart = a.y(); |
153 bEnd = b.y(); | 153 bEnd = b.y(); |
154 break; | 154 break; |
155 case FocusTypeDown: | 155 case WebFocusTypeDown: |
156 aStart = b.y(); | 156 aStart = b.y(); |
157 bEnd = a.y(); | 157 bEnd = a.y(); |
158 break; | 158 break; |
159 default: | 159 default: |
160 ASSERT_NOT_REACHED(); | 160 ASSERT_NOT_REACHED(); |
161 return false; | 161 return false; |
162 } | 162 } |
163 | 163 |
164 if (aStart < bEnd) | 164 if (aStart < bEnd) |
165 return false; | 165 return false; |
(...skipping 24 matching lines...) Expand all Loading... |
190 || (aMiddle >= bStart && aMiddle <= bEnd); // (2) | 190 || (aMiddle >= bStart && aMiddle <= bEnd); // (2) |
191 } | 191 } |
192 | 192 |
193 // This method checks if rects |a| and |b| are partially aligned either vertical
ly or | 193 // This method checks if rects |a| and |b| are partially aligned either vertical
ly or |
194 // horizontally. In general, rects whose either of edges falls between the top o
r | 194 // horizontally. In general, rects whose either of edges falls between the top o
r |
195 // bottom of each other are considered partially-aligned. | 195 // bottom of each other are considered partially-aligned. |
196 // This is a separate set of conditions from "fully-aligned" and do not include
cases | 196 // This is a separate set of conditions from "fully-aligned" and do not include
cases |
197 // that satisfy the former. | 197 // that satisfy the former. |
198 // * a = Current focused node's rect. | 198 // * a = Current focused node's rect. |
199 // * b = Focus candidate node's rect. | 199 // * b = Focus candidate node's rect. |
200 static bool areRectsPartiallyAligned(FocusType type, const LayoutRect& a, const
LayoutRect& b) | 200 static bool areRectsPartiallyAligned(WebFocusType type, const LayoutRect& a, con
st LayoutRect& b) |
201 { | 201 { |
202 LayoutUnit aStart = start(type, a); | 202 LayoutUnit aStart = start(type, a); |
203 LayoutUnit bStart = start(type, b); | 203 LayoutUnit bStart = start(type, b); |
204 LayoutUnit aEnd = end(type, a); | 204 LayoutUnit aEnd = end(type, a); |
205 LayoutUnit bEnd = end(type, b); | 205 LayoutUnit bEnd = end(type, b); |
206 | 206 |
207 // Picture of the partially aligned logic: | 207 // Picture of the partially aligned logic: |
208 // | 208 // |
209 // Horizontal Vertical | 209 // Horizontal Vertical |
210 // ******************************** | 210 // ******************************** |
211 // * _ * _ _ _ * | 211 // * _ * _ _ _ * |
212 // * |_| * |_|_|_| * | 212 // * |_| * |_|_|_| * |
213 // * |_|.... _ * . . * | 213 // * |_|.... _ * . . * |
214 // * |_| |_| * . . * | 214 // * |_| |_| * . . * |
215 // * |_|....|_| * ._._ _ * | 215 // * |_|....|_| * ._._ _ * |
216 // * |_| * |_|_|_| * | 216 // * |_| * |_|_|_| * |
217 // * |_| * * | 217 // * |_| * * |
218 // * * * | 218 // * * * |
219 // ******************************** | 219 // ******************************** |
220 // | 220 // |
221 // ... and variants of the above cases. | 221 // ... and variants of the above cases. |
222 return (bStart >= aStart && bStart <= aEnd) | 222 return (bStart >= aStart && bStart <= aEnd) |
223 || (bEnd >= aStart && bEnd <= aEnd); | 223 || (bEnd >= aStart && bEnd <= aEnd); |
224 } | 224 } |
225 | 225 |
226 static bool areRectsMoreThanFullScreenApart(FocusType type, const LayoutRect& cu
rRect, const LayoutRect& targetRect, const LayoutSize& viewSize) | 226 static bool areRectsMoreThanFullScreenApart(WebFocusType type, const LayoutRect&
curRect, const LayoutRect& targetRect, const LayoutSize& viewSize) |
227 { | 227 { |
228 ASSERT(isRectInDirection(type, curRect, targetRect)); | 228 ASSERT(isRectInDirection(type, curRect, targetRect)); |
229 | 229 |
230 switch (type) { | 230 switch (type) { |
231 case FocusTypeLeft: | 231 case WebFocusTypeLeft: |
232 return curRect.x() - targetRect.maxX() > viewSize.width(); | 232 return curRect.x() - targetRect.maxX() > viewSize.width(); |
233 case FocusTypeRight: | 233 case WebFocusTypeRight: |
234 return targetRect.x() - curRect.maxX() > viewSize.width(); | 234 return targetRect.x() - curRect.maxX() > viewSize.width(); |
235 case FocusTypeUp: | 235 case WebFocusTypeUp: |
236 return curRect.y() - targetRect.maxY() > viewSize.height(); | 236 return curRect.y() - targetRect.maxY() > viewSize.height(); |
237 case FocusTypeDown: | 237 case WebFocusTypeDown: |
238 return targetRect.y() - curRect.maxY() > viewSize.height(); | 238 return targetRect.y() - curRect.maxY() > viewSize.height(); |
239 default: | 239 default: |
240 ASSERT_NOT_REACHED(); | 240 ASSERT_NOT_REACHED(); |
241 return true; | 241 return true; |
242 } | 242 } |
243 } | 243 } |
244 | 244 |
245 // Return true if rect |a| is below |b|. False otherwise. | 245 // Return true if rect |a| is below |b|. False otherwise. |
246 // For overlapping rects, |a| is considered to be below |b| | 246 // For overlapping rects, |a| is considered to be below |b| |
247 // if both edges of |a| are below the respective ones of |b| | 247 // if both edges of |a| are below the respective ones of |b| |
248 static inline bool below(const LayoutRect& a, const LayoutRect& b) | 248 static inline bool below(const LayoutRect& a, const LayoutRect& b) |
249 { | 249 { |
250 return a.y() >= b.maxY() | 250 return a.y() >= b.maxY() |
251 || (a.y() >= b.y() && a.maxY() > b.maxY() && a.x() < b.maxX() && a.maxX(
) > b.x()); | 251 || (a.y() >= b.y() && a.maxY() > b.maxY() && a.x() < b.maxX() && a.maxX(
) > b.x()); |
252 } | 252 } |
253 | 253 |
254 // Return true if rect |a| is on the right of |b|. False otherwise. | 254 // Return true if rect |a| is on the right of |b|. False otherwise. |
255 // For overlapping rects, |a| is considered to be on the right of |b| | 255 // For overlapping rects, |a| is considered to be on the right of |b| |
256 // if both edges of |a| are on the right of the respective ones of |b| | 256 // if both edges of |a| are on the right of the respective ones of |b| |
257 static inline bool rightOf(const LayoutRect& a, const LayoutRect& b) | 257 static inline bool rightOf(const LayoutRect& a, const LayoutRect& b) |
258 { | 258 { |
259 return a.x() >= b.maxX() | 259 return a.x() >= b.maxX() |
260 || (a.x() >= b.x() && a.maxX() > b.maxX() && a.y() < b.maxY() && a.maxY(
) > b.y()); | 260 || (a.x() >= b.x() && a.maxX() > b.maxX() && a.y() < b.maxY() && a.maxY(
) > b.y()); |
261 } | 261 } |
262 | 262 |
263 static bool isRectInDirection(FocusType type, const LayoutRect& curRect, const L
ayoutRect& targetRect) | 263 static bool isRectInDirection(WebFocusType type, const LayoutRect& curRect, cons
t LayoutRect& targetRect) |
264 { | 264 { |
265 switch (type) { | 265 switch (type) { |
266 case FocusTypeLeft: | 266 case WebFocusTypeLeft: |
267 return rightOf(curRect, targetRect); | 267 return rightOf(curRect, targetRect); |
268 case FocusTypeRight: | 268 case WebFocusTypeRight: |
269 return rightOf(targetRect, curRect); | 269 return rightOf(targetRect, curRect); |
270 case FocusTypeUp: | 270 case WebFocusTypeUp: |
271 return below(curRect, targetRect); | 271 return below(curRect, targetRect); |
272 case FocusTypeDown: | 272 case WebFocusTypeDown: |
273 return below(targetRect, curRect); | 273 return below(targetRect, curRect); |
274 default: | 274 default: |
275 ASSERT_NOT_REACHED(); | 275 ASSERT_NOT_REACHED(); |
276 return false; | 276 return false; |
277 } | 277 } |
278 } | 278 } |
279 | 279 |
280 // Checks if |node| is offscreen the visible area (viewport) of its container | 280 // Checks if |node| is offscreen the visible area (viewport) of its container |
281 // document. In case it is, one can scroll in direction or take any different | 281 // document. In case it is, one can scroll in direction or take any different |
282 // desired action later on. | 282 // desired action later on. |
283 bool hasOffscreenRect(Node* node, FocusType type) | 283 bool hasOffscreenRect(Node* node, WebFocusType type) |
284 { | 284 { |
285 // Get the FrameView in which |node| is (which means the current viewport if
|node| | 285 // Get the FrameView in which |node| is (which means the current viewport if
|node| |
286 // is not in an inner document), so we can check if its content rect is visi
ble | 286 // is not in an inner document), so we can check if its content rect is visi
ble |
287 // before we actually move the focus to it. | 287 // before we actually move the focus to it. |
288 FrameView* frameView = node->document().view(); | 288 FrameView* frameView = node->document().view(); |
289 if (!frameView) | 289 if (!frameView) |
290 return true; | 290 return true; |
291 | 291 |
292 ASSERT(!frameView->needsLayout()); | 292 ASSERT(!frameView->needsLayout()); |
293 | 293 |
294 LayoutRect containerViewportRect = frameView->visibleContentRect(); | 294 LayoutRect containerViewportRect = frameView->visibleContentRect(); |
295 // We want to select a node if it is currently off screen, but will be | 295 // We want to select a node if it is currently off screen, but will be |
296 // exposed after we scroll. Adjust the viewport to post-scrolling position. | 296 // exposed after we scroll. Adjust the viewport to post-scrolling position. |
297 // If the container has overflow:hidden, we cannot scroll, so we do not pass
direction | 297 // If the container has overflow:hidden, we cannot scroll, so we do not pass
direction |
298 // and we do not adjust for scrolling. | 298 // and we do not adjust for scrolling. |
299 switch (type) { | 299 switch (type) { |
300 case FocusTypeLeft: | 300 case WebFocusTypeLeft: |
301 containerViewportRect.setX(containerViewportRect.x() - ScrollableArea::p
ixelsPerLineStep()); | 301 containerViewportRect.setX(containerViewportRect.x() - ScrollableArea::p
ixelsPerLineStep()); |
302 containerViewportRect.setWidth(containerViewportRect.width() + Scrollabl
eArea::pixelsPerLineStep()); | 302 containerViewportRect.setWidth(containerViewportRect.width() + Scrollabl
eArea::pixelsPerLineStep()); |
303 break; | 303 break; |
304 case FocusTypeRight: | 304 case WebFocusTypeRight: |
305 containerViewportRect.setWidth(containerViewportRect.width() + Scrollabl
eArea::pixelsPerLineStep()); | 305 containerViewportRect.setWidth(containerViewportRect.width() + Scrollabl
eArea::pixelsPerLineStep()); |
306 break; | 306 break; |
307 case FocusTypeUp: | 307 case WebFocusTypeUp: |
308 containerViewportRect.setY(containerViewportRect.y() - ScrollableArea::p
ixelsPerLineStep()); | 308 containerViewportRect.setY(containerViewportRect.y() - ScrollableArea::p
ixelsPerLineStep()); |
309 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); | 309 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); |
310 break; | 310 break; |
311 case FocusTypeDown: | 311 case WebFocusTypeDown: |
312 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); | 312 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); |
313 break; | 313 break; |
314 default: | 314 default: |
315 break; | 315 break; |
316 } | 316 } |
317 | 317 |
318 RenderObject* render = node->renderer(); | 318 RenderObject* render = node->renderer(); |
319 if (!render) | 319 if (!render) |
320 return true; | 320 return true; |
321 | 321 |
322 LayoutRect rect(render->absoluteClippedOverflowRect()); | 322 LayoutRect rect(render->absoluteClippedOverflowRect()); |
323 if (rect.isEmpty()) | 323 if (rect.isEmpty()) |
324 return true; | 324 return true; |
325 | 325 |
326 return !containerViewportRect.intersects(rect); | 326 return !containerViewportRect.intersects(rect); |
327 } | 327 } |
328 | 328 |
329 bool scrollInDirection(LocalFrame* frame, FocusType type) | 329 bool scrollInDirection(LocalFrame* frame, WebFocusType type) |
330 { | 330 { |
331 ASSERT(frame); | 331 ASSERT(frame); |
332 | 332 |
333 if (frame && canScrollInDirection(frame->document(), type)) { | 333 if (frame && canScrollInDirection(frame->document(), type)) { |
334 LayoutUnit dx = 0; | 334 LayoutUnit dx = 0; |
335 LayoutUnit dy = 0; | 335 LayoutUnit dy = 0; |
336 switch (type) { | 336 switch (type) { |
337 case FocusTypeLeft: | 337 case WebFocusTypeLeft: |
338 dx = - ScrollableArea::pixelsPerLineStep(); | 338 dx = - ScrollableArea::pixelsPerLineStep(); |
339 break; | 339 break; |
340 case FocusTypeRight: | 340 case WebFocusTypeRight: |
341 dx = ScrollableArea::pixelsPerLineStep(); | 341 dx = ScrollableArea::pixelsPerLineStep(); |
342 break; | 342 break; |
343 case FocusTypeUp: | 343 case WebFocusTypeUp: |
344 dy = - ScrollableArea::pixelsPerLineStep(); | 344 dy = - ScrollableArea::pixelsPerLineStep(); |
345 break; | 345 break; |
346 case FocusTypeDown: | 346 case WebFocusTypeDown: |
347 dy = ScrollableArea::pixelsPerLineStep(); | 347 dy = ScrollableArea::pixelsPerLineStep(); |
348 break; | 348 break; |
349 default: | 349 default: |
350 ASSERT_NOT_REACHED(); | 350 ASSERT_NOT_REACHED(); |
351 return false; | 351 return false; |
352 } | 352 } |
353 | 353 |
354 frame->view()->scrollBy(IntSize(dx, dy)); | 354 frame->view()->scrollBy(IntSize(dx, dy)); |
355 return true; | 355 return true; |
356 } | 356 } |
357 return false; | 357 return false; |
358 } | 358 } |
359 | 359 |
360 bool scrollInDirection(Node* container, FocusType type) | 360 bool scrollInDirection(Node* container, WebFocusType type) |
361 { | 361 { |
362 ASSERT(container); | 362 ASSERT(container); |
363 if (container->isDocumentNode()) | 363 if (container->isDocumentNode()) |
364 return scrollInDirection(toDocument(container)->frame(), type); | 364 return scrollInDirection(toDocument(container)->frame(), type); |
365 | 365 |
366 if (!container->renderBox()) | 366 if (!container->renderBox()) |
367 return false; | 367 return false; |
368 | 368 |
369 if (canScrollInDirection(container, type)) { | 369 if (canScrollInDirection(container, type)) { |
370 LayoutUnit dx = 0; | 370 LayoutUnit dx = 0; |
371 LayoutUnit dy = 0; | 371 LayoutUnit dy = 0; |
372 switch (type) { | 372 switch (type) { |
373 case FocusTypeLeft: | 373 case WebFocusTypeLeft: |
374 dx = - std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), con
tainer->renderBox()->scrollLeft()); | 374 dx = - std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), con
tainer->renderBox()->scrollLeft()); |
375 break; | 375 break; |
376 case FocusTypeRight: | 376 case WebFocusTypeRight: |
377 ASSERT(container->renderBox()->scrollWidth() > (container->renderBox
()->scrollLeft() + container->renderBox()->clientWidth())); | 377 ASSERT(container->renderBox()->scrollWidth() > (container->renderBox
()->scrollLeft() + container->renderBox()->clientWidth())); |
378 dx = std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), conta
iner->renderBox()->scrollWidth() - (container->renderBox()->scrollLeft() + conta
iner->renderBox()->clientWidth())); | 378 dx = std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), conta
iner->renderBox()->scrollWidth() - (container->renderBox()->scrollLeft() + conta
iner->renderBox()->clientWidth())); |
379 break; | 379 break; |
380 case FocusTypeUp: | 380 case WebFocusTypeUp: |
381 dy = - std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), con
tainer->renderBox()->scrollTop()); | 381 dy = - std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), con
tainer->renderBox()->scrollTop()); |
382 break; | 382 break; |
383 case FocusTypeDown: | 383 case WebFocusTypeDown: |
384 ASSERT(container->renderBox()->scrollHeight() - (container->renderBo
x()->scrollTop() + container->renderBox()->clientHeight())); | 384 ASSERT(container->renderBox()->scrollHeight() - (container->renderBo
x()->scrollTop() + container->renderBox()->clientHeight())); |
385 dy = std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), conta
iner->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + conta
iner->renderBox()->clientHeight())); | 385 dy = std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), conta
iner->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + conta
iner->renderBox()->clientHeight())); |
386 break; | 386 break; |
387 default: | 387 default: |
388 ASSERT_NOT_REACHED(); | 388 ASSERT_NOT_REACHED(); |
389 return false; | 389 return false; |
390 } | 390 } |
391 | 391 |
392 container->renderBox()->scrollByRecursively(IntSize(dx, dy)); | 392 container->renderBox()->scrollByRecursively(IntSize(dx, dy)); |
393 return true; | 393 return true; |
(...skipping 23 matching lines...) Expand all Loading... |
417 | 417 |
418 if (!node) | 418 if (!node) |
419 return false; | 419 return false; |
420 | 420 |
421 if (RenderObject* renderer = node->renderer()) | 421 if (RenderObject* renderer = node->renderer()) |
422 return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasSc
rollableArea() && node->hasChildren(); | 422 return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasSc
rollableArea() && node->hasChildren(); |
423 | 423 |
424 return false; | 424 return false; |
425 } | 425 } |
426 | 426 |
427 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusType type, Node
* node) | 427 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(WebFocusType type, N
ode* node) |
428 { | 428 { |
429 ASSERT(node); | 429 ASSERT(node); |
430 Node* parent = node; | 430 Node* parent = node; |
431 do { | 431 do { |
432 // FIXME: Spatial navigation is broken for OOPI. | 432 // FIXME: Spatial navigation is broken for OOPI. |
433 if (parent->isDocumentNode()) | 433 if (parent->isDocumentNode()) |
434 parent = toDocument(parent)->frame()->deprecatedLocalOwner(); | 434 parent = toDocument(parent)->frame()->deprecatedLocalOwner(); |
435 else | 435 else |
436 parent = parent->parentOrShadowHostNode(); | 436 parent = parent->parentOrShadowHostNode(); |
437 } while (parent && !canScrollInDirection(parent, type) && !parent->isDocumen
tNode()); | 437 } while (parent && !canScrollInDirection(parent, type) && !parent->isDocumen
tNode()); |
438 | 438 |
439 return parent; | 439 return parent; |
440 } | 440 } |
441 | 441 |
442 bool canScrollInDirection(const Node* container, FocusType type) | 442 bool canScrollInDirection(const Node* container, WebFocusType type) |
443 { | 443 { |
444 ASSERT(container); | 444 ASSERT(container); |
445 if (container->isDocumentNode()) | 445 if (container->isDocumentNode()) |
446 return canScrollInDirection(toDocument(container)->frame(), type); | 446 return canScrollInDirection(toDocument(container)->frame(), type); |
447 | 447 |
448 if (!isScrollableNode(container)) | 448 if (!isScrollableNode(container)) |
449 return false; | 449 return false; |
450 | 450 |
451 switch (type) { | 451 switch (type) { |
452 case FocusTypeLeft: | 452 case WebFocusTypeLeft: |
453 return (container->renderer()->style()->overflowX() != OHIDDEN && contai
ner->renderBox()->scrollLeft() > 0); | 453 return (container->renderer()->style()->overflowX() != OHIDDEN && contai
ner->renderBox()->scrollLeft() > 0); |
454 case FocusTypeUp: | 454 case WebFocusTypeUp: |
455 return (container->renderer()->style()->overflowY() != OHIDDEN && contai
ner->renderBox()->scrollTop() > 0); | 455 return (container->renderer()->style()->overflowY() != OHIDDEN && contai
ner->renderBox()->scrollTop() > 0); |
456 case FocusTypeRight: | 456 case WebFocusTypeRight: |
457 return (container->renderer()->style()->overflowX() != OHIDDEN && contai
ner->renderBox()->scrollLeft() + container->renderBox()->clientWidth() < contain
er->renderBox()->scrollWidth()); | 457 return (container->renderer()->style()->overflowX() != OHIDDEN && contai
ner->renderBox()->scrollLeft() + container->renderBox()->clientWidth() < contain
er->renderBox()->scrollWidth()); |
458 case FocusTypeDown: | 458 case WebFocusTypeDown: |
459 return (container->renderer()->style()->overflowY() != OHIDDEN && contai
ner->renderBox()->scrollTop() + container->renderBox()->clientHeight() < contain
er->renderBox()->scrollHeight()); | 459 return (container->renderer()->style()->overflowY() != OHIDDEN && contai
ner->renderBox()->scrollTop() + container->renderBox()->clientHeight() < contain
er->renderBox()->scrollHeight()); |
460 default: | 460 default: |
461 ASSERT_NOT_REACHED(); | 461 ASSERT_NOT_REACHED(); |
462 return false; | 462 return false; |
463 } | 463 } |
464 } | 464 } |
465 | 465 |
466 bool canScrollInDirection(const LocalFrame* frame, FocusType type) | 466 bool canScrollInDirection(const LocalFrame* frame, WebFocusType type) |
467 { | 467 { |
468 if (!frame->view()) | 468 if (!frame->view()) |
469 return false; | 469 return false; |
470 ScrollbarMode verticalMode; | 470 ScrollbarMode verticalMode; |
471 ScrollbarMode horizontalMode; | 471 ScrollbarMode horizontalMode; |
472 frame->view()->calculateScrollbarModesForLayoutAndSetViewportRenderer(horizo
ntalMode, verticalMode); | 472 frame->view()->calculateScrollbarModesForLayoutAndSetViewportRenderer(horizo
ntalMode, verticalMode); |
473 if ((type == FocusTypeLeft || type == FocusTypeRight) && ScrollbarAlwaysOff
== horizontalMode) | 473 if ((type == WebFocusTypeLeft || type == WebFocusTypeRight) && ScrollbarAlwa
ysOff == horizontalMode) |
474 return false; | 474 return false; |
475 if ((type == FocusTypeUp || type == FocusTypeDown) && ScrollbarAlwaysOff ==
verticalMode) | 475 if ((type == WebFocusTypeUp || type == WebFocusTypeDown) && ScrollbarAlways
Off == verticalMode) |
476 return false; | 476 return false; |
477 LayoutSize size(frame->view()->contentsSize()); | 477 LayoutSize size(frame->view()->contentsSize()); |
478 LayoutSize offset(frame->view()->scrollOffset()); | 478 LayoutSize offset(frame->view()->scrollOffset()); |
479 LayoutRect rect(frame->view()->visibleContentRect(IncludeScrollbars)); | 479 LayoutRect rect(frame->view()->visibleContentRect(IncludeScrollbars)); |
480 | 480 |
481 switch (type) { | 481 switch (type) { |
482 case FocusTypeLeft: | 482 case WebFocusTypeLeft: |
483 return offset.width() > 0; | 483 return offset.width() > 0; |
484 case FocusTypeUp: | 484 case WebFocusTypeUp: |
485 return offset.height() > 0; | 485 return offset.height() > 0; |
486 case FocusTypeRight: | 486 case WebFocusTypeRight: |
487 return rect.width() + offset.width() < size.width(); | 487 return rect.width() + offset.width() < size.width(); |
488 case FocusTypeDown: | 488 case WebFocusTypeDown: |
489 return rect.height() + offset.height() < size.height(); | 489 return rect.height() + offset.height() < size.height(); |
490 default: | 490 default: |
491 ASSERT_NOT_REACHED(); | 491 ASSERT_NOT_REACHED(); |
492 return false; | 492 return false; |
493 } | 493 } |
494 } | 494 } |
495 | 495 |
496 static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const Layo
utRect& initialRect) | 496 static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const Layo
utRect& initialRect) |
497 { | 497 { |
498 LayoutRect rect = initialRect; | 498 LayoutRect rect = initialRect; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 | 530 |
531 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame) | 531 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame) |
532 { | 532 { |
533 return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect())
; | 533 return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect())
; |
534 } | 534 } |
535 | 535 |
536 // This method calculates the exitPoint from the startingRect and the entryPoint
into the candidate rect. | 536 // This method calculates the exitPoint from the startingRect and the entryPoint
into the candidate rect. |
537 // The line between those 2 points is the closest distance between the 2 rects. | 537 // The line between those 2 points is the closest distance between the 2 rects. |
538 // Takes care of overlapping rects, defining points so that the distance between
them | 538 // Takes care of overlapping rects, defining points so that the distance between
them |
539 // is zero where necessary | 539 // is zero where necessary |
540 void entryAndExitPointsForDirection(FocusType type, const LayoutRect& startingRe
ct, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryP
oint) | 540 void entryAndExitPointsForDirection(WebFocusType type, const LayoutRect& startin
gRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& ent
ryPoint) |
541 { | 541 { |
542 switch (type) { | 542 switch (type) { |
543 case FocusTypeLeft: | 543 case WebFocusTypeLeft: |
544 exitPoint.setX(startingRect.x()); | 544 exitPoint.setX(startingRect.x()); |
545 if (potentialRect.maxX() < startingRect.x()) | 545 if (potentialRect.maxX() < startingRect.x()) |
546 entryPoint.setX(potentialRect.maxX()); | 546 entryPoint.setX(potentialRect.maxX()); |
547 else | 547 else |
548 entryPoint.setX(startingRect.x()); | 548 entryPoint.setX(startingRect.x()); |
549 break; | 549 break; |
550 case FocusTypeUp: | 550 case WebFocusTypeUp: |
551 exitPoint.setY(startingRect.y()); | 551 exitPoint.setY(startingRect.y()); |
552 if (potentialRect.maxY() < startingRect.y()) | 552 if (potentialRect.maxY() < startingRect.y()) |
553 entryPoint.setY(potentialRect.maxY()); | 553 entryPoint.setY(potentialRect.maxY()); |
554 else | 554 else |
555 entryPoint.setY(startingRect.y()); | 555 entryPoint.setY(startingRect.y()); |
556 break; | 556 break; |
557 case FocusTypeRight: | 557 case WebFocusTypeRight: |
558 exitPoint.setX(startingRect.maxX()); | 558 exitPoint.setX(startingRect.maxX()); |
559 if (potentialRect.x() > startingRect.maxX()) | 559 if (potentialRect.x() > startingRect.maxX()) |
560 entryPoint.setX(potentialRect.x()); | 560 entryPoint.setX(potentialRect.x()); |
561 else | 561 else |
562 entryPoint.setX(startingRect.maxX()); | 562 entryPoint.setX(startingRect.maxX()); |
563 break; | 563 break; |
564 case FocusTypeDown: | 564 case WebFocusTypeDown: |
565 exitPoint.setY(startingRect.maxY()); | 565 exitPoint.setY(startingRect.maxY()); |
566 if (potentialRect.y() > startingRect.maxY()) | 566 if (potentialRect.y() > startingRect.maxY()) |
567 entryPoint.setY(potentialRect.y()); | 567 entryPoint.setY(potentialRect.y()); |
568 else | 568 else |
569 entryPoint.setY(startingRect.maxY()); | 569 entryPoint.setY(startingRect.maxY()); |
570 break; | 570 break; |
571 default: | 571 default: |
572 ASSERT_NOT_REACHED(); | 572 ASSERT_NOT_REACHED(); |
573 } | 573 } |
574 | 574 |
575 switch (type) { | 575 switch (type) { |
576 case FocusTypeLeft: | 576 case WebFocusTypeLeft: |
577 case FocusTypeRight: | 577 case WebFocusTypeRight: |
578 if (below(startingRect, potentialRect)) { | 578 if (below(startingRect, potentialRect)) { |
579 exitPoint.setY(startingRect.y()); | 579 exitPoint.setY(startingRect.y()); |
580 if (potentialRect.maxY() < startingRect.y()) | 580 if (potentialRect.maxY() < startingRect.y()) |
581 entryPoint.setY(potentialRect.maxY()); | 581 entryPoint.setY(potentialRect.maxY()); |
582 else | 582 else |
583 entryPoint.setY(startingRect.y()); | 583 entryPoint.setY(startingRect.y()); |
584 } else if (below(potentialRect, startingRect)) { | 584 } else if (below(potentialRect, startingRect)) { |
585 exitPoint.setY(startingRect.maxY()); | 585 exitPoint.setY(startingRect.maxY()); |
586 if (potentialRect.y() > startingRect.maxY()) | 586 if (potentialRect.y() > startingRect.maxY()) |
587 entryPoint.setY(potentialRect.y()); | 587 entryPoint.setY(potentialRect.y()); |
588 else | 588 else |
589 entryPoint.setY(startingRect.maxY()); | 589 entryPoint.setY(startingRect.maxY()); |
590 } else { | 590 } else { |
591 exitPoint.setY(max(startingRect.y(), potentialRect.y())); | 591 exitPoint.setY(max(startingRect.y(), potentialRect.y())); |
592 entryPoint.setY(exitPoint.y()); | 592 entryPoint.setY(exitPoint.y()); |
593 } | 593 } |
594 break; | 594 break; |
595 case FocusTypeUp: | 595 case WebFocusTypeUp: |
596 case FocusTypeDown: | 596 case WebFocusTypeDown: |
597 if (rightOf(startingRect, potentialRect)) { | 597 if (rightOf(startingRect, potentialRect)) { |
598 exitPoint.setX(startingRect.x()); | 598 exitPoint.setX(startingRect.x()); |
599 if (potentialRect.maxX() < startingRect.x()) | 599 if (potentialRect.maxX() < startingRect.x()) |
600 entryPoint.setX(potentialRect.maxX()); | 600 entryPoint.setX(potentialRect.maxX()); |
601 else | 601 else |
602 entryPoint.setX(startingRect.x()); | 602 entryPoint.setX(startingRect.x()); |
603 } else if (rightOf(potentialRect, startingRect)) { | 603 } else if (rightOf(potentialRect, startingRect)) { |
604 exitPoint.setX(startingRect.maxX()); | 604 exitPoint.setX(startingRect.maxX()); |
605 if (potentialRect.x() > startingRect.maxX()) | 605 if (potentialRect.x() > startingRect.maxX()) |
606 entryPoint.setX(potentialRect.x()); | 606 entryPoint.setX(potentialRect.x()); |
(...skipping 25 matching lines...) Expand all Loading... |
632 | 632 |
633 if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCand
idate.visibleNode->renderer()->isRenderInline()) | 633 if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCand
idate.visibleNode->renderer()->isRenderInline()) |
634 return false; | 634 return false; |
635 | 635 |
636 if (firstCandidate.visibleNode->renderer()->containingBlock() != secondCandi
date.visibleNode->renderer()->containingBlock()) | 636 if (firstCandidate.visibleNode->renderer()->containingBlock() != secondCandi
date.visibleNode->renderer()->containingBlock()) |
637 return false; | 637 return false; |
638 | 638 |
639 return true; | 639 return true; |
640 } | 640 } |
641 | 641 |
642 void distanceDataForNode(FocusType type, const FocusCandidate& current, FocusCan
didate& candidate) | 642 void distanceDataForNode(WebFocusType type, const FocusCandidate& current, Focus
Candidate& candidate) |
643 { | 643 { |
644 if (areElementsOnSameLine(current, candidate)) { | 644 if (areElementsOnSameLine(current, candidate)) { |
645 if ((type == FocusTypeUp && current.rect.y() > candidate.rect.y()) || (t
ype == FocusTypeDown && candidate.rect.y() > current.rect.y())) { | 645 if ((type == WebFocusTypeUp && current.rect.y() > candidate.rect.y()) ||
(type == WebFocusTypeDown && candidate.rect.y() > current.rect.y())) { |
646 candidate.distance = 0; | 646 candidate.distance = 0; |
647 candidate.alignment = Full; | 647 candidate.alignment = Full; |
648 return; | 648 return; |
649 } | 649 } |
650 } | 650 } |
651 | 651 |
652 LayoutRect nodeRect = candidate.rect; | 652 LayoutRect nodeRect = candidate.rect; |
653 LayoutRect currentRect = current.rect; | 653 LayoutRect currentRect = current.rect; |
654 deflateIfOverlapped(currentRect, nodeRect); | 654 deflateIfOverlapped(currentRect, nodeRect); |
655 | 655 |
656 if (!isRectInDirection(type, currentRect, nodeRect)) | 656 if (!isRectInDirection(type, currentRect, nodeRect)) |
657 return; | 657 return; |
658 | 658 |
659 LayoutPoint exitPoint; | 659 LayoutPoint exitPoint; |
660 LayoutPoint entryPoint; | 660 LayoutPoint entryPoint; |
661 entryAndExitPointsForDirection(type, currentRect, nodeRect, exitPoint, entry
Point); | 661 entryAndExitPointsForDirection(type, currentRect, nodeRect, exitPoint, entry
Point); |
662 | 662 |
663 LayoutUnit xAxis = exitPoint.x() - entryPoint.x(); | 663 LayoutUnit xAxis = exitPoint.x() - entryPoint.x(); |
664 LayoutUnit yAxis = exitPoint.y() - entryPoint.y(); | 664 LayoutUnit yAxis = exitPoint.y() - entryPoint.y(); |
665 | 665 |
666 LayoutUnit navigationAxisDistance; | 666 LayoutUnit navigationAxisDistance; |
667 LayoutUnit orthogonalAxisDistance; | 667 LayoutUnit orthogonalAxisDistance; |
668 | 668 |
669 switch (type) { | 669 switch (type) { |
670 case FocusTypeLeft: | 670 case WebFocusTypeLeft: |
671 case FocusTypeRight: | 671 case WebFocusTypeRight: |
672 navigationAxisDistance = xAxis.abs(); | 672 navigationAxisDistance = xAxis.abs(); |
673 orthogonalAxisDistance = yAxis.abs(); | 673 orthogonalAxisDistance = yAxis.abs(); |
674 break; | 674 break; |
675 case FocusTypeUp: | 675 case WebFocusTypeUp: |
676 case FocusTypeDown: | 676 case WebFocusTypeDown: |
677 navigationAxisDistance = yAxis.abs(); | 677 navigationAxisDistance = yAxis.abs(); |
678 orthogonalAxisDistance = xAxis.abs(); | 678 orthogonalAxisDistance = xAxis.abs(); |
679 break; | 679 break; |
680 default: | 680 default: |
681 ASSERT_NOT_REACHED(); | 681 ASSERT_NOT_REACHED(); |
682 return; | 682 return; |
683 } | 683 } |
684 | 684 |
685 double euclidianDistancePow2 = (xAxis * xAxis + yAxis * yAxis).toDouble(); | 685 double euclidianDistancePow2 = (xAxis * xAxis + yAxis * yAxis).toDouble(); |
686 LayoutRect intersectionRect = intersection(currentRect, nodeRect); | 686 LayoutRect intersectionRect = intersection(currentRect, nodeRect); |
687 double overlap = (intersectionRect.width() * intersectionRect.height()).toDo
uble(); | 687 double overlap = (intersectionRect.width() * intersectionRect.height()).toDo
uble(); |
688 | 688 |
689 // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handlin
g | 689 // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handlin
g |
690 candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance+ o
rthogonalAxisDistance * 2 - sqrt(overlap); | 690 candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance+ o
rthogonalAxisDistance * 2 - sqrt(overlap); |
691 | 691 |
692 LayoutSize viewSize = LayoutSize(candidate.visibleNode->document().page()->d
eprecatedLocalMainFrame()->view()->visibleContentRect().size()); | 692 LayoutSize viewSize = LayoutSize(candidate.visibleNode->document().page()->d
eprecatedLocalMainFrame()->view()->visibleContentRect().size()); |
693 candidate.alignment = alignmentForRects(type, currentRect, nodeRect, viewSiz
e); | 693 candidate.alignment = alignmentForRects(type, currentRect, nodeRect, viewSiz
e); |
694 } | 694 } |
695 | 695 |
696 bool canBeScrolledIntoView(FocusType type, const FocusCandidate& candidate) | 696 bool canBeScrolledIntoView(WebFocusType type, const FocusCandidate& candidate) |
697 { | 697 { |
698 ASSERT(candidate.visibleNode && candidate.isOffscreen); | 698 ASSERT(candidate.visibleNode && candidate.isOffscreen); |
699 LayoutRect candidateRect = candidate.rect; | 699 LayoutRect candidateRect = candidate.rect; |
700 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { | 700 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { |
701 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); | 701 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); |
702 if (!candidateRect.intersects(parentRect)) { | 702 if (!candidateRect.intersects(parentRect)) { |
703 if (((type == FocusTypeLeft || type == FocusTypeRight) && parentNode
->renderer()->style()->overflowX() == OHIDDEN) | 703 if (((type == WebFocusTypeLeft || type == WebFocusTypeRight) && pare
ntNode->renderer()->style()->overflowX() == OHIDDEN) |
704 || ((type == FocusTypeUp || type == FocusTypeDown) && parentNode
->renderer()->style()->overflowY() == OHIDDEN)) | 704 || ((type == WebFocusTypeUp || type == WebFocusTypeDown) && pare
ntNode->renderer()->style()->overflowY() == OHIDDEN)) |
705 return false; | 705 return false; |
706 } | 706 } |
707 if (parentNode == candidate.enclosingScrollableBox) | 707 if (parentNode == candidate.enclosingScrollableBox) |
708 return canScrollInDirection(parentNode, type); | 708 return canScrollInDirection(parentNode, type); |
709 } | 709 } |
710 return true; | 710 return true; |
711 } | 711 } |
712 | 712 |
713 // The starting rect is the rect of the focused node, in document coordinates. | 713 // The starting rect is the rect of the focused node, in document coordinates. |
714 // Compose a virtual starting rect if there is no focused node or if it is off s
creen. | 714 // Compose a virtual starting rect if there is no focused node or if it is off s
creen. |
715 // The virtual rect is the edge of the container or frame. We select which | 715 // The virtual rect is the edge of the container or frame. We select which |
716 // edge depending on the direction of the navigation. | 716 // edge depending on the direction of the navigation. |
717 LayoutRect virtualRectForDirection(FocusType type, const LayoutRect& startingRec
t, LayoutUnit width) | 717 LayoutRect virtualRectForDirection(WebFocusType type, const LayoutRect& starting
Rect, LayoutUnit width) |
718 { | 718 { |
719 LayoutRect virtualStartingRect = startingRect; | 719 LayoutRect virtualStartingRect = startingRect; |
720 switch (type) { | 720 switch (type) { |
721 case FocusTypeLeft: | 721 case WebFocusTypeLeft: |
722 virtualStartingRect.setX(virtualStartingRect.maxX() - width); | 722 virtualStartingRect.setX(virtualStartingRect.maxX() - width); |
723 virtualStartingRect.setWidth(width); | 723 virtualStartingRect.setWidth(width); |
724 break; | 724 break; |
725 case FocusTypeUp: | 725 case WebFocusTypeUp: |
726 virtualStartingRect.setY(virtualStartingRect.maxY() - width); | 726 virtualStartingRect.setY(virtualStartingRect.maxY() - width); |
727 virtualStartingRect.setHeight(width); | 727 virtualStartingRect.setHeight(width); |
728 break; | 728 break; |
729 case FocusTypeRight: | 729 case WebFocusTypeRight: |
730 virtualStartingRect.setWidth(width); | 730 virtualStartingRect.setWidth(width); |
731 break; | 731 break; |
732 case FocusTypeDown: | 732 case WebFocusTypeDown: |
733 virtualStartingRect.setHeight(width); | 733 virtualStartingRect.setHeight(width); |
734 break; | 734 break; |
735 default: | 735 default: |
736 ASSERT_NOT_REACHED(); | 736 ASSERT_NOT_REACHED(); |
737 } | 737 } |
738 | 738 |
739 return virtualStartingRect; | 739 return virtualStartingRect; |
740 } | 740 } |
741 | 741 |
742 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, FocusTyp
e type) | 742 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, WebFocus
Type type) |
743 { | 743 { |
744 ASSERT(area.imageElement()); | 744 ASSERT(area.imageElement()); |
745 // Area elements tend to overlap more than other focusable elements. We flat
ten the rect of the area elements | 745 // Area elements tend to overlap more than other focusable elements. We flat
ten the rect of the area elements |
746 // to minimize the effect of overlapping areas. | 746 // to minimize the effect of overlapping areas. |
747 LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(ar
ea.document().frame(), area.computeRect(area.imageElement()->renderer())), 1); | 747 LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(ar
ea.document().frame(), area.computeRect(area.imageElement()->renderer())), 1); |
748 return rect; | 748 return rect; |
749 } | 749 } |
750 | 750 |
751 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) | 751 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) |
752 { | 752 { |
753 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : nullptr; | 753 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : nullptr; |
754 }; | 754 }; |
755 | 755 |
756 } // namespace blink | 756 } // namespace blink |
OLD | NEW |