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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 , distance(maxDistance()) | 56 , distance(maxDistance()) |
57 , isOffscreen(true) | 57 , isOffscreen(true) |
58 , isOffscreenAfterScrolling(true) | 58 , isOffscreenAfterScrolling(true) |
59 { | 59 { |
60 ASSERT(node); | 60 ASSERT(node); |
61 ASSERT(node->isElementNode()); | 61 ASSERT(node->isElementNode()); |
62 | 62 |
63 if (isHTMLAreaElement(*node)) { | 63 if (isHTMLAreaElement(*node)) { |
64 HTMLAreaElement& area = toHTMLAreaElement(*node); | 64 HTMLAreaElement& area = toHTMLAreaElement(*node); |
65 HTMLImageElement* image = area.imageElement(); | 65 HTMLImageElement* image = area.imageElement(); |
66 if (!image || !image->renderer()) | 66 if (!image || !image->layoutObject()) |
67 return; | 67 return; |
68 | 68 |
69 visibleNode = image; | 69 visibleNode = image; |
70 rect = virtualRectForAreaElementAndDirection(area, type); | 70 rect = virtualRectForAreaElementAndDirection(area, type); |
71 } else { | 71 } else { |
72 if (!node->renderer()) | 72 if (!node->layoutObject()) |
73 return; | 73 return; |
74 | 74 |
75 visibleNode = node; | 75 visibleNode = node; |
76 rect = nodeRectInAbsoluteCoordinates(node, true /* ignore border */); | 76 rect = nodeRectInAbsoluteCoordinates(node, true /* ignore border */); |
77 } | 77 } |
78 | 78 |
79 focusableNode = node; | 79 focusableNode = node; |
80 isOffscreen = hasOffscreenRect(visibleNode); | 80 isOffscreen = hasOffscreenRect(visibleNode); |
81 isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, type); | 81 isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, type); |
82 } | 82 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 containerViewportRect.setY(containerViewportRect.y() - ScrollableArea::p
ixelsPerLineStep()); | 172 containerViewportRect.setY(containerViewportRect.y() - ScrollableArea::p
ixelsPerLineStep()); |
173 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); | 173 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); |
174 break; | 174 break; |
175 case WebFocusTypeDown: | 175 case WebFocusTypeDown: |
176 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); | 176 containerViewportRect.setHeight(containerViewportRect.height() + Scrolla
bleArea::pixelsPerLineStep()); |
177 break; | 177 break; |
178 default: | 178 default: |
179 break; | 179 break; |
180 } | 180 } |
181 | 181 |
182 LayoutObject* render = node->renderer(); | 182 LayoutObject* render = node->layoutObject(); |
183 if (!render) | 183 if (!render) |
184 return true; | 184 return true; |
185 | 185 |
186 LayoutRect rect(render->absoluteClippedOverflowRect()); | 186 LayoutRect rect(render->absoluteClippedOverflowRect()); |
187 if (rect.isEmpty()) | 187 if (rect.isEmpty()) |
188 return true; | 188 return true; |
189 | 189 |
190 return !containerViewportRect.intersects(rect); | 190 return !containerViewportRect.intersects(rect); |
191 } | 191 } |
192 | 192 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 b.inflate(deflateFactor); | 275 b.inflate(deflateFactor); |
276 } | 276 } |
277 | 277 |
278 bool isScrollableNode(const Node* node) | 278 bool isScrollableNode(const Node* node) |
279 { | 279 { |
280 ASSERT(!node->isDocumentNode()); | 280 ASSERT(!node->isDocumentNode()); |
281 | 281 |
282 if (!node) | 282 if (!node) |
283 return false; | 283 return false; |
284 | 284 |
285 if (LayoutObject* renderer = node->renderer()) | 285 if (LayoutObject* renderer = node->layoutObject()) |
286 return renderer->isBox() && toLayoutBox(renderer)->canBeScrolledAndHasSc
rollableArea() && node->hasChildren(); | 286 return renderer->isBox() && toLayoutBox(renderer)->canBeScrolledAndHasSc
rollableArea() && node->hasChildren(); |
287 | 287 |
288 return false; | 288 return false; |
289 } | 289 } |
290 | 290 |
291 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(WebFocusType type, N
ode* node) | 291 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(WebFocusType type, N
ode* node) |
292 { | 292 { |
293 ASSERT(node); | 293 ASSERT(node); |
294 Node* parent = node; | 294 Node* parent = node; |
295 do { | 295 do { |
(...skipping 11 matching lines...) Expand all Loading... |
307 { | 307 { |
308 ASSERT(container); | 308 ASSERT(container); |
309 if (container->isDocumentNode()) | 309 if (container->isDocumentNode()) |
310 return canScrollInDirection(toDocument(container)->frame(), type); | 310 return canScrollInDirection(toDocument(container)->frame(), type); |
311 | 311 |
312 if (!isScrollableNode(container)) | 312 if (!isScrollableNode(container)) |
313 return false; | 313 return false; |
314 | 314 |
315 switch (type) { | 315 switch (type) { |
316 case WebFocusTypeLeft: | 316 case WebFocusTypeLeft: |
317 return (container->renderer()->style()->overflowX() != OHIDDEN && contai
ner->layoutBox()->scrollLeft() > 0); | 317 return (container->layoutObject()->style()->overflowX() != OHIDDEN && co
ntainer->layoutBox()->scrollLeft() > 0); |
318 case WebFocusTypeUp: | 318 case WebFocusTypeUp: |
319 return (container->renderer()->style()->overflowY() != OHIDDEN && contai
ner->layoutBox()->scrollTop() > 0); | 319 return (container->layoutObject()->style()->overflowY() != OHIDDEN && co
ntainer->layoutBox()->scrollTop() > 0); |
320 case WebFocusTypeRight: | 320 case WebFocusTypeRight: |
321 return (container->renderer()->style()->overflowX() != OHIDDEN && contai
ner->layoutBox()->scrollLeft() + container->layoutBox()->clientWidth() < contain
er->layoutBox()->scrollWidth()); | 321 return (container->layoutObject()->style()->overflowX() != OHIDDEN && co
ntainer->layoutBox()->scrollLeft() + container->layoutBox()->clientWidth() < con
tainer->layoutBox()->scrollWidth()); |
322 case WebFocusTypeDown: | 322 case WebFocusTypeDown: |
323 return (container->renderer()->style()->overflowY() != OHIDDEN && contai
ner->layoutBox()->scrollTop() + container->layoutBox()->clientHeight() < contain
er->layoutBox()->scrollHeight()); | 323 return (container->layoutObject()->style()->overflowY() != OHIDDEN && co
ntainer->layoutBox()->scrollTop() + container->layoutBox()->clientHeight() < con
tainer->layoutBox()->scrollHeight()); |
324 default: | 324 default: |
325 ASSERT_NOT_REACHED(); | 325 ASSERT_NOT_REACHED(); |
326 return false; | 326 return false; |
327 } | 327 } |
328 } | 328 } |
329 | 329 |
330 bool canScrollInDirection(const LocalFrame* frame, WebFocusType type) | 330 bool canScrollInDirection(const LocalFrame* frame, WebFocusType type) |
331 { | 331 { |
332 if (!frame->view()) | 332 if (!frame->view()) |
333 return false; | 333 return false; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 for (; element; element = element->offsetParent()) | 369 for (; element; element = element->offsetParent()) |
370 rect.move(element->offsetLeft(), element->offsetTop()); | 370 rect.move(element->offsetLeft(), element->offsetTop()); |
371 rect.move((-toLocalFrame(frame)->view()->scrollOffset())); | 371 rect.move((-toLocalFrame(frame)->view()->scrollOffset())); |
372 } | 372 } |
373 } | 373 } |
374 return rect; | 374 return rect; |
375 } | 375 } |
376 | 376 |
377 LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) | 377 LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) |
378 { | 378 { |
379 ASSERT(node && node->renderer() && !node->document().view()->needsLayout()); | 379 ASSERT(node && node->layoutObject() && !node->document().view()->needsLayout
()); |
380 | 380 |
381 if (node->isDocumentNode()) | 381 if (node->isDocumentNode()) |
382 return frameRectInAbsoluteCoordinates(toDocument(node)->frame()); | 382 return frameRectInAbsoluteCoordinates(toDocument(node)->frame()); |
383 LayoutRect rect = rectToAbsoluteCoordinates(node->document().frame(), node->
boundingBox()); | 383 LayoutRect rect = rectToAbsoluteCoordinates(node->document().frame(), node->
boundingBox()); |
384 | 384 |
385 // For authors that use border instead of outline in their CSS, we compensat
e by ignoring the border when calculating | 385 // For authors that use border instead of outline in their CSS, we compensat
e by ignoring the border when calculating |
386 // the rect of the focused element. | 386 // the rect of the focused element. |
387 if (ignoreBorder) { | 387 if (ignoreBorder) { |
388 rect.move(node->renderer()->style()->borderLeftWidth(), node->renderer()
->style()->borderTopWidth()); | 388 rect.move(node->layoutObject()->style()->borderLeftWidth(), node->layout
Object()->style()->borderTopWidth()); |
389 rect.setWidth(rect.width() - node->renderer()->style()->borderLeftWidth(
) - node->renderer()->style()->borderRightWidth()); | 389 rect.setWidth(rect.width() - node->layoutObject()->style()->borderLeftWi
dth() - node->layoutObject()->style()->borderRightWidth()); |
390 rect.setHeight(rect.height() - node->renderer()->style()->borderTopWidth
() - node->renderer()->style()->borderBottomWidth()); | 390 rect.setHeight(rect.height() - node->layoutObject()->style()->borderTopW
idth() - node->layoutObject()->style()->borderBottomWidth()); |
391 } | 391 } |
392 return rect; | 392 return rect; |
393 } | 393 } |
394 | 394 |
395 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame) | 395 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame) |
396 { | 396 { |
397 return rectToAbsoluteCoordinates(frame, LayoutRect(frame->view()->visibleCon
tentRect())); | 397 return rectToAbsoluteCoordinates(frame, LayoutRect(frame->view()->visibleCon
tentRect())); |
398 } | 398 } |
399 | 399 |
400 // This method calculates the exitPoint from the startingRect and the entryPoint
into the candidate rect. | 400 // This method calculates the exitPoint from the startingRect and the entryPoint
into the candidate rect. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 default: | 478 default: |
479 ASSERT_NOT_REACHED(); | 479 ASSERT_NOT_REACHED(); |
480 } | 480 } |
481 } | 481 } |
482 | 482 |
483 bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCand
idate& secondCandidate) | 483 bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCand
idate& secondCandidate) |
484 { | 484 { |
485 if (firstCandidate.isNull() || secondCandidate.isNull()) | 485 if (firstCandidate.isNull() || secondCandidate.isNull()) |
486 return false; | 486 return false; |
487 | 487 |
488 if (!firstCandidate.visibleNode->renderer() || !secondCandidate.visibleNode-
>renderer()) | 488 if (!firstCandidate.visibleNode->layoutObject() || !secondCandidate.visibleN
ode->layoutObject()) |
489 return false; | 489 return false; |
490 | 490 |
491 if (!firstCandidate.rect.intersects(secondCandidate.rect)) | 491 if (!firstCandidate.rect.intersects(secondCandidate.rect)) |
492 return false; | 492 return false; |
493 | 493 |
494 if (isHTMLAreaElement(*firstCandidate.focusableNode) || isHTMLAreaElement(*s
econdCandidate.focusableNode)) | 494 if (isHTMLAreaElement(*firstCandidate.focusableNode) || isHTMLAreaElement(*s
econdCandidate.focusableNode)) |
495 return false; | 495 return false; |
496 | 496 |
497 if (!firstCandidate.visibleNode->renderer()->isLayoutInline() || !secondCand
idate.visibleNode->renderer()->isLayoutInline()) | 497 if (!firstCandidate.visibleNode->layoutObject()->isLayoutInline() || !second
Candidate.visibleNode->layoutObject()->isLayoutInline()) |
498 return false; | 498 return false; |
499 | 499 |
500 if (firstCandidate.visibleNode->renderer()->containingBlock() != secondCandi
date.visibleNode->renderer()->containingBlock()) | 500 if (firstCandidate.visibleNode->layoutObject()->containingBlock() != secondC
andidate.visibleNode->layoutObject()->containingBlock()) |
501 return false; | 501 return false; |
502 | 502 |
503 return true; | 503 return true; |
504 } | 504 } |
505 | 505 |
506 void distanceDataForNode(WebFocusType type, const FocusCandidate& current, Focus
Candidate& candidate) | 506 void distanceDataForNode(WebFocusType type, const FocusCandidate& current, Focus
Candidate& candidate) |
507 { | 507 { |
508 if (areElementsOnSameLine(current, candidate)) { | 508 if (areElementsOnSameLine(current, candidate)) { |
509 if ((type == WebFocusTypeUp && current.rect.y() > candidate.rect.y()) ||
(type == WebFocusTypeDown && candidate.rect.y() > current.rect.y())) { | 509 if ((type == WebFocusTypeUp && current.rect.y() > candidate.rect.y()) ||
(type == WebFocusTypeDown && candidate.rect.y() > current.rect.y())) { |
510 candidate.distance = 0; | 510 candidate.distance = 0; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance +
weightedOrthogonalAxisDistance - sqrt(overlap); | 568 candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance +
weightedOrthogonalAxisDistance - sqrt(overlap); |
569 } | 569 } |
570 | 570 |
571 bool canBeScrolledIntoView(WebFocusType type, const FocusCandidate& candidate) | 571 bool canBeScrolledIntoView(WebFocusType type, const FocusCandidate& candidate) |
572 { | 572 { |
573 ASSERT(candidate.visibleNode && candidate.isOffscreen); | 573 ASSERT(candidate.visibleNode && candidate.isOffscreen); |
574 LayoutRect candidateRect = candidate.rect; | 574 LayoutRect candidateRect = candidate.rect; |
575 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { | 575 for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; par
entNode = parentNode->parentNode()) { |
576 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); | 576 LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); |
577 if (!candidateRect.intersects(parentRect)) { | 577 if (!candidateRect.intersects(parentRect)) { |
578 if (((type == WebFocusTypeLeft || type == WebFocusTypeRight) && pare
ntNode->renderer()->style()->overflowX() == OHIDDEN) | 578 if (((type == WebFocusTypeLeft || type == WebFocusTypeRight) && pare
ntNode->layoutObject()->style()->overflowX() == OHIDDEN) |
579 || ((type == WebFocusTypeUp || type == WebFocusTypeDown) && pare
ntNode->renderer()->style()->overflowY() == OHIDDEN)) | 579 || ((type == WebFocusTypeUp || type == WebFocusTypeDown) && pare
ntNode->layoutObject()->style()->overflowY() == OHIDDEN)) |
580 return false; | 580 return false; |
581 } | 581 } |
582 if (parentNode == candidate.enclosingScrollableBox) | 582 if (parentNode == candidate.enclosingScrollableBox) |
583 return canScrollInDirection(parentNode, type); | 583 return canScrollInDirection(parentNode, type); |
584 } | 584 } |
585 return true; | 585 return true; |
586 } | 586 } |
587 | 587 |
588 // The starting rect is the rect of the focused node, in document coordinates. | 588 // The starting rect is the rect of the focused node, in document coordinates. |
589 // Compose a virtual starting rect if there is no focused node or if it is off s
creen. | 589 // Compose a virtual starting rect if there is no focused node or if it is off s
creen. |
(...skipping 22 matching lines...) Expand all Loading... |
612 } | 612 } |
613 | 613 |
614 return virtualStartingRect; | 614 return virtualStartingRect; |
615 } | 615 } |
616 | 616 |
617 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, WebFocus
Type type) | 617 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, WebFocus
Type type) |
618 { | 618 { |
619 ASSERT(area.imageElement()); | 619 ASSERT(area.imageElement()); |
620 // Area elements tend to overlap more than other focusable elements. We flat
ten the rect of the area elements | 620 // Area elements tend to overlap more than other focusable elements. We flat
ten the rect of the area elements |
621 // to minimize the effect of overlapping areas. | 621 // to minimize the effect of overlapping areas. |
622 LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(ar
ea.document().frame(), area.computeRect(area.imageElement()->renderer())), 1); | 622 LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(ar
ea.document().frame(), area.computeRect(area.imageElement()->layoutObject())), 1
); |
623 return rect; | 623 return rect; |
624 } | 624 } |
625 | 625 |
626 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) | 626 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate) |
627 { | 627 { |
628 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : nullptr; | 628 return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.v
isibleNode) : nullptr; |
629 }; | 629 }; |
630 | 630 |
631 } // namespace blink | 631 } // namespace blink |
OLD | NEW |