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 |