| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. | 3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 { | 541 { |
| 542 if (candidate.isNull()) | 542 if (candidate.isNull()) |
| 543 return PositionType(); | 543 return PositionType(); |
| 544 ASSERT(candidate.isCandidate()); | 544 ASSERT(candidate.isCandidate()); |
| 545 PositionType upstream = candidate.upstream(); | 545 PositionType upstream = candidate.upstream(); |
| 546 if (upstream.isCandidate()) | 546 if (upstream.isCandidate()) |
| 547 return upstream; | 547 return upstream; |
| 548 return candidate; | 548 return candidate; |
| 549 } | 549 } |
| 550 | 550 |
| 551 static Position canonicalPosition(const Position& passedPosition) | 551 template <typename PositionType> |
| 552 static PositionType canonicalPosition(const PositionType& passedPosition) |
| 552 { | 553 { |
| 553 // Sometimes updating selection positions can be extremely expensive and occ
ur | 554 // Sometimes updating selection positions can be extremely expensive and occ
ur |
| 554 // frequently. Often calling preventDefault on mousedown events can avoid | 555 // frequently. Often calling preventDefault on mousedown events can avoid |
| 555 // doing unnecessary text selection work. http://crbug.com/472258. | 556 // doing unnecessary text selection work. http://crbug.com/472258. |
| 556 TRACE_EVENT0("blink", "VisiblePosition::canonicalPosition"); | 557 TRACE_EVENT0("blink", "VisiblePosition::canonicalPosition"); |
| 557 | 558 |
| 558 // The updateLayout call below can do so much that even the position passed | 559 // The updateLayout call below can do so much that even the position passed |
| 559 // in to us might get changed as a side effect. Specifically, there are code | 560 // in to us might get changed as a side effect. Specifically, there are code |
| 560 // paths that pass selection endpoints, and updateLayout can change the sele
ction. | 561 // paths that pass selection endpoints, and updateLayout can change the sele
ction. |
| 561 Position position = passedPosition; | 562 PositionType position = passedPosition; |
| 562 | 563 |
| 563 // FIXME (9535): Canonicalizing to the leftmost candidate means that if we'
re at a line wrap, we will | 564 // FIXME (9535): Canonicalizing to the leftmost candidate means that if we'
re at a line wrap, we will |
| 564 // ask layoutObjects to paint downstream carets for other layoutObjects. | 565 // ask layoutObjects to paint downstream carets for other layoutObjects. |
| 565 // To fix this, we need to either a) add code to all paintCarets to pass the
responsibility off to | 566 // To fix this, we need to either a) add code to all paintCarets to pass the
responsibility off to |
| 566 // the appropriate layoutObject for VisiblePosition's like these, or b) cano
nicalize to the rightmost candidate | 567 // the appropriate layoutObject for VisiblePosition's like these, or b) cano
nicalize to the rightmost candidate |
| 567 // unless the affinity is upstream. | 568 // unless the affinity is upstream. |
| 568 if (position.isNull()) | 569 if (position.isNull()) |
| 569 return Position(); | 570 return PositionType(); |
| 570 | 571 |
| 571 ASSERT(position.document()); | 572 ASSERT(position.document()); |
| 572 position.document()->updateLayoutIgnorePendingStylesheets(); | 573 position.document()->updateLayoutIgnorePendingStylesheets(); |
| 573 | 574 |
| 574 Node* node = position.containerNode(); | 575 Node* node = position.containerNode(); |
| 575 | 576 |
| 576 Position candidate = position.upstream(); | 577 PositionType candidate = position.upstream(); |
| 577 if (candidate.isCandidate()) | 578 if (candidate.isCandidate()) |
| 578 return candidate; | 579 return candidate; |
| 579 candidate = position.downstream(); | 580 candidate = position.downstream(); |
| 580 if (candidate.isCandidate()) | 581 if (candidate.isCandidate()) |
| 581 return candidate; | 582 return candidate; |
| 582 | 583 |
| 583 // When neither upstream or downstream gets us to a candidate (upstream/down
stream won't leave | 584 // When neither upstream or downstream gets us to a candidate (upstream/down
stream won't leave |
| 584 // blocks or enter new ones), we search forward and backward until we find o
ne. | 585 // blocks or enter new ones), we search forward and backward until we find o
ne. |
| 585 Position next = canonicalizeCandidate(nextCandidate(position)); | 586 PositionType next = canonicalizeCandidate(nextCandidate(position)); |
| 586 Position prev = canonicalizeCandidate(previousCandidate(position)); | 587 PositionType prev = canonicalizeCandidate(previousCandidate(position)); |
| 587 Node* nextNode = next.deprecatedNode(); | 588 Node* nextNode = next.deprecatedNode(); |
| 588 Node* prevNode = prev.deprecatedNode(); | 589 Node* prevNode = prev.deprecatedNode(); |
| 589 | 590 |
| 590 // The new position must be in the same editable element. Enforce that first
. | 591 // The new position must be in the same editable element. Enforce that first
. |
| 591 // Unless the descent is from a non-editable html element to an editable bod
y. | 592 // Unless the descent is from a non-editable html element to an editable bod
y. |
| 592 if (isHTMLHtmlElement(node) && !node->hasEditableStyle() && node->document()
.body() && node->document().body()->hasEditableStyle()) | 593 if (isHTMLHtmlElement(node) && !node->hasEditableStyle() && node->document()
.body() && node->document().body()->hasEditableStyle()) |
| 593 return next.isNotNull() ? next : prev; | 594 return next.isNotNull() ? next : prev; |
| 594 | 595 |
| 595 Element* editingRoot = editableRootForPosition(position); | 596 Element* editingRoot = editableRootForPosition(position); |
| 596 | 597 |
| 597 // If the html element is editable, descending into its body will look like
a descent | 598 // If the html element is editable, descending into its body will look like
a descent |
| 598 // from non-editable to editable content since rootEditableElement() always
stops at the body. | 599 // from non-editable to editable content since rootEditableElement() always
stops at the body. |
| 599 if (isHTMLHtmlElement(editingRoot) || position.deprecatedNode()->isDocumentN
ode()) | 600 if (isHTMLHtmlElement(editingRoot) || position.deprecatedNode()->isDocumentN
ode()) |
| 600 return next.isNotNull() ? next : prev; | 601 return next.isNotNull() ? next : prev; |
| 601 | 602 |
| 602 bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev)
== editingRoot; | 603 bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev)
== editingRoot; |
| 603 bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next)
== editingRoot; | 604 bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next)
== editingRoot; |
| 604 if (prevIsInSameEditableElement && !nextIsInSameEditableElement) | 605 if (prevIsInSameEditableElement && !nextIsInSameEditableElement) |
| 605 return prev; | 606 return prev; |
| 606 | 607 |
| 607 if (nextIsInSameEditableElement && !prevIsInSameEditableElement) | 608 if (nextIsInSameEditableElement && !prevIsInSameEditableElement) |
| 608 return next; | 609 return next; |
| 609 | 610 |
| 610 if (!nextIsInSameEditableElement && !prevIsInSameEditableElement) | 611 if (!nextIsInSameEditableElement && !prevIsInSameEditableElement) |
| 611 return Position(); | 612 return PositionType(); |
| 612 | 613 |
| 613 // The new position should be in the same block flow element. Favor that. | 614 // The new position should be in the same block flow element. Favor that. |
| 614 Element* originalBlock = node ? enclosingBlockFlowElement(*node) : 0; | 615 Element* originalBlock = node ? enclosingBlockFlowElement(*node) : 0; |
| 615 bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) &
& nextNode != originalBlock; | 616 bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) &
& nextNode != originalBlock; |
| 616 bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) &
& prevNode != originalBlock; | 617 bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) &
& prevNode != originalBlock; |
| 617 if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock) | 618 if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock) |
| 618 return prev; | 619 return prev; |
| 619 | 620 |
| 620 return next; | 621 return next; |
| 621 } | 622 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 else | 799 else |
| 799 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); | 800 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); |
| 800 } | 801 } |
| 801 | 802 |
| 802 void showTree(const blink::VisiblePosition& vpos) | 803 void showTree(const blink::VisiblePosition& vpos) |
| 803 { | 804 { |
| 804 vpos.showTreeForThis(); | 805 vpos.showTreeForThis(); |
| 805 } | 806 } |
| 806 | 807 |
| 807 #endif | 808 #endif |
| OLD | NEW |