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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 | 56 |
57 m_deepPosition = canonicalPosition(position); | 57 m_deepPosition = canonicalPosition(position); |
58 | 58 |
59 // When not at a line wrap, make sure to end up with DOWNSTREAM affinity. | 59 // When not at a line wrap, make sure to end up with DOWNSTREAM affinity. |
60 if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(positi
on, DOWNSTREAM), *this))) | 60 if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(positi
on, DOWNSTREAM), *this))) |
61 m_affinity = DOWNSTREAM; | 61 m_affinity = DOWNSTREAM; |
62 } | 62 } |
63 | 63 |
64 VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const | 64 VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const |
65 { | 65 { |
66 // FIXME: Support CanSkipEditingBoundary | |
67 ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary
); | |
68 VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affini
ty); | 66 VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affini
ty); |
69 | 67 |
70 if (rule == CanCrossEditingBoundary) | 68 switch (rule) { |
| 69 case CanCrossEditingBoundary: |
71 return next; | 70 return next; |
72 | 71 case CannotCrossEditingBoundary: |
73 return honorEditingBoundaryAtOrAfter(next); | 72 return honorEditingBoundaryAtOrAfter(next); |
| 73 case CanSkipOverEditingBoundary: |
| 74 return skipToEndOfEditingBoundary(next); |
| 75 } |
74 } | 76 } |
75 | 77 |
76 VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) cons
t | 78 VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) cons
t |
77 { | 79 { |
78 // FIXME: Support CanSkipEditingBoundary | |
79 ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary
); | |
80 // find first previous DOM position that is visible | |
81 Position pos = previousVisuallyDistinctCandidate(m_deepPosition); | 80 Position pos = previousVisuallyDistinctCandidate(m_deepPosition); |
82 | 81 |
83 // return null visible position if there is no previous visible position | 82 // return null visible position if there is no previous visible position |
84 if (pos.atStartOfTree()) | 83 if (pos.atStartOfTree()) |
85 return VisiblePosition(); | 84 return VisiblePosition(); |
86 | 85 |
87 VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); | 86 VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); |
88 ASSERT(prev != *this); | 87 ASSERT(prev != *this); |
89 | 88 |
90 #ifndef NDEBUG | 89 #ifndef NDEBUG |
91 // we should always be able to make the affinity DOWNSTREAM, because going p
revious from an | 90 // we should always be able to make the affinity DOWNSTREAM, because going p
revious from an |
92 // UPSTREAM position can never yield another UPSTREAM position (unless line
wrap length is 0!). | 91 // UPSTREAM position can never yield another UPSTREAM position (unless line
wrap length is 0!). |
93 if (prev.isNotNull() && m_affinity == UPSTREAM) { | 92 if (prev.isNotNull() && m_affinity == UPSTREAM) { |
94 VisiblePosition temp = prev; | 93 VisiblePosition temp = prev; |
95 temp.setAffinity(UPSTREAM); | 94 temp.setAffinity(UPSTREAM); |
96 ASSERT(inSameLine(temp, prev)); | 95 ASSERT(inSameLine(temp, prev)); |
97 } | 96 } |
98 #endif | 97 #endif |
99 | 98 |
100 if (rule == CanCrossEditingBoundary) | 99 switch (rule) { |
| 100 case CanCrossEditingBoundary: |
101 return prev; | 101 return prev; |
102 | 102 case CannotCrossEditingBoundary: |
103 return honorEditingBoundaryAtOrBefore(prev); | 103 return honorEditingBoundaryAtOrBefore(prev); |
| 104 case CanSkipOverEditingBoundary: |
| 105 return skipToStartOfEditingBoundary(prev); |
| 106 } |
104 } | 107 } |
105 | 108 |
106 Position VisiblePosition::leftVisuallyDistinctCandidate() const | 109 Position VisiblePosition::leftVisuallyDistinctCandidate() const |
107 { | 110 { |
108 Position p = m_deepPosition; | 111 Position p = m_deepPosition; |
109 if (p.isNull()) | 112 if (p.isNull()) |
110 return Position(); | 113 return Position(); |
111 | 114 |
112 Position downstreamStart = p.downstream(); | 115 Position downstreamStart = p.downstream(); |
113 TextDirection primaryDirection = p.primaryDirection(); | 116 TextDirection primaryDirection = p.primaryDirection(); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 | 484 |
482 // Return empty position if this position is non-editable, but pos is editab
le | 485 // Return empty position if this position is non-editable, but pos is editab
le |
483 // FIXME: Move to the next non-editable region. | 486 // FIXME: Move to the next non-editable region. |
484 if (!highestRoot) | 487 if (!highestRoot) |
485 return VisiblePosition(); | 488 return VisiblePosition(); |
486 | 489 |
487 // Return the next position after pos that is in the same editable region as
this position | 490 // Return the next position after pos that is in the same editable region as
this position |
488 return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highes
tRoot); | 491 return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highes
tRoot); |
489 } | 492 } |
490 | 493 |
| 494 VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosit
ion &pos) const |
| 495 { |
| 496 if (pos.isNull()) |
| 497 return pos; |
| 498 |
| 499 Node* highestRoot = highestEditableRoot(deepEquivalent()); |
| 500 Node* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
| 501 |
| 502 // Return pos itself if the two are from the very same editable region, or b
oth are non-editable. |
| 503 if (highestRootOfPos == highestRoot) |
| 504 return pos; |
| 505 |
| 506 // If |pos| has an editable root, skip to the start |
| 507 if (highestRootOfPos) |
| 508 return previousVisuallyDistinctCandidate(Position(highestRootOfPos, Posi
tion::PositionIsBeforeAnchor).parentAnchoredEquivalent()); |
| 509 |
| 510 // 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 |
| 511 return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highes
tRoot); |
| 512 } |
| 513 |
| 514 VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePositio
n &pos) const |
| 515 { |
| 516 if (pos.isNull()) |
| 517 return pos; |
| 518 |
| 519 Node* highestRoot = highestEditableRoot(deepEquivalent()); |
| 520 Node* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
| 521 |
| 522 // Return pos itself if the two are from the very same editable region, or b
oth are non-editable. |
| 523 if (highestRootOfPos == highestRoot) |
| 524 return pos; |
| 525 |
| 526 // If |pos| has an editable root, skip to the end |
| 527 if (highestRootOfPos) |
| 528 return Position(highestRootOfPos, Position::PositionIsAfterAnchor).paren
tAnchoredEquivalent(); |
| 529 |
| 530 // That must mean that |pos| is not editable. Return the next position after
pos that is in the same editable region as this position |
| 531 return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highes
tRoot); |
| 532 } |
| 533 |
491 static Position canonicalizeCandidate(const Position& candidate) | 534 static Position canonicalizeCandidate(const Position& candidate) |
492 { | 535 { |
493 if (candidate.isNull()) | 536 if (candidate.isNull()) |
494 return Position(); | 537 return Position(); |
495 ASSERT(candidate.isCandidate()); | 538 ASSERT(candidate.isCandidate()); |
496 Position upstream = candidate.upstream(); | 539 Position upstream = candidate.upstream(); |
497 if (upstream.isCandidate()) | 540 if (upstream.isCandidate()) |
498 return upstream; | 541 return upstream; |
499 return candidate; | 542 return candidate; |
500 } | 543 } |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 if (vpos) | 791 if (vpos) |
749 vpos->showTreeForThis(); | 792 vpos->showTreeForThis(); |
750 } | 793 } |
751 | 794 |
752 void showTree(const WebCore::VisiblePosition& vpos) | 795 void showTree(const WebCore::VisiblePosition& vpos) |
753 { | 796 { |
754 vpos.showTreeForThis(); | 797 vpos.showTreeForThis(); |
755 } | 798 } |
756 | 799 |
757 #endif | 800 #endif |
OLD | NEW |