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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 ASSERT_NOT_REACHED(); | 113 ASSERT_NOT_REACHED(); |
114 return honorEditingBoundaryAtOrBefore(prev); | 114 return honorEditingBoundaryAtOrBefore(prev); |
115 } | 115 } |
116 | 116 |
117 Position VisiblePosition::leftVisuallyDistinctCandidate() const | 117 Position VisiblePosition::leftVisuallyDistinctCandidate() const |
118 { | 118 { |
119 Position p = m_deepPosition; | 119 Position p = m_deepPosition; |
120 if (p.isNull()) | 120 if (p.isNull()) |
121 return Position(); | 121 return Position(); |
122 | 122 |
123 Position downstreamStart = p.downstream(); | 123 Position downstreamStart = mostForwardCaretPosition(p); |
124 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 124 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
125 | 125 |
126 while (true) { | 126 while (true) { |
127 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, m_affinity,
primaryDirection); | 127 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, m_affinity,
primaryDirection); |
128 InlineBox* box = boxPosition.inlineBox; | 128 InlineBox* box = boxPosition.inlineBox; |
129 int offset = boxPosition.offsetInBox; | 129 int offset = boxPosition.offsetInBox; |
130 if (!box) | 130 if (!box) |
131 return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m
_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); | 131 return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m
_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); |
132 | 132 |
133 LayoutObject* layoutObject = &box->layoutObject(); | 133 LayoutObject* layoutObject = &box->layoutObject(); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 level = box->bidiLevel(); | 246 level = box->bidiLevel(); |
247 } | 247 } |
248 layoutObject = &box->layoutObject(); | 248 layoutObject = &box->layoutObject(); |
249 offset = primaryDirection == LTR ? box->caretMinOffset() : box->
caretMaxOffset(); | 249 offset = primaryDirection == LTR ? box->caretMinOffset() : box->
caretMaxOffset(); |
250 } | 250 } |
251 break; | 251 break; |
252 } | 252 } |
253 | 253 |
254 p = Position::editingPositionOf(layoutObject->node(), offset); | 254 p = Position::editingPositionOf(layoutObject->node(), offset); |
255 | 255 |
256 if ((isVisuallyEquivalentCandidate(p) && p.downstream() != downstreamSta
rt) || p.atStartOfTree() || p.atEndOfTree()) | 256 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) |
257 return p; | 257 return p; |
258 | 258 |
259 ASSERT(p != m_deepPosition); | 259 ASSERT(p != m_deepPosition); |
260 } | 260 } |
261 } | 261 } |
262 | 262 |
263 VisiblePosition VisiblePosition::left() const | 263 VisiblePosition VisiblePosition::left() const |
264 { | 264 { |
265 Position pos = leftVisuallyDistinctCandidate(); | 265 Position pos = leftVisuallyDistinctCandidate(); |
266 // FIXME: Why can't we move left from the last position in a tree? | 266 // FIXME: Why can't we move left from the last position in a tree? |
267 if (pos.atStartOfTree() || pos.atEndOfTree()) | 267 if (pos.atStartOfTree() || pos.atEndOfTree()) |
268 return VisiblePosition(); | 268 return VisiblePosition(); |
269 | 269 |
270 VisiblePosition left = VisiblePosition(pos); | 270 VisiblePosition left = VisiblePosition(pos); |
271 ASSERT(left.deepEquivalent() != m_deepPosition); | 271 ASSERT(left.deepEquivalent() != m_deepPosition); |
272 | 272 |
273 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin
gBoundaryAtOrBefore(left) : honorEditingBoundaryAtOrAfter(left); | 273 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin
gBoundaryAtOrBefore(left) : honorEditingBoundaryAtOrAfter(left); |
274 } | 274 } |
275 | 275 |
276 Position VisiblePosition::rightVisuallyDistinctCandidate() const | 276 Position VisiblePosition::rightVisuallyDistinctCandidate() const |
277 { | 277 { |
278 Position p = m_deepPosition; | 278 Position p = m_deepPosition; |
279 if (p.isNull()) | 279 if (p.isNull()) |
280 return Position(); | 280 return Position(); |
281 | 281 |
282 Position downstreamStart = p.downstream(); | 282 Position downstreamStart = mostForwardCaretPosition(p); |
283 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 283 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
284 | 284 |
285 while (true) { | 285 while (true) { |
286 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, m_affinity,
primaryDirection); | 286 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, m_affinity,
primaryDirection); |
287 InlineBox* box = boxPosition.inlineBox; | 287 InlineBox* box = boxPosition.inlineBox; |
288 int offset = boxPosition.offsetInBox; | 288 int offset = boxPosition.offsetInBox; |
289 if (!box) | 289 if (!box) |
290 return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_dee
pPosition) : previousVisuallyDistinctCandidate(m_deepPosition); | 290 return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_dee
pPosition) : previousVisuallyDistinctCandidate(m_deepPosition); |
291 | 291 |
292 LayoutObject* layoutObject = &box->layoutObject(); | 292 LayoutObject* layoutObject = &box->layoutObject(); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 level = box->bidiLevel(); | 408 level = box->bidiLevel(); |
409 } | 409 } |
410 layoutObject = &box->layoutObject(); | 410 layoutObject = &box->layoutObject(); |
411 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->
caretMinOffset(); | 411 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->
caretMinOffset(); |
412 } | 412 } |
413 break; | 413 break; |
414 } | 414 } |
415 | 415 |
416 p = Position::editingPositionOf(layoutObject->node(), offset); | 416 p = Position::editingPositionOf(layoutObject->node(), offset); |
417 | 417 |
418 if ((isVisuallyEquivalentCandidate(p) && p.downstream() != downstreamSta
rt) || p.atStartOfTree() || p.atEndOfTree()) | 418 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) |
419 return p; | 419 return p; |
420 | 420 |
421 ASSERT(p != m_deepPosition); | 421 ASSERT(p != m_deepPosition); |
422 } | 422 } |
423 } | 423 } |
424 | 424 |
425 VisiblePosition VisiblePosition::right() const | 425 VisiblePosition VisiblePosition::right() const |
426 { | 426 { |
427 Position pos = rightVisuallyDistinctCandidate(); | 427 Position pos = rightVisuallyDistinctCandidate(); |
428 // FIXME: Why can't we move left from the last position in a tree? | 428 // FIXME: Why can't we move left from the last position in a tree? |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 // That must mean that |pos| is not editable. Return the next position after
pos that is in the same editable region as this position | 542 // That must mean that |pos| is not editable. Return the next position after
pos that is in the same editable region as this position |
543 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
highestRoot); | 543 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
highestRoot); |
544 } | 544 } |
545 | 545 |
546 template <typename PositionType> | 546 template <typename PositionType> |
547 static PositionType canonicalizeCandidate(const PositionType& candidate) | 547 static PositionType canonicalizeCandidate(const PositionType& candidate) |
548 { | 548 { |
549 if (candidate.isNull()) | 549 if (candidate.isNull()) |
550 return PositionType(); | 550 return PositionType(); |
551 ASSERT(isVisuallyEquivalentCandidate(candidate)); | 551 ASSERT(isVisuallyEquivalentCandidate(candidate)); |
552 PositionType upstream = candidate.upstream(); | 552 PositionType upstream = mostBackwardCaretPosition(candidate); |
553 if (isVisuallyEquivalentCandidate(upstream)) | 553 if (isVisuallyEquivalentCandidate(upstream)) |
554 return upstream; | 554 return upstream; |
555 return candidate; | 555 return candidate; |
556 } | 556 } |
557 | 557 |
558 template <typename PositionType> | 558 template <typename PositionType> |
559 static PositionType canonicalPosition(const PositionType& passedPosition) | 559 static PositionType canonicalPosition(const PositionType& passedPosition) |
560 { | 560 { |
561 // Sometimes updating selection positions can be extremely expensive and occ
ur | 561 // Sometimes updating selection positions can be extremely expensive and occ
ur |
562 // frequently. Often calling preventDefault on mousedown events can avoid | 562 // frequently. Often calling preventDefault on mousedown events can avoid |
(...skipping 11 matching lines...) Expand all Loading... |
574 // the appropriate layoutObject for VisiblePosition's like these, or b) cano
nicalize to the rightmost candidate | 574 // the appropriate layoutObject for VisiblePosition's like these, or b) cano
nicalize to the rightmost candidate |
575 // unless the affinity is upstream. | 575 // unless the affinity is upstream. |
576 if (position.isNull()) | 576 if (position.isNull()) |
577 return PositionType(); | 577 return PositionType(); |
578 | 578 |
579 ASSERT(position.document()); | 579 ASSERT(position.document()); |
580 position.document()->updateLayoutIgnorePendingStylesheets(); | 580 position.document()->updateLayoutIgnorePendingStylesheets(); |
581 | 581 |
582 Node* node = position.computeContainerNode(); | 582 Node* node = position.computeContainerNode(); |
583 | 583 |
584 PositionType candidate = position.upstream(); | 584 PositionType candidate = mostBackwardCaretPosition(position); |
585 if (isVisuallyEquivalentCandidate(candidate)) | 585 if (isVisuallyEquivalentCandidate(candidate)) |
586 return candidate; | 586 return candidate; |
587 candidate = position.downstream(); | 587 candidate = mostForwardCaretPosition(position); |
588 if (isVisuallyEquivalentCandidate(candidate)) | 588 if (isVisuallyEquivalentCandidate(candidate)) |
589 return candidate; | 589 return candidate; |
590 | 590 |
591 // When neither upstream or downstream gets us to a candidate (upstream/down
stream won't leave | 591 // When neither upstream or downstream gets us to a candidate (upstream/down
stream won't leave |
592 // blocks or enter new ones), we search forward and backward until we find o
ne. | 592 // blocks or enter new ones), we search forward and backward until we find o
ne. |
593 PositionType next = canonicalizeCandidate(nextCandidate(position)); | 593 PositionType next = canonicalizeCandidate(nextCandidate(position)); |
594 PositionType prev = canonicalizeCandidate(previousCandidate(position)); | 594 PositionType prev = canonicalizeCandidate(previousCandidate(position)); |
595 Node* nextNode = next.anchorNode(); | 595 Node* nextNode = next.anchorNode(); |
596 Node* prevNode = prev.anchorNode(); | 596 Node* prevNode = prev.anchorNode(); |
597 | 597 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 if (!inSameLine(PositionWithAffinityTemplate<Strategy>(deepPosition), Positi
onWithAffinityTemplate<Strategy>(deepPosition, TextAffinity::Upstream))) | 659 if (!inSameLine(PositionWithAffinityTemplate<Strategy>(deepPosition), Positi
onWithAffinityTemplate<Strategy>(deepPosition, TextAffinity::Upstream))) |
660 return; | 660 return; |
661 m_affinity = TextAffinity::Downstream; | 661 m_affinity = TextAffinity::Downstream; |
662 } | 662 } |
663 | 663 |
664 UChar32 VisiblePosition::characterAfter() const | 664 UChar32 VisiblePosition::characterAfter() const |
665 { | 665 { |
666 // We canonicalize to the first of two equivalent candidates, but the second | 666 // We canonicalize to the first of two equivalent candidates, but the second |
667 // of the two candidates is the one that will be inside the text node | 667 // of the two candidates is the one that will be inside the text node |
668 // containing the character after this visible position. | 668 // containing the character after this visible position. |
669 Position pos = m_deepPosition.downstream(); | 669 Position pos = mostForwardCaretPosition(m_deepPosition); |
670 if (!pos.isOffsetInAnchor()) | 670 if (!pos.isOffsetInAnchor()) |
671 return 0; | 671 return 0; |
672 Node* containerNode = pos.computeContainerNode(); | 672 Node* containerNode = pos.computeContainerNode(); |
673 if (!containerNode || !containerNode->isTextNode()) | 673 if (!containerNode || !containerNode->isTextNode()) |
674 return 0; | 674 return 0; |
675 unsigned offset = static_cast<unsigned>(pos.offsetInContainerNode()); | 675 unsigned offset = static_cast<unsigned>(pos.offsetInContainerNode()); |
676 Text* textNode = toText(containerNode); | 676 Text* textNode = toText(containerNode); |
677 unsigned length = textNode->length(); | 677 unsigned length = textNode->length(); |
678 if (offset >= length) | 678 if (offset >= length) |
679 return 0; | 679 return 0; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 else | 769 else |
770 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); | 770 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); |
771 } | 771 } |
772 | 772 |
773 void showTree(const blink::VisiblePosition& vpos) | 773 void showTree(const blink::VisiblePosition& vpos) |
774 { | 774 { |
775 vpos.showTreeForThis(); | 775 vpos.showTreeForThis(); |
776 } | 776 } |
777 | 777 |
778 #endif | 778 #endif |
OLD | NEW |