| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 { | 612 { |
| 613 return inRenderedTextAlgorithm<EditingStrategy>(position); | 613 return inRenderedTextAlgorithm<EditingStrategy>(position); |
| 614 } | 614 } |
| 615 | 615 |
| 616 bool inRenderedText(const PositionInComposedTree& position) | 616 bool inRenderedText(const PositionInComposedTree& position) |
| 617 { | 617 { |
| 618 return inRenderedTextAlgorithm<EditingInComposedTreeStrategy>(position); | 618 return inRenderedTextAlgorithm<EditingInComposedTreeStrategy>(position); |
| 619 } | 619 } |
| 620 | 620 |
| 621 template <typename Strategy> | 621 template <typename Strategy> |
| 622 InlineBoxPosition PositionAlgorithm<Strategy>::computeInlineBoxPosition(TextAffi
nity affinity) const | 622 static InlineBoxPosition computeInlineBoxPositionAlgorithm(const PositionAlgorit
hm<Strategy>& position, TextAffinity affinity) |
| 623 { | 623 { |
| 624 return computeInlineBoxPosition(affinity, primaryDirectionOf(*anchorNode()))
; | 624 return computeInlineBoxPositionAlgorithm<Strategy>(position, affinity, prima
ryDirectionOf(*position.anchorNode())); |
| 625 } |
| 626 |
| 627 InlineBoxPosition computeInlineBoxPosition(const Position& position, TextAffinit
y affinity) |
| 628 { |
| 629 return computeInlineBoxPositionAlgorithm<EditingStrategy>(position, affinity
); |
| 630 } |
| 631 |
| 632 InlineBoxPosition computeInlineBoxPosition(const PositionInComposedTree& positio
n, TextAffinity affinity) |
| 633 { |
| 634 return computeInlineBoxPositionAlgorithm<EditingInComposedTreeStrategy>(posi
tion, affinity); |
| 625 } | 635 } |
| 626 | 636 |
| 627 static bool isNonTextLeafChild(LayoutObject* object) | 637 static bool isNonTextLeafChild(LayoutObject* object) |
| 628 { | 638 { |
| 629 if (object->slowFirstChild()) | 639 if (object->slowFirstChild()) |
| 630 return false; | 640 return false; |
| 631 if (object->isText()) | 641 if (object->isText()) |
| 632 return false; | 642 return false; |
| 633 return true; | 643 return true; |
| 634 } | 644 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 { | 686 { |
| 677 PositionAlgorithm<Strategy> lastPosition; | 687 PositionAlgorithm<Strategy> lastPosition; |
| 678 while (position != lastPosition) { | 688 while (position != lastPosition) { |
| 679 lastPosition = position; | 689 lastPosition = position; |
| 680 position = position.upstream(CanCrossEditingBoundary); | 690 position = position.upstream(CanCrossEditingBoundary); |
| 681 } | 691 } |
| 682 return position; | 692 return position; |
| 683 } | 693 } |
| 684 | 694 |
| 685 template <typename Strategy> | 695 template <typename Strategy> |
| 686 InlineBoxPosition PositionAlgorithm<Strategy>::computeInlineBoxPosition(TextAffi
nity affinity, TextDirection primaryDirection) const | 696 static InlineBoxPosition computeInlineBoxPositionAlgorithm(const PositionAlgorit
hm<Strategy>& position, TextAffinity affinity, TextDirection primaryDirection) |
| 687 { | 697 { |
| 688 InlineBox* inlineBox = nullptr; | 698 InlineBox* inlineBox = nullptr; |
| 689 int caretOffset = computeEditingOffset(); | 699 int caretOffset = position.computeEditingOffset(); |
| 690 LayoutObject* layoutObject = m_anchorNode->isShadowRoot() ? toShadowRoot(m_a
nchorNode)->host()->layoutObject() : m_anchorNode->layoutObject(); | 700 Node* const anchorNode = position.anchorNode(); |
| 701 LayoutObject* layoutObject = anchorNode->isShadowRoot() ? toShadowRoot(ancho
rNode)->host()->layoutObject() : anchorNode->layoutObject(); |
| 691 | 702 |
| 692 if (!layoutObject->isText()) { | 703 if (!layoutObject->isText()) { |
| 693 inlineBox = 0; | 704 inlineBox = 0; |
| 694 if (canHaveChildrenForEditing(anchorNode()) && layoutObject->isLayoutBlo
ckFlow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { | 705 if (canHaveChildrenForEditing(anchorNode) && layoutObject->isLayoutBlock
Flow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { |
| 695 // Try a visually equivalent position with possibly opposite | 706 // Try a visually equivalent position with possibly opposite |
| 696 // editability. This helps in case |this| is in an editable block | 707 // editability. This helps in case |this| is in an editable block |
| 697 // but surrounded by non-editable positions. It acts to negate the | 708 // but surrounded by non-editable positions. It acts to negate the |
| 698 // logic at the beginning of LayoutObject::createVisiblePosition(). | 709 // logic at the beginning of LayoutObject::createVisiblePosition(). |
| 699 PositionAlgorithm<Strategy> thisPosition = PositionAlgorithm<Strateg
y>(*this); | 710 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo
undaries(position); |
| 700 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo
undaries(thisPosition); | 711 if (equivalent == position) { |
| 701 if (equivalent == thisPosition) { | 712 equivalent = upstreamIgnoringEditingBoundaries(position); |
| 702 equivalent = upstreamIgnoringEditingBoundaries(thisPosition); | 713 if (equivalent == position || downstreamIgnoringEditingBoundarie
s(equivalent) == position) |
| 703 if (equivalent == thisPosition || downstreamIgnoringEditingBound
aries(equivalent) == thisPosition) | |
| 704 return InlineBoxPosition(inlineBox, caretOffset); | 714 return InlineBoxPosition(inlineBox, caretOffset); |
| 705 } | 715 } |
| 706 | 716 |
| 707 return equivalent.computeInlineBoxPosition(TextAffinity::Upstream, p
rimaryDirection); | 717 return computeInlineBoxPosition(equivalent, TextAffinity::Upstream,
primaryDirection); |
| 708 } | 718 } |
| 709 if (layoutObject->isBox()) { | 719 if (layoutObject->isBox()) { |
| 710 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper(); | 720 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper(); |
| 711 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care
tOffset < inlineBox->caretMaxOffset())) | 721 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care
tOffset < inlineBox->caretMaxOffset())) |
| 712 return InlineBoxPosition(inlineBox, caretOffset); | 722 return InlineBoxPosition(inlineBox, caretOffset); |
| 713 } | 723 } |
| 714 } else { | 724 } else { |
| 715 LayoutText* textLayoutObject = toLayoutText(layoutObject); | 725 LayoutText* textLayoutObject = toLayoutText(layoutObject); |
| 716 | 726 |
| 717 InlineTextBox* box; | 727 InlineTextBox* box; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 | 851 |
| 842 // Left edge of a "tertiary" run. Set to the right edge of that run. | 852 // Left edge of a "tertiary" run. Set to the right edge of that run. |
| 843 while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak())
{ | 853 while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak())
{ |
| 844 if (tertiaryBox->bidiLevel() <= level) | 854 if (tertiaryBox->bidiLevel() <= level) |
| 845 break; | 855 break; |
| 846 inlineBox = tertiaryBox; | 856 inlineBox = tertiaryBox; |
| 847 } | 857 } |
| 848 return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset()); | 858 return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset()); |
| 849 } | 859 } |
| 850 | 860 |
| 861 InlineBoxPosition computeInlineBoxPosition(const Position& position, TextAffinit
y affinity, TextDirection primaryDirection) |
| 862 { |
| 863 return computeInlineBoxPositionAlgorithm<EditingStrategy>(position, affinity
, primaryDirection); |
| 864 } |
| 865 |
| 866 InlineBoxPosition computeInlineBoxPosition(const PositionInComposedTree& positio
n, TextAffinity affinity, TextDirection primaryDirection) |
| 867 { |
| 868 return computeInlineBoxPositionAlgorithm<EditingInComposedTreeStrategy>(posi
tion, affinity, primaryDirection); |
| 869 } |
| 870 |
| 851 template <typename Strategy> | 871 template <typename Strategy> |
| 852 void PositionAlgorithm<Strategy>::debugPosition(const char* msg) const | 872 void PositionAlgorithm<Strategy>::debugPosition(const char* msg) const |
| 853 { | 873 { |
| 854 static const char* const anchorTypes[] = { | 874 static const char* const anchorTypes[] = { |
| 855 "OffsetInAnchor", | 875 "OffsetInAnchor", |
| 856 "BeforeAnchor", | 876 "BeforeAnchor", |
| 857 "AfterAnchor", | 877 "AfterAnchor", |
| 858 "BeforeChildren", | 878 "BeforeChildren", |
| 859 "AfterChildren", | 879 "AfterChildren", |
| 860 "Invalid", | 880 "Invalid", |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 | 1044 |
| 1025 void showTree(const blink::Position* pos) | 1045 void showTree(const blink::Position* pos) |
| 1026 { | 1046 { |
| 1027 if (pos) | 1047 if (pos) |
| 1028 pos->showTreeForThis(); | 1048 pos->showTreeForThis(); |
| 1029 else | 1049 else |
| 1030 fprintf(stderr, "Cannot showTree for (nil)\n"); | 1050 fprintf(stderr, "Cannot showTree for (nil)\n"); |
| 1031 } | 1051 } |
| 1032 | 1052 |
| 1033 #endif | 1053 #endif |
| OLD | NEW |