| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 m_deepPosition = canonicalPosition(position); | 66 m_deepPosition = canonicalPosition(position); |
| 67 | 67 |
| 68 // When not at a line wrap, make sure to end up with DOWNSTREAM affinity. | 68 // When not at a line wrap, make sure to end up with DOWNSTREAM affinity. |
| 69 if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(positi
on, DOWNSTREAM), *this))) | 69 if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(positi
on, DOWNSTREAM), *this))) |
| 70 m_affinity = DOWNSTREAM; | 70 m_affinity = DOWNSTREAM; |
| 71 } | 71 } |
| 72 | 72 |
| 73 VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const | 73 VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const |
| 74 { | 74 { |
| 75 // FIXME: Support CanSkipEditingBoundary | |
| 76 ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary
); | |
| 77 VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affini
ty); | 75 VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affini
ty); |
| 78 | 76 |
| 79 if (rule == CanCrossEditingBoundary) | 77 switch (rule) { |
| 78 case CanCrossEditingBoundary: |
| 80 return next; | 79 return next; |
| 81 | 80 case CannotCrossEditingBoundary: |
| 81 return honorEditingBoundaryAtOrAfter(next); |
| 82 case CanSkipOverEditingBoundary: |
| 83 return skipToEndOfEditingBoundary(next); |
| 84 } |
| 85 ASSERT_NOT_REACHED(); |
| 82 return honorEditingBoundaryAtOrAfter(next); | 86 return honorEditingBoundaryAtOrAfter(next); |
| 83 } | 87 } |
| 84 | 88 |
| 85 VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) cons
t | 89 VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) cons
t |
| 86 { | 90 { |
| 87 // FIXME: Support CanSkipEditingBoundary | |
| 88 ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary
); | |
| 89 // find first previous DOM position that is visible | |
| 90 Position pos = previousVisuallyDistinctCandidate(m_deepPosition); | 91 Position pos = previousVisuallyDistinctCandidate(m_deepPosition); |
| 91 | 92 |
| 92 // return null visible position if there is no previous visible position | 93 // return null visible position if there is no previous visible position |
| 93 if (pos.atStartOfTree()) | 94 if (pos.atStartOfTree()) |
| 94 return VisiblePosition(); | 95 return VisiblePosition(); |
| 95 | 96 |
| 96 VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); | 97 VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); |
| 97 ASSERT(prev != *this); | 98 ASSERT(prev != *this); |
| 98 | 99 |
| 99 #ifndef NDEBUG | 100 #ifndef NDEBUG |
| 100 // we should always be able to make the affinity DOWNSTREAM, because going p
revious from an | 101 // we should always be able to make the affinity DOWNSTREAM, because going p
revious from an |
| 101 // UPSTREAM position can never yield another UPSTREAM position (unless line
wrap length is 0!). | 102 // UPSTREAM position can never yield another UPSTREAM position (unless line
wrap length is 0!). |
| 102 if (prev.isNotNull() && m_affinity == UPSTREAM) { | 103 if (prev.isNotNull() && m_affinity == UPSTREAM) { |
| 103 VisiblePosition temp = prev; | 104 VisiblePosition temp = prev; |
| 104 temp.setAffinity(UPSTREAM); | 105 temp.setAffinity(UPSTREAM); |
| 105 ASSERT(inSameLine(temp, prev)); | 106 ASSERT(inSameLine(temp, prev)); |
| 106 } | 107 } |
| 107 #endif | 108 #endif |
| 108 | 109 |
| 109 if (rule == CanCrossEditingBoundary) | 110 switch (rule) { |
| 111 case CanCrossEditingBoundary: |
| 110 return prev; | 112 return prev; |
| 113 case CannotCrossEditingBoundary: |
| 114 return honorEditingBoundaryAtOrBefore(prev); |
| 115 case CanSkipOverEditingBoundary: |
| 116 return skipToStartOfEditingBoundary(prev); |
| 117 } |
| 111 | 118 |
| 119 ASSERT_NOT_REACHED(); |
| 112 return honorEditingBoundaryAtOrBefore(prev); | 120 return honorEditingBoundaryAtOrBefore(prev); |
| 113 } | 121 } |
| 114 | 122 |
| 115 Position VisiblePosition::leftVisuallyDistinctCandidate() const | 123 Position VisiblePosition::leftVisuallyDistinctCandidate() const |
| 116 { | 124 { |
| 117 Position p = m_deepPosition; | 125 Position p = m_deepPosition; |
| 118 if (p.isNull()) | 126 if (p.isNull()) |
| 119 return Position(); | 127 return Position(); |
| 120 | 128 |
| 121 Position downstreamStart = p.downstream(); | 129 Position downstreamStart = p.downstream(); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 498 |
| 491 // Return empty position if this position is non-editable, but pos is editab
le | 499 // Return empty position if this position is non-editable, but pos is editab
le |
| 492 // FIXME: Move to the next non-editable region. | 500 // FIXME: Move to the next non-editable region. |
| 493 if (!highestRoot) | 501 if (!highestRoot) |
| 494 return VisiblePosition(); | 502 return VisiblePosition(); |
| 495 | 503 |
| 496 // Return the next position after pos that is in the same editable region as
this position | 504 // Return the next position after pos that is in the same editable region as
this position |
| 497 return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highes
tRoot); | 505 return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highes
tRoot); |
| 498 } | 506 } |
| 499 | 507 |
| 508 VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosit
ion &pos) const |
| 509 { |
| 510 if (pos.isNull()) |
| 511 return pos; |
| 512 |
| 513 Node* highestRoot = highestEditableRoot(deepEquivalent()); |
| 514 Node* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
| 515 |
| 516 // Return pos itself if the two are from the very same editable region, or b
oth are non-editable. |
| 517 if (highestRootOfPos == highestRoot) |
| 518 return pos; |
| 519 |
| 520 // If |pos| has an editable root, skip to the start |
| 521 if (highestRootOfPos) |
| 522 return previousVisuallyDistinctCandidate(Position(highestRootOfPos, Posi
tion::PositionIsBeforeAnchor).parentAnchoredEquivalent()); |
| 523 |
| 524 // That must mean that |pos| is not editable. Return the last position befor
e pos that is in the same editable region as this position |
| 525 return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highes
tRoot); |
| 526 } |
| 527 |
| 528 VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePositio
n &pos) const |
| 529 { |
| 530 if (pos.isNull()) |
| 531 return pos; |
| 532 |
| 533 Node* highestRoot = highestEditableRoot(deepEquivalent()); |
| 534 Node* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
| 535 |
| 536 // Return pos itself if the two are from the very same editable region, or b
oth are non-editable. |
| 537 if (highestRootOfPos == highestRoot) |
| 538 return pos; |
| 539 |
| 540 // If |pos| has an editable root, skip to the end |
| 541 if (highestRootOfPos) |
| 542 return Position(highestRootOfPos, Position::PositionIsAfterAnchor).paren
tAnchoredEquivalent(); |
| 543 |
| 544 // That must mean that |pos| is not editable. Return the next position after
pos that is in the same editable region as this position |
| 545 return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highes
tRoot); |
| 546 } |
| 547 |
| 500 static Position canonicalizeCandidate(const Position& candidate) | 548 static Position canonicalizeCandidate(const Position& candidate) |
| 501 { | 549 { |
| 502 if (candidate.isNull()) | 550 if (candidate.isNull()) |
| 503 return Position(); | 551 return Position(); |
| 504 ASSERT(candidate.isCandidate()); | 552 ASSERT(candidate.isCandidate()); |
| 505 Position upstream = candidate.upstream(); | 553 Position upstream = candidate.upstream(); |
| 506 if (upstream.isCandidate()) | 554 if (upstream.isCandidate()) |
| 507 return upstream; | 555 return upstream; |
| 508 return candidate; | 556 return candidate; |
| 509 } | 557 } |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 if (vpos) | 805 if (vpos) |
| 758 vpos->showTreeForThis(); | 806 vpos->showTreeForThis(); |
| 759 } | 807 } |
| 760 | 808 |
| 761 void showTree(const WebCore::VisiblePosition& vpos) | 809 void showTree(const WebCore::VisiblePosition& vpos) |
| 762 { | 810 { |
| 763 vpos.showTreeForThis(); | 811 vpos.showTreeForThis(); |
| 764 } | 812 } |
| 765 | 813 |
| 766 #endif | 814 #endif |
| OLD | NEW |