Changeset 93270 in webkit
- Timestamp:
- Aug 17, 2011 5:49:01 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r93269 r93270 1 2011-08-17 Emil A Eklund <eae@chromium.org> 2 3 Switch focus handling to to new layout types 4 https://bugs.webkit.org/show_bug.cgi?id=66331 5 6 Reviewed by Eric Seidel. 7 8 Convert FocusController and SpatialNavigation to new layout abstraction 9 as a part of the ongoing conversion work. 10 11 No new tests, no new functionality. 12 13 * page/FocusController.cpp: 14 (WebCore::updateFocusCandidateIfNeeded): 15 (WebCore::FocusController::findFocusCandidateInContainer): 16 (WebCore::FocusController::advanceFocusDirectionallyInContainer): 17 (WebCore::FocusController::advanceFocusDirectionally): 18 * page/FocusController.h: 19 * page/SpatialNavigation.cpp: 20 (WebCore::alignmentForRects): 21 (WebCore::start): 22 (WebCore::middle): 23 (WebCore::end): 24 (WebCore::areRectsFullyAligned): 25 (WebCore::areRectsPartiallyAligned): 26 (WebCore::areRectsMoreThanFullScreenApart): 27 (WebCore::below): 28 (WebCore::rightOf): 29 (WebCore::isRectInDirection): 30 (WebCore::hasOffscreenRect): 31 (WebCore::scrollInDirection): 32 (WebCore::deflateIfOverlapped): 33 (WebCore::canScrollInDirection): 34 (WebCore::rectToAbsoluteCoordinates): 35 (WebCore::nodeRectInAbsoluteCoordinates): 36 (WebCore::frameRectInAbsoluteCoordinates): 37 (WebCore::entryAndExitPointsForDirection): 38 (WebCore::distanceDataForNode): 39 (WebCore::canBeScrolledIntoView): 40 (WebCore::virtualRectForDirection): 41 (WebCore::virtualRectForAreaElementAndDirection): 42 * page/SpatialNavigation.h: 43 1 44 2011-08-17 Levi Weintraub <leviw@chromium.org> 2 45 -
trunk/Source/WebCore/page/FocusController.cpp
r90004 r93270 612 612 } 613 613 614 IntRect intersectionRect = intersection(candidate.rect, closest.rect);614 LayoutRect intersectionRect = intersection(candidate.rect, closest.rect); 615 615 if (!intersectionRect.isEmpty() && !areElementsOnSameLine(closest, candidate)) { 616 616 // If 2 nodes are intersecting, do hit test to find which node in on top. 617 int x = intersectionRect.x() + intersectionRect.width() / 2;618 int y = intersectionRect.y() + intersectionRect.height() / 2;617 LayoutUnit x = intersectionRect.x() + intersectionRect.width() / 2; 618 LayoutUnit y = intersectionRect.y() + intersectionRect.height() / 2; 619 619 HitTestResult result = candidate.visibleNode->document()->page()->mainFrame()->eventHandler()->hitTestResultAtPoint(IntPoint(x, y), false, true); 620 620 if (candidate.visibleNode->contains(result.innerNode())) { … … 636 636 } 637 637 638 void FocusController::findFocusCandidateInContainer(Node* container, const IntRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest)638 void FocusController::findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest) 639 639 { 640 640 ASSERT(container); … … 666 666 } 667 667 668 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, const IntRect& startingRect, FocusDirection direction, KeyboardEvent* event)668 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event) 669 669 { 670 670 if (!container || !container->document()) 671 671 return false; 672 672 673 IntRect newStartingRect = startingRect;673 LayoutRect newStartingRect = startingRect; 674 674 675 675 if (startingRect.isEmpty()) … … 698 698 } 699 699 // Navigate into a new frame. 700 IntRect rect;700 LayoutRect rect; 701 701 Node* focusedNode = focusedOrMainFrame()->document()->focusedNode(); 702 702 if (focusedNode && !hasOffscreenRect(focusedNode)) … … 716 716 } 717 717 // Navigate into a new scrollable container. 718 IntRect startingRect;718 LayoutRect startingRect; 719 719 Node* focusedNode = focusedOrMainFrame()->document()->focusedNode(); 720 720 if (focusedNode && !hasOffscreenRect(focusedNode)) … … 752 752 753 753 // Figure out the starting rect. 754 IntRect startingRect;754 LayoutRect startingRect; 755 755 if (focusedNode) { 756 756 if (!hasOffscreenRect(focusedNode)) { -
trunk/Source/WebCore/page/FocusController.h
r90004 r93270 28 28 29 29 #include "FocusDirection.h" 30 #include "LayoutTypes.h" 30 31 #include <wtf/Forward.h> 31 32 #include <wtf/Noncopyable.h> … … 86 87 Node* previousFocusableNode(TreeScope*, Node* start, KeyboardEvent*); 87 88 88 bool advanceFocusDirectionallyInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*);89 void findFocusCandidateInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest);89 bool advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusDirection, KeyboardEvent*); 90 void findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest); 90 91 91 92 Page* m_page; -
trunk/Source/WebCore/page/SpatialNavigation.cpp
r87616 r93270 46 46 namespace WebCore { 47 47 48 static RectsAlignment alignmentForRects(FocusDirection, const IntRect&, const IntRect&, const IntSize& viewSize);49 static bool areRectsFullyAligned(FocusDirection, const IntRect&, const IntRect&);50 static bool areRectsPartiallyAligned(FocusDirection, const IntRect&, const IntRect&);51 static bool areRectsMoreThanFullScreenApart(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect, const IntSize& viewSize);52 static bool isRectInDirection(FocusDirection, const IntRect&, const IntRect&);53 static void deflateIfOverlapped( IntRect&, IntRect&);54 static IntRect rectToAbsoluteCoordinates(Frame* initialFrame, const IntRect&);55 static void entryAndExitPointsForDirection(FocusDirection direction, const IntRect& startingRect, const IntRect& potentialRect, IntPoint& exitPoint, IntPoint& entryPoint);48 static RectsAlignment alignmentForRects(FocusDirection, const LayoutRect&, const LayoutRect&, const LayoutSize& viewSize); 49 static bool areRectsFullyAligned(FocusDirection, const LayoutRect&, const LayoutRect&); 50 static bool areRectsPartiallyAligned(FocusDirection, const LayoutRect&, const LayoutRect&); 51 static bool areRectsMoreThanFullScreenApart(FocusDirection, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize); 52 static bool isRectInDirection(FocusDirection, const LayoutRect&, const LayoutRect&); 53 static void deflateIfOverlapped(LayoutRect&, LayoutRect&); 54 static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect&); 55 static void entryAndExitPointsForDirection(FocusDirection, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint); 56 56 static bool isScrollableNode(const Node*); 57 57 … … 96 96 } 97 97 98 static RectsAlignment alignmentForRects(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect, const IntSize& viewSize)98 static RectsAlignment alignmentForRects(FocusDirection direction, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize) 99 99 { 100 100 // If we found a node in full alignment, but it is too far away, ignore it. … … 116 116 } 117 117 118 static inline int start(FocusDirection direction, const IntRect& rect)118 static inline LayoutUnit start(FocusDirection direction, const LayoutRect& rect) 119 119 { 120 120 return isHorizontalMove(direction) ? rect.y() : rect.x(); 121 121 } 122 122 123 static inline int middle(FocusDirection direction, const IntRect& rect)124 { 125 IntPoint center(rect.center());123 static inline LayoutUnit middle(FocusDirection direction, const LayoutRect& rect) 124 { 125 LayoutPoint center(rect.center()); 126 126 return isHorizontalMove(direction) ? center.y(): center.x(); 127 127 } 128 128 129 static inline int end(FocusDirection direction, const IntRect& rect)129 static inline LayoutUnit end(FocusDirection direction, const LayoutRect& rect) 130 130 { 131 131 return isHorizontalMove(direction) ? rect.maxY() : rect.maxX(); … … 139 139 // * a = Current focused node's rect. 140 140 // * b = Focus candidate node's rect. 141 static bool areRectsFullyAligned(FocusDirection direction, const IntRect& a, const IntRect& b)142 { 143 int aStart, bStart, aEnd, bEnd;141 static bool areRectsFullyAligned(FocusDirection direction, const LayoutRect& a, const LayoutRect& b) 142 { 143 LayoutUnit aStart, bStart, aEnd, bEnd; 144 144 145 145 switch (direction) { … … 171 171 bStart = start(direction, b); 172 172 173 int aMiddle = middle(direction, a);174 int bMiddle = middle(direction, b);173 LayoutUnit aMiddle = middle(direction, a); 174 LayoutUnit bMiddle = middle(direction, b); 175 175 176 176 aEnd = end(direction, a); … … 211 211 // * a = Current focused node's rect. 212 212 // * b = Focus candidate node's rect. 213 static bool areRectsPartiallyAligned(FocusDirection direction, const IntRect& a, const IntRect& b)214 { 215 int aStart = start(direction, a);216 int bStart = start(direction, b);217 int bMiddle = middle(direction, b);218 int aEnd = end(direction, a);219 int bEnd = end(direction, b);213 static bool areRectsPartiallyAligned(FocusDirection direction, const LayoutRect& a, const LayoutRect& b) 214 { 215 LayoutUnit aStart = start(direction, a); 216 LayoutUnit bStart = start(direction, b); 217 LayoutUnit bMiddle = middle(direction, b); 218 LayoutUnit aEnd = end(direction, a); 219 LayoutUnit bEnd = end(direction, b); 220 220 221 221 // Picture of the partially aligned logic: … … 240 240 } 241 241 242 static bool areRectsMoreThanFullScreenApart(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect, const IntSize& viewSize)242 static bool areRectsMoreThanFullScreenApart(FocusDirection direction, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize) 243 243 { 244 244 ASSERT(isRectInDirection(direction, curRect, targetRect)); … … 260 260 261 261 // Return true if rect |a| is below |b|. False otherwise. 262 static inline bool below(const IntRect& a, const IntRect& b)262 static inline bool below(const LayoutRect& a, const LayoutRect& b) 263 263 { 264 264 return a.y() > b.maxY(); … … 266 266 267 267 // Return true if rect |a| is on the right of |b|. False otherwise. 268 static inline bool rightOf(const IntRect& a, const IntRect& b)268 static inline bool rightOf(const LayoutRect& a, const LayoutRect& b) 269 269 { 270 270 return a.x() > b.maxX(); 271 271 } 272 272 273 static bool isRectInDirection(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect)273 static bool isRectInDirection(FocusDirection direction, const LayoutRect& curRect, const LayoutRect& targetRect) 274 274 { 275 275 switch (direction) { … … 302 302 ASSERT(!frameView->needsLayout()); 303 303 304 IntRect containerViewportRect = frameView->visibleContentRect();304 LayoutRect containerViewportRect = frameView->visibleContentRect(); 305 305 // We want to select a node if it is currently off screen, but will be 306 306 // exposed after we scroll. Adjust the viewport to post-scrolling position. … … 330 330 return true; 331 331 332 IntRect rect(render->absoluteClippedOverflowRect());332 LayoutRect rect(render->absoluteClippedOverflowRect()); 333 333 if (rect.isEmpty()) 334 334 return true; … … 342 342 343 343 if (frame && canScrollInDirection(frame->document(), direction)) { 344 int dx = 0;345 int dy = 0;344 LayoutUnit dx = 0; 345 LayoutUnit dy = 0; 346 346 switch (direction) { 347 347 case FocusDirectionLeft: … … 362 362 } 363 363 364 frame->view()->scrollBy( IntSize(dx, dy));364 frame->view()->scrollBy(LayoutSize(dx, dy)); 365 365 return true; 366 366 } … … 378 378 379 379 if (canScrollInDirection(container, direction)) { 380 int dx = 0;381 int dy = 0;380 LayoutUnit dx = 0; 381 LayoutUnit dy = 0; 382 382 switch (direction) { 383 383 case FocusDirectionLeft: 384 dx = - min (Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollLeft());384 dx = - min<LayoutUnit>(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollLeft()); 385 385 break; 386 386 case FocusDirectionRight: 387 387 ASSERT(container->renderBox()->scrollWidth() > (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth())); 388 dx = min (Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollWidth() - (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth()));388 dx = min<LayoutUnit>(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollWidth() - (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth())); 389 389 break; 390 390 case FocusDirectionUp: 391 dy = - min (Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollTop());391 dy = - min<LayoutUnit>(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollTop()); 392 392 break; 393 393 case FocusDirectionDown: 394 394 ASSERT(container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight())); 395 dy = min (Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight()));395 dy = min<LayoutUnit>(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight())); 396 396 break; 397 397 default: … … 407 407 } 408 408 409 static void deflateIfOverlapped( IntRect& a, IntRect& b)409 static void deflateIfOverlapped(LayoutRect& a, LayoutRect& b) 410 410 { 411 411 if (!a.intersects(b) || a.contains(b) || b.contains(a)) 412 412 return; 413 413 414 int deflateFactor = -fudgeFactor();414 LayoutUnit deflateFactor = -fudgeFactor(); 415 415 416 416 // Avoid negative width or height values. … … 484 484 if ((direction == FocusDirectionUp || direction == FocusDirectionDown) && ScrollbarAlwaysOff == verticalMode) 485 485 return false; 486 IntSize size = frame->view()->contentsSize();487 IntSize offset = frame->view()->scrollOffset();488 IntRect rect = frame->view()->visibleContentRect(true);486 LayoutSize size = frame->view()->contentsSize(); 487 LayoutSize offset = frame->view()->scrollOffset(); 488 LayoutRect rect = frame->view()->visibleContentRect(true); 489 489 490 490 switch (direction) { … … 503 503 } 504 504 505 static IntRect rectToAbsoluteCoordinates(Frame* initialFrame, const IntRect& initialRect)506 { 507 IntRect rect = initialRect;505 static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect) 506 { 507 LayoutRect rect = initialRect; 508 508 for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) { 509 509 if (Element* element = static_cast<Element*>(frame->ownerElement())) { … … 517 517 } 518 518 519 IntRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder)519 LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) 520 520 { 521 521 ASSERT(node && node->renderer() && !node->document()->view()->needsLayout()); … … 523 523 if (node->isDocumentNode()) 524 524 return frameRectInAbsoluteCoordinates(static_cast<Document*>(node)->frame()); 525 IntRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node->getRect());525 LayoutRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node->getRect()); 526 526 527 527 // For authors that use border instead of outline in their CSS, we compensate by ignoring the border when calculating … … 535 535 } 536 536 537 IntRect frameRectInAbsoluteCoordinates(Frame* frame)537 LayoutRect frameRectInAbsoluteCoordinates(Frame* frame) 538 538 { 539 539 return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect()); … … 542 542 // This method calculates the exitPoint from the startingRect and the entryPoint into the candidate rect. 543 543 // The line between those 2 points is the closest distance between the 2 rects. 544 void entryAndExitPointsForDirection(FocusDirection direction, const IntRect& startingRect, const IntRect& potentialRect, IntPoint& exitPoint, IntPoint& entryPoint)544 void entryAndExitPointsForDirection(FocusDirection direction, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint) 545 545 { 546 546 switch (direction) { … … 630 630 } 631 631 632 IntRect nodeRect = candidate.rect;633 IntRect currentRect = current.rect;632 LayoutRect nodeRect = candidate.rect; 633 LayoutRect currentRect = current.rect; 634 634 deflateIfOverlapped(currentRect, nodeRect); 635 635 … … 637 637 return; 638 638 639 IntPoint exitPoint;640 IntPoint entryPoint;641 int sameAxisDistance = 0;642 int otherAxisDistance = 0;639 LayoutPoint exitPoint; 640 LayoutPoint entryPoint; 641 LayoutUnit sameAxisDistance = 0; 642 LayoutUnit otherAxisDistance = 0; 643 643 entryAndExitPointsForDirection(direction, currentRect, nodeRect, exitPoint, entryPoint); 644 644 … … 665 665 } 666 666 667 int x = (entryPoint.x() - exitPoint.x()) * (entryPoint.x() - exitPoint.x());668 int y = (entryPoint.y() - exitPoint.y()) * (entryPoint.y() - exitPoint.y());667 LayoutUnit x = (entryPoint.x() - exitPoint.x()) * (entryPoint.x() - exitPoint.x()); 668 LayoutUnit y = (entryPoint.y() - exitPoint.y()) * (entryPoint.y() - exitPoint.y()); 669 669 670 670 float euclidianDistance = sqrt((x + y) * 1.0f); … … 675 675 float distance = euclidianDistance + sameAxisDistance + 2 * otherAxisDistance; 676 676 candidate.distance = roundf(distance); 677 IntSize viewSize = candidate.visibleNode->document()->page()->mainFrame()->view()->visibleContentRect().size();677 LayoutSize viewSize = candidate.visibleNode->document()->page()->mainFrame()->view()->visibleContentRect().size(); 678 678 candidate.alignment = alignmentForRects(direction, currentRect, nodeRect, viewSize); 679 679 } … … 682 682 { 683 683 ASSERT(candidate.visibleNode && candidate.isOffscreen); 684 IntRect candidateRect = candidate.rect;684 LayoutRect candidateRect = candidate.rect; 685 685 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; parentNode = parentNode->parentNode()) { 686 IntRect parentRect = nodeRectInAbsoluteCoordinates(parentNode);686 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); 687 687 if (!candidateRect.intersects(parentRect)) { 688 688 if (((direction == FocusDirectionLeft || direction == FocusDirectionRight) && parentNode->renderer()->style()->overflowX() == OHIDDEN) … … 700 700 // The virtual rect is the edge of the container or frame. We select which 701 701 // edge depending on the direction of the navigation. 702 IntRect virtualRectForDirection(FocusDirection direction, const IntRect& startingRect, int width)703 { 704 IntRect virtualStartingRect = startingRect;702 LayoutRect virtualRectForDirection(FocusDirection direction, const LayoutRect& startingRect, LayoutUnit width) 703 { 704 LayoutRect virtualStartingRect = startingRect; 705 705 switch (direction) { 706 706 case FocusDirectionLeft: … … 725 725 } 726 726 727 IntRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusDirection direction)727 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusDirection direction) 728 728 { 729 729 ASSERT(area); … … 731 731 // Area elements tend to overlap more than other focusable elements. We flatten the rect of the area elements 732 732 // to minimize the effect of overlapping areas. 733 IntRect rect = virtualRectForDirection(direction, rectToAbsoluteCoordinates(area->document()->frame(), area->computeRect(area->imageElement()->renderer())), 1);733 LayoutRect rect = virtualRectForDirection(direction, rectToAbsoluteCoordinates(area->document()->frame(), area->computeRect(area->imageElement()->renderer())), 1); 734 734 return rect; 735 735 } -
trunk/Source/WebCore/page/SpatialNavigation.h
r79021 r93270 24 24 #include "FocusDirection.h" 25 25 #include "HTMLFrameOwnerElement.h" 26 #include " IntRect.h"26 #include "LayoutTypes.h" 27 27 #include "Node.h" 28 28 … … 131 131 RectsAlignment alignment; 132 132 RectsAlignment parentAlignment; 133 IntRect rect;133 LayoutRect rect; 134 134 bool isOffscreen; 135 135 bool isOffscreenAfterScrolling; … … 145 145 void distanceDataForNode(FocusDirection, const FocusCandidate& current, FocusCandidate& candidate); 146 146 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection, Node*); 147 IntRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false);148 IntRect frameRectInAbsoluteCoordinates(Frame*);149 IntRect virtualRectForDirection(FocusDirection, const IntRect& startingRect, int width = 0);150 IntRect virtualRectForAreaElementAndDirection(HTMLAreaElement*, FocusDirection);147 LayoutRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false); 148 LayoutRect frameRectInAbsoluteCoordinates(Frame*); 149 LayoutRect virtualRectForDirection(FocusDirection, const LayoutRect& startingRect, LayoutUnit width = 0); 150 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement*, FocusDirection); 151 151 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate&); 152 152
Note: See TracChangeset
for help on using the changeset viewer.