| 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 |