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 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 return false; | 876 return false; |
877 | 877 |
878 if (layoutObject->isBR()) { | 878 if (layoutObject->isBR()) { |
879 // TODO(leviw) The condition should be | 879 // TODO(leviw) The condition should be |
880 // m_anchorType == PositionAnchorType::BeforeAnchor, but for now we | 880 // m_anchorType == PositionAnchorType::BeforeAnchor, but for now we |
881 // still need to support legacy positions. | 881 // still need to support legacy positions. |
882 return !m_offset && !isAfterAnchor() && !nodeIsUserSelectNone(Strategy::
parent(*anchorNode())); | 882 return !m_offset && !isAfterAnchor() && !nodeIsUserSelectNone(Strategy::
parent(*anchorNode())); |
883 } | 883 } |
884 | 884 |
885 if (layoutObject->isText()) | 885 if (layoutObject->isText()) |
886 return !nodeIsUserSelectNone(anchorNode()) && inRenderedText(); | 886 return !nodeIsUserSelectNone(anchorNode()) && inRenderedText(*this); |
887 | 887 |
888 if (layoutObject->isSVG()) { | 888 if (layoutObject->isSVG()) { |
889 // We don't consider SVG elements are contenteditable except for | 889 // We don't consider SVG elements are contenteditable except for |
890 // associated layoutObject returns isText() true, e.g. LayoutSVGInlineTe
xt. | 890 // associated layoutObject returns isText() true, e.g. LayoutSVGInlineTe
xt. |
891 return false; | 891 return false; |
892 } | 892 } |
893 | 893 |
894 if (isRenderedHTMLTableElement(anchorNode()) || Strategy::editingIgnoresCont
ent(anchorNode())) | 894 if (isRenderedHTMLTableElement(anchorNode()) || Strategy::editingIgnoresCont
ent(anchorNode())) |
895 return (atFirstEditingPositionForNode() || atLastEditingPositionForNode(
)) && !nodeIsUserSelectNone(Strategy::parent(*anchorNode())); | 895 return (atFirstEditingPositionForNode() || atLastEditingPositionForNode(
)) && !nodeIsUserSelectNone(Strategy::parent(*anchorNode())); |
896 | 896 |
897 if (isHTMLHtmlElement(*m_anchorNode)) | 897 if (isHTMLHtmlElement(*m_anchorNode)) |
898 return false; | 898 return false; |
899 | 899 |
900 if (layoutObject->isLayoutBlockFlow() || layoutObject->isFlexibleBox() || la
youtObject->isLayoutGrid()) { | 900 if (layoutObject->isLayoutBlockFlow() || layoutObject->isFlexibleBox() || la
youtObject->isLayoutGrid()) { |
901 if (toLayoutBlock(layoutObject)->logicalHeight() || isHTMLBodyElement(*m
_anchorNode)) { | 901 if (toLayoutBlock(layoutObject)->logicalHeight() || isHTMLBodyElement(*m
_anchorNode)) { |
902 if (!hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) | 902 if (!hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) |
903 return atFirstEditingPositionForNode() && !nodeIsUserSelectNone(
anchorNode()); | 903 return atFirstEditingPositionForNode() && !nodeIsUserSelectNone(
anchorNode()); |
904 return m_anchorNode->hasEditableStyle() && !nodeIsUserSelectNone(anc
horNode()) && atEditingBoundary(*this); | 904 return m_anchorNode->hasEditableStyle() && !nodeIsUserSelectNone(anc
horNode()) && atEditingBoundary(*this); |
905 } | 905 } |
906 } else { | 906 } else { |
907 LocalFrame* frame = m_anchorNode->document().frame(); | 907 LocalFrame* frame = m_anchorNode->document().frame(); |
908 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsi
ngEnabled(); | 908 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsi
ngEnabled(); |
909 return (caretBrowsing || m_anchorNode->hasEditableStyle()) && !nodeIsUse
rSelectNone(anchorNode()) && atEditingBoundary(*this); | 909 return (caretBrowsing || m_anchorNode->hasEditableStyle()) && !nodeIsUse
rSelectNone(anchorNode()) && atEditingBoundary(*this); |
910 } | 910 } |
911 | 911 |
912 return false; | 912 return false; |
913 } | 913 } |
914 | 914 |
| 915 // TODO(yosin) We should move |inRenderedText()| to "VisibleUnits.h" for |
| 916 // reduce dependency of |LayoutObject| in |Position| class. |
915 template <typename Strategy> | 917 template <typename Strategy> |
916 bool PositionAlgorithm<Strategy>::inRenderedText() const | 918 static bool inRenderedTextAlgorithm(const PositionAlgorithm<Strategy>& position) |
917 { | 919 { |
918 if (isNull() || !anchorNode()->isTextNode()) | 920 Node* const anchorNode = position.anchorNode(); |
| 921 if (!anchorNode || !anchorNode->isTextNode()) |
919 return false; | 922 return false; |
920 | 923 |
921 LayoutObject* layoutObject = anchorNode()->layoutObject(); | 924 LayoutObject* layoutObject = anchorNode->layoutObject(); |
922 if (!layoutObject) | 925 if (!layoutObject) |
923 return false; | 926 return false; |
924 | 927 |
| 928 const int offsetInNode = position.computeEditingOffset(); |
925 LayoutText* textLayoutObject = toLayoutText(layoutObject); | 929 LayoutText* textLayoutObject = toLayoutText(layoutObject); |
926 for (InlineTextBox *box = textLayoutObject->firstTextBox(); box; box = box->
nextTextBox()) { | 930 for (InlineTextBox *box = textLayoutObject->firstTextBox(); box; box = box->
nextTextBox()) { |
927 if (m_offset < static_cast<int>(box->start()) && !textLayoutObject->cont
ainsReversedText()) { | 931 if (offsetInNode < static_cast<int>(box->start()) && !textLayoutObject->
containsReversedText()) { |
928 // The offset we're looking for is before this node | 932 // The offset we're looking for is before this node |
929 // this means the offset must be in content that is | 933 // this means the offset must be in content that is |
930 // not laid out. Return false. | 934 // not laid out. Return false. |
931 return false; | 935 return false; |
932 } | 936 } |
933 if (box->containsCaretOffset(m_offset)) { | 937 if (box->containsCaretOffset(offsetInNode)) { |
934 // Return false for offsets inside composed characters. | 938 // Return false for offsets inside composed characters. |
935 return m_offset == 0 || m_offset == textLayoutObject->nextOffset(tex
tLayoutObject->previousOffset(m_offset)); | 939 return offsetInNode == 0 || offsetInNode == textLayoutObject->nextOf
fset(textLayoutObject->previousOffset(offsetInNode)); |
936 } | 940 } |
937 } | 941 } |
938 | 942 |
939 return false; | 943 return false; |
940 } | 944 } |
941 | 945 |
| 946 bool inRenderedText(const Position& position) |
| 947 { |
| 948 return inRenderedTextAlgorithm<EditingStrategy>(position); |
| 949 } |
| 950 |
| 951 bool inRenderedText(const PositionInComposedTree& position) |
| 952 { |
| 953 return inRenderedTextAlgorithm<EditingInComposedTreeStrategy>(position); |
| 954 } |
| 955 |
942 bool isRenderedCharacter(const Position& position) | 956 bool isRenderedCharacter(const Position& position) |
943 { | 957 { |
944 if (position.isNull()) | 958 if (position.isNull()) |
945 return false; | 959 return false; |
946 ASSERT(position.isOffsetInAnchor()); | 960 ASSERT(position.isOffsetInAnchor()); |
947 if (!position.anchorNode()->isTextNode()) | 961 if (!position.anchorNode()->isTextNode()) |
948 return false; | 962 return false; |
949 | 963 |
950 LayoutObject* layoutObject = position.anchorNode()->layoutObject(); | 964 LayoutObject* layoutObject = position.anchorNode()->layoutObject(); |
951 if (!layoutObject) | 965 if (!layoutObject) |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 | 1374 |
1361 void showTree(const blink::Position* pos) | 1375 void showTree(const blink::Position* pos) |
1362 { | 1376 { |
1363 if (pos) | 1377 if (pos) |
1364 pos->showTreeForThis(); | 1378 pos->showTreeForThis(); |
1365 else | 1379 else |
1366 fprintf(stderr, "Cannot showTree for (nil)\n"); | 1380 fprintf(stderr, "Cannot showTree for (nil)\n"); |
1367 } | 1381 } |
1368 | 1382 |
1369 #endif | 1383 #endif |
OLD | NEW |