| 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 } | 285 } |
| 286 | 286 |
| 287 // Checks if |node| is offscreen the visible area (viewport) of its container | 287 // Checks if |node| is offscreen the visible area (viewport) of its container |
| 288 // document. In case it is, one can scroll in direction or take any different | 288 // document. In case it is, one can scroll in direction or take any different |
| 289 // desired action later on. | 289 // desired action later on. |
| 290 bool hasOffscreenRect(Node* node, FocusDirection direction) | 290 bool hasOffscreenRect(Node* node, FocusDirection direction) |
| 291 { | 291 { |
| 292 // Get the FrameView in which |node| is (which means the current viewport if
|node| | 292 // Get the FrameView in which |node| is (which means the current viewport if
|node| |
| 293 // is not in an inner document), so we can check if its content rect is visi
ble | 293 // is not in an inner document), so we can check if its content rect is visi
ble |
| 294 // before we actually move the focus to it. | 294 // before we actually move the focus to it. |
| 295 FrameView* frameView = node->document()->view(); | 295 FrameView* frameView = node->document().view(); |
| 296 if (!frameView) | 296 if (!frameView) |
| 297 return true; | 297 return true; |
| 298 | 298 |
| 299 ASSERT(!frameView->needsLayout()); | 299 ASSERT(!frameView->needsLayout()); |
| 300 | 300 |
| 301 LayoutRect containerViewportRect = frameView->visibleContentRect(); | 301 LayoutRect containerViewportRect = frameView->visibleContentRect(); |
| 302 // We want to select a node if it is currently off screen, but will be | 302 // We want to select a node if it is currently off screen, but will be |
| 303 // exposed after we scroll. Adjust the viewport to post-scrolling position. | 303 // exposed after we scroll. Adjust the viewport to post-scrolling position. |
| 304 // If the container has overflow:hidden, we cannot scroll, so we do not pass
direction | 304 // If the container has overflow:hidden, we cannot scroll, so we do not pass
direction |
| 305 // and we do not adjust for scrolling. | 305 // and we do not adjust for scrolling. |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 | 430 |
| 431 return false; | 431 return false; |
| 432 } | 432 } |
| 433 | 433 |
| 434 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection direc
tion, Node* node) | 434 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection direc
tion, Node* node) |
| 435 { | 435 { |
| 436 ASSERT(node); | 436 ASSERT(node); |
| 437 Node* parent = node; | 437 Node* parent = node; |
| 438 do { | 438 do { |
| 439 if (parent->isDocumentNode()) | 439 if (parent->isDocumentNode()) |
| 440 parent = toDocument(parent)->document()->frame()->ownerElement(); | 440 parent = toDocument(parent)->document().frame()->ownerElement(); |
| 441 else | 441 else |
| 442 parent = parent->parentOrShadowHostNode(); | 442 parent = parent->parentOrShadowHostNode(); |
| 443 } while (parent && !canScrollInDirection(parent, direction) && !parent->isDo
cumentNode()); | 443 } while (parent && !canScrollInDirection(parent, direction) && !parent->isDo
cumentNode()); |
| 444 | 444 |
| 445 return parent; | 445 return parent; |
| 446 } | 446 } |
| 447 | 447 |
| 448 bool canScrollInDirection(const Node* container, FocusDirection direction) | 448 bool canScrollInDirection(const Node* container, FocusDirection direction) |
| 449 { | 449 { |
| 450 ASSERT(container); | 450 ASSERT(container); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 rect.move(element->offsetLeft(), element->offsetTop()); | 508 rect.move(element->offsetLeft(), element->offsetTop()); |
| 509 } while ((element = element->offsetParent())); | 509 } while ((element = element->offsetParent())); |
| 510 rect.move((-frame->view()->scrollOffset())); | 510 rect.move((-frame->view()->scrollOffset())); |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 return rect; | 513 return rect; |
| 514 } | 514 } |
| 515 | 515 |
| 516 LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) | 516 LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) |
| 517 { | 517 { |
| 518 ASSERT(node && node->renderer() && !node->document()->view()->needsLayout())
; | 518 ASSERT(node && node->renderer() && !node->document().view()->needsLayout()); |
| 519 | 519 |
| 520 if (node->isDocumentNode()) | 520 if (node->isDocumentNode()) |
| 521 return frameRectInAbsoluteCoordinates(toDocument(node)->frame()); | 521 return frameRectInAbsoluteCoordinates(toDocument(node)->frame()); |
| 522 LayoutRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node-
>boundingBox()); | 522 LayoutRect rect = rectToAbsoluteCoordinates(node->document().frame(), node->
boundingBox()); |
| 523 | 523 |
| 524 // For authors that use border instead of outline in their CSS, we compensat
e by ignoring the border when calculating | 524 // For authors that use border instead of outline in their CSS, we compensat
e by ignoring the border when calculating |
| 525 // the rect of the focused element. | 525 // the rect of the focused element. |
| 526 if (ignoreBorder) { | 526 if (ignoreBorder) { |
| 527 rect.move(node->renderer()->style()->borderLeftWidth(), node->renderer()
->style()->borderTopWidth()); | 527 rect.move(node->renderer()->style()->borderLeftWidth(), node->renderer()
->style()->borderTopWidth()); |
| 528 rect.setWidth(rect.width() - node->renderer()->style()->borderLeftWidth(
) - node->renderer()->style()->borderRightWidth()); | 528 rect.setWidth(rect.width() - node->renderer()->style()->borderLeftWidth(
) - node->renderer()->style()->borderRightWidth()); |
| 529 rect.setHeight(rect.height() - node->renderer()->style()->borderTopWidth
() - node->renderer()->style()->borderBottomWidth()); | 529 rect.setHeight(rect.height() - node->renderer()->style()->borderTopWidth
() - node->renderer()->style()->borderBottomWidth()); |
| 530 } | 530 } |
| 531 return rect; | 531 return rect; |
| 532 } | 532 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 float x = (entryPoint.x() - exitPoint.x()) * (entryPoint.x() - exitPoint.x()
); | 664 float x = (entryPoint.x() - exitPoint.x()) * (entryPoint.x() - exitPoint.x()
); |
| 665 float y = (entryPoint.y() - exitPoint.y()) * (entryPoint.y() - exitPoint.y()
); | 665 float y = (entryPoint.y() - exitPoint.y()) * (entryPoint.y() - exitPoint.y()
); |
| 666 | 666 |
| 667 float euclidianDistance = sqrt(x + y); | 667 float euclidianDistance = sqrt(x + y); |
| 668 | 668 |
| 669 // Loosely based on http://www.w3.org/TR/WICD/#focus-handling | 669 // Loosely based on http://www.w3.org/TR/WICD/#focus-handling |
| 670 // df = dotDist + dx + dy + 2 * (xdisplacement + ydisplacement) - sqrt(Overl
ap) | 670 // df = dotDist + dx + dy + 2 * (xdisplacement + ydisplacement) - sqrt(Overl
ap) |
| 671 | 671 |
| 672 float distance = euclidianDistance + sameAxisDistance + 2 * otherAxisDistanc
e; | 672 float distance = euclidianDistance + sameAxisDistance + 2 * otherAxisDistanc
e; |
| 673 candidate.distance = roundf(distance); | 673 candidate.distance = roundf(distance); |
| 674 LayoutSize viewSize = candidate.visibleNode->document()->page()->mainFrame()
->view()->visibleContentRect().size(); | 674 LayoutSize viewSize = candidate.visibleNode->document().page()->mainFrame()-
>view()->visibleContentRect().size(); |
| 675 candidate.alignment = alignmentForRects(direction, currentRect, nodeRect, vi
ewSize); | 675 candidate.alignment = alignmentForRects(direction, currentRect, nodeRect, vi
ewSize); |
| 676 } | 676 } |
| 677 | 677 |
| 678 bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candi
date) | 678 bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candi
date) |
| 679 { | 679 { |
| 680 ASSERT(candidate.visibleNode && candidate.isOffscreen); | 680 ASSERT(candidate.visibleNode && candidate.isOffscreen); |
| 681 LayoutRect candidateRect = candidate.rect; | 681 LayoutRect candidateRect = candidate.rect; |
| 682 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { | 682 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { |
| 683 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); | 683 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); |
| 684 if (!candidateRect.intersects(parentRect)) { | 684 if (!candidateRect.intersects(parentRect)) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 | 720 |
| 721 return virtualStartingRect; | 721 return virtualStartingRect; |
| 722 } | 722 } |
| 723 | 723 |
| 724 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusDir
ection direction) | 724 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusDir
ection direction) |
| 725 { | 725 { |
| 726 ASSERT(area); | 726 ASSERT(area); |
| 727 ASSERT(area->imageElement()); | 727 ASSERT(area->imageElement()); |
| 728 // Area elements tend to overlap more than other focusable elements. We flat
ten the rect of the area elements | 728 // Area elements tend to overlap more than other focusable elements. We flat
ten the rect of the area elements |
| 729 // to minimize the effect of overlapping areas. | 729 // to minimize the effect of overlapping areas. |
| 730 LayoutRect rect = virtualRectForDirection(direction, rectToAbsoluteCoordinat
es(area->document()->frame(), area->computeRect(area->imageElement()->renderer()
)), 1); | 730 LayoutRect rect = virtualRectForDirection(direction, rectToAbsoluteCoordinat
es(area->document().frame(), area->computeRect(area->imageElement()->renderer())
), 1); |
| 731 return rect; | 731 return rect; |
| 732 } | 732 } |
| 733 | 733 |
| 734 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) | 734 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) |
| 735 { | 735 { |
| 736 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : 0; | 736 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : 0; |
| 737 }; | 737 }; |
| 738 | 738 |
| 739 } // namespace WebCore | 739 } // namespace WebCore |
| OLD | NEW |