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 |