bool scrollInDirection(Frame* frame, FocusDirection direction) { ASSERT(frame); if (frame && canScrollInDirection(frame->document(), direction)) { int dx = 0; int dy = 0; switch (direction) { case FocusDirectionLeft: dx = - Scrollbar::pixelsPerLineStep(); break; case FocusDirectionRight: dx = Scrollbar::pixelsPerLineStep(); break; case FocusDirectionUp: dy = - Scrollbar::pixelsPerLineStep(); break; case FocusDirectionDown: dy = Scrollbar::pixelsPerLineStep(); break; default: ASSERT_NOT_REACHED(); return false; } frame->view()->scrollBy(IntSize(dx, dy)); return true; } return false; }
bool canScrollInDirection(const Node* container, FocusDirection direction) { ASSERT(container); if (isHTMLSelectElement(container)) return false; if (container->isDocumentNode()) return canScrollInDirection(toDocument(container)->frame(), direction); if (!isScrollableNode(container)) return false; switch (direction) { case FocusDirectionLeft: return (container->renderer()->style().overflowX() != OHIDDEN && container->renderBox()->scrollLeft() > 0); case FocusDirectionUp: return (container->renderer()->style().overflowY() != OHIDDEN && container->renderBox()->scrollTop() > 0); case FocusDirectionRight: return (container->renderer()->style().overflowX() != OHIDDEN && container->renderBox()->scrollLeft() + container->renderBox()->clientWidth() < container->renderBox()->scrollWidth()); case FocusDirectionDown: return (container->renderer()->style().overflowY() != OHIDDEN && container->renderBox()->scrollTop() + container->renderBox()->clientHeight() < container->renderBox()->scrollHeight()); default: ASSERT_NOT_REACHED(); return false; } }
Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection direction, Node* node) { ASSERT(node); Node* parent = node; do { if (parent->isDocumentNode()) parent = static_cast<Document*>(parent)->document()->frame()->ownerElement(); else parent = parent->parentNode(); } while (parent && !canScrollInDirection(parent, direction) && !parent->isDocumentNode()); return parent; }
bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candidate) { ASSERT(candidate.visibleNode && candidate.isOffscreen); IntRect candidateRect = candidate.rect; for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; parentNode = parentNode->parentNode()) { IntRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); if (!candidateRect.intersects(parentRect)) { if (((direction == FocusDirectionLeft || direction == FocusDirectionRight) && parentNode->renderer()->style()->overflowX() == OHIDDEN) || ((direction == FocusDirectionUp || direction == FocusDirectionDown) && parentNode->renderer()->style()->overflowY() == OHIDDEN)) return false; } if (parentNode == candidate.enclosingScrollableBox) return canScrollInDirection(parentNode, direction); } return true; }
bool scrollInDirection(Node* container, FocusDirection direction) { ASSERT(container); if (container->isDocumentNode()) return scrollInDirection(static_cast<Document*>(container)->frame(), direction); if (!container->renderBox()) return false; if (canScrollInDirection(container, direction)) { int dx = 0; int dy = 0; switch (direction) { case FocusDirectionLeft: dx = - min(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollLeft()); break; case FocusDirectionRight: ASSERT(container->renderBox()->scrollWidth() > (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth())); dx = min(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollWidth() - (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth())); break; case FocusDirectionUp: dy = - min(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollTop()); break; case FocusDirectionDown: ASSERT(container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight())); dy = min(Scrollbar::pixelsPerLineStep(), container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight())); break; default: ASSERT_NOT_REACHED(); return false; } container->renderBox()->enclosingLayer()->scrollByRecursively(dx, dy); return true; } return false; }