| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 const LayoutRect& a, | 95 const LayoutRect& a, |
| 96 const LayoutRect& b) { | 96 const LayoutRect& b) { |
| 97 switch (type) { | 97 switch (type) { |
| 98 case kWebFocusTypeLeft: | 98 case kWebFocusTypeLeft: |
| 99 case kWebFocusTypeRight: | 99 case kWebFocusTypeRight: |
| 100 return a.MaxY() > b.Y() && a.Y() < b.MaxY(); | 100 return a.MaxY() > b.Y() && a.Y() < b.MaxY(); |
| 101 case kWebFocusTypeUp: | 101 case kWebFocusTypeUp: |
| 102 case kWebFocusTypeDown: | 102 case kWebFocusTypeDown: |
| 103 return a.MaxX() > b.X() && a.X() < b.MaxX(); | 103 return a.MaxX() > b.X() && a.X() < b.MaxX(); |
| 104 default: | 104 default: |
| 105 ASSERT_NOT_REACHED(); | 105 NOTREACHED(); |
| 106 return false; | 106 return false; |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 | 109 |
| 110 // Return true if rect |a| is below |b|. False otherwise. | 110 // Return true if rect |a| is below |b|. False otherwise. |
| 111 // For overlapping rects, |a| is considered to be below |b| | 111 // For overlapping rects, |a| is considered to be below |b| |
| 112 // if both edges of |a| are below the respective ones of |b| | 112 // if both edges of |a| are below the respective ones of |b| |
| 113 static inline bool Below(const LayoutRect& a, const LayoutRect& b) { | 113 static inline bool Below(const LayoutRect& a, const LayoutRect& b) { |
| 114 return a.Y() >= b.MaxY() || (a.Y() >= b.Y() && a.MaxY() > b.MaxY() && | 114 return a.Y() >= b.MaxY() || (a.Y() >= b.Y() && a.MaxY() > b.MaxY() && |
| 115 a.X() < b.MaxX() && a.MaxX() > b.X()); | 115 a.X() < b.MaxX() && a.MaxX() > b.X()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 129 switch (type) { | 129 switch (type) { |
| 130 case kWebFocusTypeLeft: | 130 case kWebFocusTypeLeft: |
| 131 return RightOf(cur_rect, target_rect); | 131 return RightOf(cur_rect, target_rect); |
| 132 case kWebFocusTypeRight: | 132 case kWebFocusTypeRight: |
| 133 return RightOf(target_rect, cur_rect); | 133 return RightOf(target_rect, cur_rect); |
| 134 case kWebFocusTypeUp: | 134 case kWebFocusTypeUp: |
| 135 return Below(cur_rect, target_rect); | 135 return Below(cur_rect, target_rect); |
| 136 case kWebFocusTypeDown: | 136 case kWebFocusTypeDown: |
| 137 return Below(target_rect, cur_rect); | 137 return Below(target_rect, cur_rect); |
| 138 default: | 138 default: |
| 139 ASSERT_NOT_REACHED(); | 139 NOTREACHED(); |
| 140 return false; | 140 return false; |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 // Checks if |node| is offscreen the visible area (viewport) of its container | 144 // Checks if |node| is offscreen the visible area (viewport) of its container |
| 145 // document. In case it is, one can scroll in direction or take any different | 145 // document. In case it is, one can scroll in direction or take any different |
| 146 // desired action later on. | 146 // desired action later on. |
| 147 bool HasOffscreenRect(Node* node, WebFocusType type) { | 147 bool HasOffscreenRect(Node* node, WebFocusType type) { |
| 148 // Get the FrameView in which |node| is (which means the current viewport if | 148 // Get the FrameView in which |node| is (which means the current viewport if |
| 149 // |node| is not in an inner document), so we can check if its content rect is | 149 // |node| is not in an inner document), so we can check if its content rect is |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 case kWebFocusTypeRight: | 212 case kWebFocusTypeRight: |
| 213 dx = pixels_per_line_step; | 213 dx = pixels_per_line_step; |
| 214 break; | 214 break; |
| 215 case kWebFocusTypeUp: | 215 case kWebFocusTypeUp: |
| 216 dy = -pixels_per_line_step; | 216 dy = -pixels_per_line_step; |
| 217 break; | 217 break; |
| 218 case kWebFocusTypeDown: | 218 case kWebFocusTypeDown: |
| 219 dy = pixels_per_line_step; | 219 dy = pixels_per_line_step; |
| 220 break; | 220 break; |
| 221 default: | 221 default: |
| 222 ASSERT_NOT_REACHED(); | 222 NOTREACHED(); |
| 223 return false; | 223 return false; |
| 224 } | 224 } |
| 225 | 225 |
| 226 frame->View()->ScrollBy(ScrollOffset(dx, dy), kUserScroll); | 226 frame->View()->ScrollBy(ScrollOffset(dx, dy), kUserScroll); |
| 227 return true; | 227 return true; |
| 228 } | 228 } |
| 229 return false; | 229 return false; |
| 230 } | 230 } |
| 231 | 231 |
| 232 bool ScrollInDirection(Node* container, WebFocusType type) { | 232 bool ScrollInDirection(Node* container, WebFocusType type) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 257 case kWebFocusTypeUp: | 257 case kWebFocusTypeUp: |
| 258 dy = -pixels_per_line_step; | 258 dy = -pixels_per_line_step; |
| 259 break; | 259 break; |
| 260 case kWebFocusTypeDown: | 260 case kWebFocusTypeDown: |
| 261 ASSERT(container->GetLayoutBox()->ScrollHeight() - | 261 ASSERT(container->GetLayoutBox()->ScrollHeight() - |
| 262 (container->GetLayoutBox()->ScrollTop() + | 262 (container->GetLayoutBox()->ScrollTop() + |
| 263 container->GetLayoutBox()->ClientHeight())); | 263 container->GetLayoutBox()->ClientHeight())); |
| 264 dy = pixels_per_line_step; | 264 dy = pixels_per_line_step; |
| 265 break; | 265 break; |
| 266 default: | 266 default: |
| 267 ASSERT_NOT_REACHED(); | 267 NOTREACHED(); |
| 268 return false; | 268 return false; |
| 269 } | 269 } |
| 270 | 270 |
| 271 container->GetLayoutBox()->ScrollByRecursively(ScrollOffset(dx, dy)); | 271 container->GetLayoutBox()->ScrollByRecursively(ScrollOffset(dx, dy)); |
| 272 return true; | 272 return true; |
| 273 } | 273 } |
| 274 | 274 |
| 275 return false; | 275 return false; |
| 276 } | 276 } |
| 277 | 277 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 container->GetLayoutBox()->ScrollLeft() + | 344 container->GetLayoutBox()->ScrollLeft() + |
| 345 container->GetLayoutBox()->ClientWidth() < | 345 container->GetLayoutBox()->ClientWidth() < |
| 346 container->GetLayoutBox()->ScrollWidth()); | 346 container->GetLayoutBox()->ScrollWidth()); |
| 347 case kWebFocusTypeDown: | 347 case kWebFocusTypeDown: |
| 348 return (container->GetLayoutObject()->Style()->OverflowY() != | 348 return (container->GetLayoutObject()->Style()->OverflowY() != |
| 349 EOverflow::kHidden && | 349 EOverflow::kHidden && |
| 350 container->GetLayoutBox()->ScrollTop() + | 350 container->GetLayoutBox()->ScrollTop() + |
| 351 container->GetLayoutBox()->ClientHeight() < | 351 container->GetLayoutBox()->ClientHeight() < |
| 352 container->GetLayoutBox()->ScrollHeight()); | 352 container->GetLayoutBox()->ScrollHeight()); |
| 353 default: | 353 default: |
| 354 ASSERT_NOT_REACHED(); | 354 NOTREACHED(); |
| 355 return false; | 355 return false; |
| 356 } | 356 } |
| 357 } | 357 } |
| 358 | 358 |
| 359 bool CanScrollInDirection(const LocalFrame* frame, WebFocusType type) { | 359 bool CanScrollInDirection(const LocalFrame* frame, WebFocusType type) { |
| 360 if (!frame->View()) | 360 if (!frame->View()) |
| 361 return false; | 361 return false; |
| 362 ScrollbarMode vertical_mode; | 362 ScrollbarMode vertical_mode; |
| 363 ScrollbarMode horizontal_mode; | 363 ScrollbarMode horizontal_mode; |
| 364 frame->View()->CalculateScrollbarModes(horizontal_mode, vertical_mode); | 364 frame->View()->CalculateScrollbarModes(horizontal_mode, vertical_mode); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 375 switch (type) { | 375 switch (type) { |
| 376 case kWebFocusTypeLeft: | 376 case kWebFocusTypeLeft: |
| 377 return offset.Width() > 0; | 377 return offset.Width() > 0; |
| 378 case kWebFocusTypeUp: | 378 case kWebFocusTypeUp: |
| 379 return offset.Height() > 0; | 379 return offset.Height() > 0; |
| 380 case kWebFocusTypeRight: | 380 case kWebFocusTypeRight: |
| 381 return rect.Width() + offset.Width() < size.Width(); | 381 return rect.Width() + offset.Width() < size.Width(); |
| 382 case kWebFocusTypeDown: | 382 case kWebFocusTypeDown: |
| 383 return rect.Height() + offset.Height() < size.Height(); | 383 return rect.Height() + offset.Height() < size.Height(); |
| 384 default: | 384 default: |
| 385 ASSERT_NOT_REACHED(); | 385 NOTREACHED(); |
| 386 return false; | 386 return false; |
| 387 } | 387 } |
| 388 } | 388 } |
| 389 | 389 |
| 390 static LayoutRect RectToAbsoluteCoordinates(LocalFrame* initial_frame, | 390 static LayoutRect RectToAbsoluteCoordinates(LocalFrame* initial_frame, |
| 391 const LayoutRect& initial_rect) { | 391 const LayoutRect& initial_rect) { |
| 392 LayoutRect rect = initial_rect; | 392 LayoutRect rect = initial_rect; |
| 393 for (Frame* frame = initial_frame; frame; frame = frame->Tree().Parent()) { | 393 for (Frame* frame = initial_frame; frame; frame = frame->Tree().Parent()) { |
| 394 if (!frame->IsLocalFrame()) | 394 if (!frame->IsLocalFrame()) |
| 395 continue; | 395 continue; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 entry_point.SetX(starting_rect.MaxX()); | 468 entry_point.SetX(starting_rect.MaxX()); |
| 469 break; | 469 break; |
| 470 case kWebFocusTypeDown: | 470 case kWebFocusTypeDown: |
| 471 exit_point.SetY(starting_rect.MaxY()); | 471 exit_point.SetY(starting_rect.MaxY()); |
| 472 if (potential_rect.Y() > starting_rect.MaxY()) | 472 if (potential_rect.Y() > starting_rect.MaxY()) |
| 473 entry_point.SetY(potential_rect.Y()); | 473 entry_point.SetY(potential_rect.Y()); |
| 474 else | 474 else |
| 475 entry_point.SetY(starting_rect.MaxY()); | 475 entry_point.SetY(starting_rect.MaxY()); |
| 476 break; | 476 break; |
| 477 default: | 477 default: |
| 478 ASSERT_NOT_REACHED(); | 478 NOTREACHED(); |
| 479 } | 479 } |
| 480 | 480 |
| 481 switch (type) { | 481 switch (type) { |
| 482 case kWebFocusTypeLeft: | 482 case kWebFocusTypeLeft: |
| 483 case kWebFocusTypeRight: | 483 case kWebFocusTypeRight: |
| 484 if (Below(starting_rect, potential_rect)) { | 484 if (Below(starting_rect, potential_rect)) { |
| 485 exit_point.SetY(starting_rect.Y()); | 485 exit_point.SetY(starting_rect.Y()); |
| 486 if (potential_rect.MaxY() < starting_rect.Y()) | 486 if (potential_rect.MaxY() < starting_rect.Y()) |
| 487 entry_point.SetY(potential_rect.MaxY()); | 487 entry_point.SetY(potential_rect.MaxY()); |
| 488 else | 488 else |
| (...skipping 22 matching lines...) Expand all Loading... |
| 511 if (potential_rect.X() > starting_rect.MaxX()) | 511 if (potential_rect.X() > starting_rect.MaxX()) |
| 512 entry_point.SetX(potential_rect.X()); | 512 entry_point.SetX(potential_rect.X()); |
| 513 else | 513 else |
| 514 entry_point.SetX(starting_rect.MaxX()); | 514 entry_point.SetX(starting_rect.MaxX()); |
| 515 } else { | 515 } else { |
| 516 exit_point.SetX(max(starting_rect.X(), potential_rect.X())); | 516 exit_point.SetX(max(starting_rect.X(), potential_rect.X())); |
| 517 entry_point.SetX(exit_point.X()); | 517 entry_point.SetX(exit_point.X()); |
| 518 } | 518 } |
| 519 break; | 519 break; |
| 520 default: | 520 default: |
| 521 ASSERT_NOT_REACHED(); | 521 NOTREACHED(); |
| 522 } | 522 } |
| 523 } | 523 } |
| 524 | 524 |
| 525 bool AreElementsOnSameLine(const FocusCandidate& first_candidate, | 525 bool AreElementsOnSameLine(const FocusCandidate& first_candidate, |
| 526 const FocusCandidate& second_candidate) { | 526 const FocusCandidate& second_candidate) { |
| 527 if (first_candidate.IsNull() || second_candidate.IsNull()) | 527 if (first_candidate.IsNull() || second_candidate.IsNull()) |
| 528 return false; | 528 return false; |
| 529 | 529 |
| 530 if (!first_candidate.visible_node->GetLayoutObject() || | 530 if (!first_candidate.visible_node->GetLayoutObject() || |
| 531 !second_candidate.visible_node->GetLayoutObject()) | 531 !second_candidate.visible_node->GetLayoutObject()) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 break; | 600 break; |
| 601 case kWebFocusTypeUp: | 601 case kWebFocusTypeUp: |
| 602 case kWebFocusTypeDown: | 602 case kWebFocusTypeDown: |
| 603 navigation_axis_distance = y_axis; | 603 navigation_axis_distance = y_axis; |
| 604 if (!RectsIntersectOnOrthogonalAxis(type, current_rect, node_rect)) | 604 if (!RectsIntersectOnOrthogonalAxis(type, current_rect, node_rect)) |
| 605 orthogonal_bias = (current_rect.Width() / 2).ToInt(); | 605 orthogonal_bias = (current_rect.Width() / 2).ToInt(); |
| 606 weighted_orthogonal_axis_distance = | 606 weighted_orthogonal_axis_distance = |
| 607 (x_axis + orthogonal_bias) * kOrthogonalWeightForUpDown; | 607 (x_axis + orthogonal_bias) * kOrthogonalWeightForUpDown; |
| 608 break; | 608 break; |
| 609 default: | 609 default: |
| 610 ASSERT_NOT_REACHED(); | 610 NOTREACHED(); |
| 611 return; | 611 return; |
| 612 } | 612 } |
| 613 | 613 |
| 614 double euclidian_distance_pow2 = | 614 double euclidian_distance_pow2 = |
| 615 (x_axis * x_axis + y_axis * y_axis).ToDouble(); | 615 (x_axis * x_axis + y_axis * y_axis).ToDouble(); |
| 616 LayoutRect intersection_rect = Intersection(current_rect, node_rect); | 616 LayoutRect intersection_rect = Intersection(current_rect, node_rect); |
| 617 double overlap = | 617 double overlap = |
| 618 (intersection_rect.Width() * intersection_rect.Height()).ToDouble(); | 618 (intersection_rect.Width() * intersection_rect.Height()).ToDouble(); |
| 619 | 619 |
| 620 // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handling | 620 // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handling |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 virtual_starting_rect.SetY(virtual_starting_rect.MaxY() - width); | 661 virtual_starting_rect.SetY(virtual_starting_rect.MaxY() - width); |
| 662 virtual_starting_rect.SetHeight(width); | 662 virtual_starting_rect.SetHeight(width); |
| 663 break; | 663 break; |
| 664 case kWebFocusTypeRight: | 664 case kWebFocusTypeRight: |
| 665 virtual_starting_rect.SetWidth(width); | 665 virtual_starting_rect.SetWidth(width); |
| 666 break; | 666 break; |
| 667 case kWebFocusTypeDown: | 667 case kWebFocusTypeDown: |
| 668 virtual_starting_rect.SetHeight(width); | 668 virtual_starting_rect.SetHeight(width); |
| 669 break; | 669 break; |
| 670 default: | 670 default: |
| 671 ASSERT_NOT_REACHED(); | 671 NOTREACHED(); |
| 672 } | 672 } |
| 673 | 673 |
| 674 return virtual_starting_rect; | 674 return virtual_starting_rect; |
| 675 } | 675 } |
| 676 | 676 |
| 677 LayoutRect VirtualRectForAreaElementAndDirection(HTMLAreaElement& area, | 677 LayoutRect VirtualRectForAreaElementAndDirection(HTMLAreaElement& area, |
| 678 WebFocusType type) { | 678 WebFocusType type) { |
| 679 ASSERT(area.ImageElement()); | 679 ASSERT(area.ImageElement()); |
| 680 // Area elements tend to overlap more than other focusable elements. We | 680 // Area elements tend to overlap more than other focusable elements. We |
| 681 // flatten the rect of the area elements to minimize the effect of overlapping | 681 // flatten the rect of the area elements to minimize the effect of overlapping |
| 682 // areas. | 682 // areas. |
| 683 LayoutRect rect = VirtualRectForDirection( | 683 LayoutRect rect = VirtualRectForDirection( |
| 684 type, | 684 type, |
| 685 RectToAbsoluteCoordinates( | 685 RectToAbsoluteCoordinates( |
| 686 area.GetDocument().GetFrame(), | 686 area.GetDocument().GetFrame(), |
| 687 area.ComputeAbsoluteRect(area.ImageElement()->GetLayoutObject())), | 687 area.ComputeAbsoluteRect(area.ImageElement()->GetLayoutObject())), |
| 688 LayoutUnit(1)); | 688 LayoutUnit(1)); |
| 689 return rect; | 689 return rect; |
| 690 } | 690 } |
| 691 | 691 |
| 692 HTMLFrameOwnerElement* FrameOwnerElement(FocusCandidate& candidate) { | 692 HTMLFrameOwnerElement* FrameOwnerElement(FocusCandidate& candidate) { |
| 693 return candidate.IsFrameOwnerElement() | 693 return candidate.IsFrameOwnerElement() |
| 694 ? ToHTMLFrameOwnerElement(candidate.visible_node) | 694 ? ToHTMLFrameOwnerElement(candidate.visible_node) |
| 695 : nullptr; | 695 : nullptr; |
| 696 }; | 696 }; |
| 697 | 697 |
| 698 } // namespace blink | 698 } // namespace blink |
| OLD | NEW |