| 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 |