Changeset 72596 in webkit


Ignore:
Timestamp:
Nov 23, 2010 4:57:17 AM (13 years ago)
Author:
yael.aharon@nokia.com
Message:

2010-11-23 Yael Aharon <yael.aharon@nokia.com>

Reviewed by Antonio Gomes.

Spatial Navigation: Code cleanup
https://bugs.webkit.org/show_bug.cgi?id=49442

Remove code that is not used anymore after http://trac.webkit.org/changeset/72522.
Added const to canBeScrolledIntoView.
No new tests because this is only code cleanup.

  • page/FocusController.cpp:
  • page/FocusController.h:
  • page/SpatialNavigation.cpp: (WebCore::canBeScrolledIntoView):
  • page/SpatialNavigation.h:
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r72593 r72596  
     12010-11-23  Yael Aharon  <yael.aharon@nokia.com>
     2
     3        Reviewed by Antonio Gomes.
     4
     5        Spatial Navigation: Code cleanup
     6        https://bugs.webkit.org/show_bug.cgi?id=49442
     7
     8        Remove code that is not used anymore after http://trac.webkit.org/changeset/72522.
     9        Added const to canBeScrolledIntoView.
     10        No new tests because this is only code cleanup.
     11
     12        * page/FocusController.cpp:
     13        * page/FocusController.h:
     14        * page/SpatialNavigation.cpp:
     15        (WebCore::canBeScrolledIntoView):
     16        * page/SpatialNavigation.h:
     17
    1182010-11-23  Jeremy Orlow  <jorlow@chromium.org>
    219
  • trunk/WebCore/page/FocusController.cpp

    r72522 r72596  
    293293}
    294294
    295 static void updateFocusCandidateInSameContainer(const FocusCandidate& candidate, FocusCandidate& closest)
    296 {
    297     if (closest.isNull()) {
    298         closest = candidate;
    299         return;
    300     }
    301 
    302     if (candidate.alignment == closest.alignment) {
    303         if (candidate.distance < closest.distance)
    304             closest = candidate;
    305         return;
    306     }
    307 
    308     if (candidate.alignment > closest.alignment)
    309         closest = candidate;
    310 }
    311 
    312 static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate& candidate, FocusCandidate& closest)
    313 {
    314     // First, check the common case: neither candidate nor closest are
    315     // inside scrollable content, then no need to care about enclosingScrollableBox
    316     // heuristics or parent{Distance,Alignment}, but only distance and alignment.
    317     if (!candidate.inScrollableContainer() && !closest.inScrollableContainer()) {
    318         updateFocusCandidateInSameContainer(candidate, closest);
    319         return;
    320     }
    321 
    322     bool sameContainer = candidate.document() == closest.document() && candidate.enclosingScrollableBox == closest.enclosingScrollableBox;
    323 
    324     // Second, if candidate and closest are in the same "container" (i.e. {i}frame or any
    325     // scrollable block element), we can handle them as common case.
    326     if (sameContainer) {
    327         updateFocusCandidateInSameContainer(candidate, closest);
    328         return;
    329     }
    330 
    331     // Last, we are considering moving to a candidate located in a different enclosing
    332     // scrollable box than closest.
    333     bool isInInnerDocument = !isInRootDocument(focusedNode);
    334 
    335     bool sameContainerAsCandidate = isInInnerDocument ? focusedNode->document() == candidate.document() :
    336         focusedNode->isDescendantOf(candidate.enclosingScrollableBox);
    337 
    338     bool sameContainerAsClosest = isInInnerDocument ? focusedNode->document() == closest.document() :
    339         focusedNode->isDescendantOf(closest.enclosingScrollableBox);
    340 
    341     // sameContainerAsCandidate and sameContainerAsClosest are mutually exclusive.
    342     ASSERT(!(sameContainerAsCandidate && sameContainerAsClosest));
    343 
    344     if (sameContainerAsCandidate) {
    345         closest = candidate;
    346         return;
    347     }
    348 
    349     if (sameContainerAsClosest) {
    350         // Nothing to be done.
    351         return;
    352     }
    353 
    354     // NOTE: !sameContainerAsCandidate && !sameContainerAsClosest
    355     // If distance is shorter, and we are talking about scrollable container,
    356     // lets compare parent distance and alignment before anything.
    357     if (candidate.distance < closest.distance) {
    358         if (candidate.alignment >= closest.parentAlignment
    359          || candidate.parentAlignment == closest.parentAlignment) {
    360             closest = candidate;
    361             return;
    362         }
    363 
    364     } else if (candidate.parentDistance < closest.distance) {
    365         if (candidate.parentAlignment >= closest.alignment) {
    366             closest = candidate;
    367             return;
    368         }
    369     }
    370 }
    371 
    372 void FocusController::findFocusableNodeInDirection(Node* outer, Node* focusedNode,
    373                                                    FocusDirection direction, KeyboardEvent* event,
    374                                                    FocusCandidate& closest, const FocusCandidate& candidateParent)
    375 {
    376     ASSERT(outer);
    377     ASSERT(candidateParent.isNull()
    378         || candidateParent.node->hasTagName(frameTag)
    379         || candidateParent.node->hasTagName(iframeTag)
    380         || isScrollableContainerNode(candidateParent.node));
    381 
    382     // Walk all the child nodes and update closest if we find a nearer node.
    383     Node* node = outer;
    384     while (node) {
    385 
    386         // Inner documents case.
    387         if (node->isFrameOwnerElement()) {
    388             deepFindFocusableNodeInDirection(node, focusedNode, direction, event, closest);
    389 
    390         // Scrollable block elements (e.g. <div>, etc) case.
    391         } else if (isScrollableContainerNode(node)) {
    392             deepFindFocusableNodeInDirection(node, focusedNode, direction, event, closest);
    393             node = node->traverseNextSibling();
    394             continue;
    395 
    396         } else if (node != focusedNode && node->isKeyboardFocusable(event)) {
    397             FocusCandidate candidate(node);
    398 
    399             // There are two ways to identify we are in a recursive call from deepFindFocusableNodeInDirection
    400             // (i.e. processing an element in an iframe, frame or a scrollable block element):
    401 
    402             // 1) If candidateParent is not null, and it holds the distance and alignment data of the
    403             // parent container element itself;
    404             // 2) Parent of outer is <frame> or <iframe>;
    405             // 3) Parent is any other scrollable block element.
    406             if (!candidateParent.isNull()) {
    407                 candidate.parentAlignment = candidateParent.alignment;
    408                 candidate.parentDistance = candidateParent.distance;
    409                 candidate.enclosingScrollableBox = candidateParent.node;
    410 
    411             } else if (!isInRootDocument(outer)) {
    412                 if (Document* document = static_cast<Document*>(outer->parentNode()))
    413                     candidate.enclosingScrollableBox = static_cast<Node*>(document->ownerElement());
    414 
    415             } else if (isScrollableContainerNode(outer->parentNode()))
    416                 candidate.enclosingScrollableBox = outer->parentNode();
    417 
    418             // Get distance and alignment from current candidate.
    419             distanceDataForNode(direction, focusedNode, candidate);
    420 
    421             // Bail out if distance is maximum.
    422             if (candidate.distance == maxDistance()) {
    423                 node = node->traverseNextNode(outer->parentNode());
    424                 continue;
    425             }
    426 
    427             updateFocusCandidateIfCloser(focusedNode, candidate, closest);
    428         }
    429 
    430         node = node->traverseNextNode(outer->parentNode());
    431     }
    432 }
    433 
    434 void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* focusedNode,
    435                                                        FocusDirection direction, KeyboardEvent* event,
    436                                                        FocusCandidate& closest)
    437 {
    438     ASSERT(container->hasTagName(frameTag)
    439         || container->hasTagName(iframeTag)
    440         || isScrollableContainerNode(container));
    441 
    442     // Track if focusedNode is a descendant of the current container node being processed.
    443     bool descendantOfContainer = false;
    444     Node* firstChild = 0;
    445 
    446     // Iframe or Frame.
    447     if (container->hasTagName(frameTag) || container->hasTagName(iframeTag)) {
    448 
    449         HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(container);
    450         if (!owner->contentFrame())
    451             return;
    452 
    453         Document* innerDocument = owner->contentFrame()->document();
    454         if (!innerDocument)
    455             return;
    456 
    457         descendantOfContainer = isNodeDeepDescendantOfDocument(focusedNode, innerDocument);
    458         firstChild = innerDocument->firstChild();
    459 
    460     // Scrollable block elements (e.g. <div>, etc)
    461     } else if (isScrollableContainerNode(container)) {
    462 
    463         firstChild = container->firstChild();
    464         descendantOfContainer = focusedNode->isDescendantOf(container);
    465     }
    466 
    467     if (descendantOfContainer) {
    468         findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closest);
    469         return;
    470     }
    471 
    472     // Check if the current container element itself is a good candidate
    473     // to move focus to. If it is, then we traverse its inner nodes.
    474     FocusCandidate candidateParent = FocusCandidate(container);
    475     distanceDataForNode(direction, focusedNode, candidateParent);
    476 
    477     // Bail out if distance is maximum.
    478     if (candidateParent.distance == maxDistance())
    479         return;
    480 
    481     // FIXME: Consider alignment?
    482     if (candidateParent.distance < closest.distance)
    483         findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closest, candidateParent);
    484 }
    485 
    486295static bool relinquishesEditingFocus(Node *node)
    487296{
  • trunk/WebCore/page/FocusController.h

    r72522 r72596  
    6464    bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus);
    6565
    66     void findFocusableNodeInDirection(Node* outter, Node*, FocusDirection, KeyboardEvent*,
    67                                       FocusCandidate& closestFocusCandidate,
    68                                       const FocusCandidate& parentCandidate = FocusCandidate());
    69     void deepFindFocusableNodeInDirection(Node* container, Node* focused, FocusDirection, KeyboardEvent*, FocusCandidate&);
    70 
    7166    bool advanceFocusDirectionallyInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*);
    7267    void findFocusCandidateInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest);
  • trunk/WebCore/page/SpatialNavigation.cpp

    r72522 r72596  
    4242namespace WebCore {
    4343
    44 static long long spatialDistance(FocusDirection, const IntRect&, const IntRect&);
    45 static IntRect renderRectRelativeToRootDocument(RenderObject*);
    4644static RectsAlignment alignmentForRects(FocusDirection, const IntRect&, const IntRect&, const IntSize& viewSize);
    4745static bool areRectsFullyAligned(FocusDirection, const IntRect&, const IntRect&);
     
    5048static bool isRectInDirection(FocusDirection, const IntRect&, const IntRect&);
    5149static void deflateIfOverlapped(IntRect&, IntRect&);
    52 static bool checkNegativeCoordsForNode(Node*, const IntRect&);
    5350static IntRect rectToAbsoluteCoordinates(Frame* initialFrame, const IntRect& rect);
    5451static void entryAndExitPointsForDirection(FocusDirection direction, const IntRect& startingRect, const IntRect& potentialRect, IntPoint& exitPoint, IntPoint& entryPoint);
     
    6966{
    7067    return (frame && frame->settings() && frame->settings()->isSpatialNavigationEnabled());
    71 }
    72 
    73 void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate)
    74 {
    75     RenderObject* startRender = start->renderer();
    76     if (!startRender) {
    77         candidate.distance = maxDistance();
    78         return;
    79     }
    80 
    81     RenderObject* destRender = candidate.node->renderer();
    82     if (!destRender) {
    83         candidate.distance = maxDistance();
    84         return;
    85     }
    86 
    87     IntRect curRect = renderRectRelativeToRootDocument(startRender);
    88     IntRect targetRect  = renderRectRelativeToRootDocument(destRender);
    89 
    90     // The bounding rectangle of two consecutive nodes can overlap. In such cases,
    91     // deflate both.
    92     deflateIfOverlapped(curRect, targetRect);
    93 
    94     // If empty rects or negative width or height, bail out.
    95     if (curRect.isEmpty() || targetRect.isEmpty()
    96      || targetRect.width() <= 0 || targetRect.height() <= 0) {
    97         candidate.distance = maxDistance();
    98         return;
    99     }
    100 
    101     // Negative coordinates can be used if node is scrolled up offscreen.
    102     if (!checkNegativeCoordsForNode(start, curRect)) {
    103         candidate.distance = maxDistance();
    104         return;
    105     }
    106 
    107     if (!checkNegativeCoordsForNode(candidate.node, targetRect)) {
    108         candidate.distance = maxDistance();
    109         return;
    110     }
    111 
    112     if (!isRectInDirection(direction, curRect, targetRect)) {
    113         candidate.distance = maxDistance();
    114         return;
    115     }
    116 
    117     // The distance between two nodes is not to be considered alone when evaluating/looking
    118     // for the best focus candidate node. Alignment of rects can be also a good point to be
    119     // considered in order to make the algorithm to behavior in a more intuitive way.
    120     IntSize viewSize = candidate.node->document()->page()->mainFrame()->view()->visibleContentRect().size();
    121     candidate.alignment = alignmentForRects(direction, curRect, targetRect, viewSize);
    122     candidate.distance = spatialDistance(direction, curRect, targetRect);
    123 }
    124 
    125 // FIXME: This function does not behave correctly with transformed frames.
    126 static IntRect renderRectRelativeToRootDocument(RenderObject* render)
    127 {
    128     ASSERT(render && render->node());
    129 
    130     IntRect rect = render->node()->getRect();
    131 
    132     // In cases when the |render|'s associated node is in a scrollable inner
    133     // document, we only consider its scrollOffset if it is not offscreen.
    134     Node* node = render->node();
    135     Document* mainDocument = node->document()->page()->mainFrame()->document();
    136     bool considerScrollOffset = !(hasOffscreenRect(node) && node->document() != mainDocument);
    137 
    138     if (considerScrollOffset) {
    139         if (FrameView* frameView = render->node()->document()->view())
    140             rect.move(-frameView->scrollOffset());
    141     }
    142 
    143     // Handle nested frames.
    144     for (Frame* frame = render->document()->frame(); frame; frame = frame->tree()->parent()) {
    145         if (Element* element = static_cast<Element*>(frame->ownerElement())) {
    146             do {
    147                 rect.move(element->offsetLeft(), element->offsetTop());
    148             } while ((element = element->offsetParent()));
    149         }
    150     }
    151 
    152     return rect;
    15368}
    15469
     
    329244}
    330245
    331 // * a = Current focused node's rect.
    332 // * b = Focus candidate node's rect.
    333 static long long spatialDistance(FocusDirection direction, const IntRect& a, const IntRect& b)
    334 {
    335     int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
    336 
    337     if (direction == FocusDirectionLeft) {
    338         // #1  |--|
    339         //
    340         // #2  |--|  |--|
    341         //
    342         // #3  |--|
    343 
    344         x1 = a.x();
    345         x2 = b.right();
    346 
    347         if (below(a, b)) {
    348             // #1 The a rect is below b.
    349             y1 = a.y();
    350             y2 = b.bottom();
    351         } else if (below(b, a)) {
    352             // #3 The b rect is below a.
    353             y1 = a.bottom();
    354             y2 = b.y();
    355         } else {
    356             // #2 Both b and a share some common y's.
    357             y1 = 0;
    358             y2 = 0;
    359         }
    360     } else if (direction == FocusDirectionRight) {
    361         //        |--|  #1
    362         //
    363         //  |--|  |--|  #2
    364         //
    365         //        |--|  #3
    366 
    367         x1 = a.right();
    368         x2 = b.x();
    369 
    370         if (below(a, b)) {
    371             // #1 The b rect is above a.
    372             y1 = a.y();
    373             y2 = b.bottom();
    374         } else if (below(b, a)) {
    375             // #3 The b rect is below a.
    376             y1 = a.bottom();
    377             y2 = b.y();
    378         } else {
    379             // #2 Both b and a share some common y's.
    380             y1 = 0;
    381             y2 = 0;
    382         }
    383     } else if (direction == FocusDirectionUp) {
    384         //
    385         //   #1    #2    #3
    386         //
    387         //  |--|  |--|  |--|
    388         //
    389         //        |--|
    390 
    391         y1 = a.y();
    392         y2 = b.bottom();
    393 
    394         if (rightOf(a, b)) {
    395             // #1 The b rect is to the left of a.
    396             x1 = a.x();
    397             x2 = b.right();
    398         } else if (rightOf(b, a)) {
    399             // #3 The b rect is to the right of a.
    400             x1 = a.right();
    401             x2 = b.x();
    402         } else {
    403             // #2 Both b and a share some common x's.
    404             x1 = 0;
    405             x2 = 0;
    406         }
    407     } else if (direction == FocusDirectionDown) {
    408         //        |--|
    409         //
    410         //  |--|  |--|  |--|
    411         //
    412         //   #1    #2    #3
    413 
    414         y1 = a.bottom();
    415         y2 = b.y();
    416 
    417         if (rightOf(a, b)) {
    418             // #1 The b rect is to the left of a.
    419             x1 = a.x();
    420             x2 = b.right();
    421         } else if (rightOf(b, a)) {
    422             // #3 The b rect is to the right of a
    423             x1 = a.right();
    424             x2 = b.x();
    425         } else {
    426             // #2 Both b and a share some common x's.
    427             x1 = 0;
    428             x2 = 0;
    429         }
    430     }
    431 
    432     long long dx = x1 - x2;
    433     long long dy = y1 - y2;
    434 
    435     long long distance = (dx * dx) + (dy * dy);
    436 
    437     if (distance < 0)
    438         distance *= -1;
    439 
    440     return distance;
    441 }
    442 
    443246static bool isRectInDirection(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect)
    444247{
     
    573376}
    574377
    575 void scrollIntoView(Element* element)
    576 {
    577     // NOTE: Element's scrollIntoView method could had been used here, but
    578     // it is preferable to inflate |element|'s bounding rect a bit before
    579     // scrolling it for accurate reason.
    580     // Element's scrollIntoView method does not provide this flexibility.
    581     IntRect bounds = element->getRect();
    582     bounds.inflate(fudgeFactor());
    583     element->renderer()->enclosingLayer()->scrollRectToVisible(bounds);
    584 }
    585 
    586 bool isInRootDocument(Node* node)
    587 {
    588     if (!node)
    589         return false;
    590 
    591     Document* rootDocument = node->document()->page()->mainFrame()->document();
    592     return node->document() == rootDocument;
    593 }
    594 
    595378static void deflateIfOverlapped(IntRect& a, IntRect& b)
    596379{
     
    608391}
    609392
    610 static bool checkNegativeCoordsForNode(Node* node, const IntRect& curRect)
    611 {
    612     ASSERT(node || node->renderer());
    613 
    614     if (curRect.x() >= 0 && curRect.y() >= 0)
    615         return true;
    616 
    617     bool canBeScrolled = false;
    618 
    619     RenderObject* renderer = node->renderer();
    620     for (; renderer; renderer = renderer->parent()) {
    621         if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) {
    622             canBeScrolled = true;
    623             break;
    624         }
    625     }
    626 
    627     return canBeScrolled;
    628 }
    629 
    630393bool isScrollableContainerNode(const Node* node)
    631394{
     
    639402
    640403    return false;
    641 }
    642 
    643 bool isNodeDeepDescendantOfDocument(Node* node, Document* baseDocument)
    644 {
    645     if (!node || !baseDocument)
    646         return false;
    647 
    648     bool descendant = baseDocument == node->document();
    649 
    650     Element* currentElement = static_cast<Element*>(node);
    651     while (!descendant) {
    652         Element* documentOwner = currentElement->document()->ownerElement();
    653         if (!documentOwner)
    654             break;
    655 
    656         descendant = documentOwner->document() == baseDocument;
    657         currentElement = documentOwner;
    658     }
    659 
    660     return descendant;
    661404}
    662405
     
    878621}
    879622
    880 bool canBeScrolledIntoView(FocusDirection direction, FocusCandidate& candidate)
     623bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candidate)
    881624{
    882625    ASSERT(candidate.node && hasOffscreenRect(candidate.node));
  • trunk/WebCore/page/SpatialNavigation.h

    r72522 r72596  
    123123};
    124124
    125 void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate);
    126125bool scrollInDirection(Frame*, FocusDirection);
    127126bool scrollInDirection(Node* container, FocusDirection);
    128 void scrollIntoView(Element*);
    129127bool hasOffscreenRect(Node*, FocusDirection direction = FocusDirectionNone);
    130 bool isInRootDocument(Node*);
    131128bool isScrollableContainerNode(const Node*);
    132129bool isNodeDeepDescendantOfDocument(Node*, Document*);
     
    137134IntRect frameRectInAbsoluteCoordinates(Frame*);
    138135void distanceDataForNode(FocusDirection, FocusCandidate& current, FocusCandidate& candidate);
    139 bool canBeScrolledIntoView(FocusDirection, FocusCandidate&);
     136bool canBeScrolledIntoView(FocusDirection, const FocusCandidate&);
    140137IntRect virtualRectForDirection(FocusDirection, const IntRect& startingRect);
    141138} // namspace WebCore
Note: See TracChangeset for help on using the changeset viewer.