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 * | 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 24 matching lines...) Expand all Loading... |
35 #include "core/dom/Position.h" | 35 #include "core/dom/Position.h" |
36 #include "core/dom/Text.h" | 36 #include "core/dom/Text.h" |
37 #include "core/editing/RenderedPosition.h" | 37 #include "core/editing/RenderedPosition.h" |
38 #include "core/editing/VisiblePosition.h" | 38 #include "core/editing/VisiblePosition.h" |
39 #include "core/editing/htmlediting.h" | 39 #include "core/editing/htmlediting.h" |
40 #include "core/editing/iterators/BackwardsCharacterIterator.h" | 40 #include "core/editing/iterators/BackwardsCharacterIterator.h" |
41 #include "core/editing/iterators/CharacterIterator.h" | 41 #include "core/editing/iterators/CharacterIterator.h" |
42 #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h" | 42 #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h" |
43 #include "core/editing/iterators/TextIterator.h" | 43 #include "core/editing/iterators/TextIterator.h" |
44 #include "core/html/HTMLBRElement.h" | 44 #include "core/html/HTMLBRElement.h" |
| 45 #include "core/layout/LayoutObject.h" |
45 #include "core/layout/line/InlineTextBox.h" | 46 #include "core/layout/line/InlineTextBox.h" |
46 #include "core/rendering/RenderBlockFlow.h" | 47 #include "core/rendering/RenderBlockFlow.h" |
47 #include "core/rendering/RenderObject.h" | |
48 #include "platform/RuntimeEnabledFeatures.h" | 48 #include "platform/RuntimeEnabledFeatures.h" |
49 #include "platform/heap/Handle.h" | 49 #include "platform/heap/Handle.h" |
50 #include "platform/text/TextBoundaries.h" | 50 #include "platform/text/TextBoundaries.h" |
51 | 51 |
52 namespace blink { | 52 namespace blink { |
53 | 53 |
54 using namespace HTMLNames; | 54 using namespace HTMLNames; |
55 using namespace WTF::Unicode; | 55 using namespace WTF::Unicode; |
56 | 56 |
57 static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
pe) | 57 static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
pe) |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
lineDirectionPoint, EditableType editableType) | 917 VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
lineDirectionPoint, EditableType editableType) |
918 { | 918 { |
919 Position p = visiblePosition.deepEquivalent(); | 919 Position p = visiblePosition.deepEquivalent(); |
920 Node* node = p.deprecatedNode(); | 920 Node* node = p.deprecatedNode(); |
921 | 921 |
922 if (!node) | 922 if (!node) |
923 return VisiblePosition(); | 923 return VisiblePosition(); |
924 | 924 |
925 node->document().updateLayoutIgnorePendingStylesheets(); | 925 node->document().updateLayoutIgnorePendingStylesheets(); |
926 | 926 |
927 RenderObject* renderer = node->renderer(); | 927 LayoutObject* renderer = node->renderer(); |
928 if (!renderer) | 928 if (!renderer) |
929 return VisiblePosition(); | 929 return VisiblePosition(); |
930 | 930 |
931 RootInlineBox* root = 0; | 931 RootInlineBox* root = 0; |
932 InlineBox* box; | 932 InlineBox* box; |
933 int ignoredCaretOffset; | 933 int ignoredCaretOffset; |
934 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); | 934 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); |
935 if (box) { | 935 if (box) { |
936 root = box->root().prevRootBox(); | 936 root = box->root().prevRootBox(); |
937 // We want to skip zero height boxes. | 937 // We want to skip zero height boxes. |
938 // This could happen in case it is a TrailingFloatsRootInlineBox. | 938 // This could happen in case it is a TrailingFloatsRootInlineBox. |
939 if (!root || !root->logicalHeight() || !root->firstLeafChild()) | 939 if (!root || !root->logicalHeight() || !root->firstLeafChild()) |
940 root = 0; | 940 root = 0; |
941 } | 941 } |
942 | 942 |
943 if (!root) { | 943 if (!root) { |
944 Position position = previousRootInlineBoxCandidatePosition(node, visible
Position, editableType); | 944 Position position = previousRootInlineBoxCandidatePosition(node, visible
Position, editableType); |
945 if (position.isNotNull()) { | 945 if (position.isNotNull()) { |
946 RenderedPosition renderedPosition((VisiblePosition(position))); | 946 RenderedPosition renderedPosition((VisiblePosition(position))); |
947 root = renderedPosition.rootBox(); | 947 root = renderedPosition.rootBox(); |
948 if (!root) | 948 if (!root) |
949 return VisiblePosition(position); | 949 return VisiblePosition(position); |
950 } | 950 } |
951 } | 951 } |
952 | 952 |
953 if (root) { | 953 if (root) { |
954 // FIXME: Can be wrong for multi-column layout and with transforms. | 954 // FIXME: Can be wrong for multi-column layout and with transforms. |
955 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); | 955 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); |
956 RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 956 LayoutObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); |
957 Node* node = renderer.node(); | 957 Node* node = renderer.node(); |
958 if (node && editingIgnoresContent(node)) | 958 if (node && editingIgnoresContent(node)) |
959 return VisiblePosition(positionInParentBeforeNode(*node)); | 959 return VisiblePosition(positionInParentBeforeNode(*node)); |
960 return VisiblePosition(renderer.positionForPoint(pointInLine)); | 960 return VisiblePosition(renderer.positionForPoint(pointInLine)); |
961 } | 961 } |
962 | 962 |
963 // Could not find a previous line. This means we must already be on the firs
t line. | 963 // Could not find a previous line. This means we must already be on the firs
t line. |
964 // Move to the start of the content in this block, which effectively moves u
s | 964 // Move to the start of the content in this block, which effectively moves u
s |
965 // to the start of the line we're on. | 965 // to the start of the line we're on. |
966 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); | 966 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); |
967 if (!rootElement) | 967 if (!rootElement) |
968 return VisiblePosition(); | 968 return VisiblePosition(); |
969 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); | 969 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); |
970 } | 970 } |
971 | 971 |
972 VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
eDirectionPoint, EditableType editableType) | 972 VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
eDirectionPoint, EditableType editableType) |
973 { | 973 { |
974 Position p = visiblePosition.deepEquivalent(); | 974 Position p = visiblePosition.deepEquivalent(); |
975 Node* node = p.deprecatedNode(); | 975 Node* node = p.deprecatedNode(); |
976 | 976 |
977 if (!node) | 977 if (!node) |
978 return VisiblePosition(); | 978 return VisiblePosition(); |
979 | 979 |
980 node->document().updateLayoutIgnorePendingStylesheets(); | 980 node->document().updateLayoutIgnorePendingStylesheets(); |
981 | 981 |
982 RenderObject* renderer = node->renderer(); | 982 LayoutObject* renderer = node->renderer(); |
983 if (!renderer) | 983 if (!renderer) |
984 return VisiblePosition(); | 984 return VisiblePosition(); |
985 | 985 |
986 RootInlineBox* root = 0; | 986 RootInlineBox* root = 0; |
987 InlineBox* box; | 987 InlineBox* box; |
988 int ignoredCaretOffset; | 988 int ignoredCaretOffset; |
989 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); | 989 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); |
990 if (box) { | 990 if (box) { |
991 root = box->root().nextRootBox(); | 991 root = box->root().nextRootBox(); |
992 // We want to skip zero height boxes. | 992 // We want to skip zero height boxes. |
(...skipping 11 matching lines...) Expand all Loading... |
1004 RenderedPosition renderedPosition((VisiblePosition(position))); | 1004 RenderedPosition renderedPosition((VisiblePosition(position))); |
1005 root = renderedPosition.rootBox(); | 1005 root = renderedPosition.rootBox(); |
1006 if (!root) | 1006 if (!root) |
1007 return VisiblePosition(position); | 1007 return VisiblePosition(position); |
1008 } | 1008 } |
1009 } | 1009 } |
1010 | 1010 |
1011 if (root) { | 1011 if (root) { |
1012 // FIXME: Can be wrong for multi-column layout and with transforms. | 1012 // FIXME: Can be wrong for multi-column layout and with transforms. |
1013 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); | 1013 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); |
1014 RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 1014 LayoutObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); |
1015 Node* node = renderer.node(); | 1015 Node* node = renderer.node(); |
1016 if (node && editingIgnoresContent(node)) | 1016 if (node && editingIgnoresContent(node)) |
1017 return VisiblePosition(positionInParentBeforeNode(*node)); | 1017 return VisiblePosition(positionInParentBeforeNode(*node)); |
1018 return VisiblePosition(renderer.positionForPoint(pointInLine)); | 1018 return VisiblePosition(renderer.positionForPoint(pointInLine)); |
1019 } | 1019 } |
1020 | 1020 |
1021 // Could not find a next line. This means we must already be on the last lin
e. | 1021 // Could not find a next line. This means we must already be on the last lin
e. |
1022 // Move to the end of the content in this block, which effectively moves us | 1022 // Move to the end of the content in this block, which effectively moves us |
1023 // to the end of the line we're on. | 1023 // to the end of the line we're on. |
1024 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); | 1024 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 bool startNodeIsEditable = startNode->hasEditableStyle(); | 1103 bool startNodeIsEditable = startNode->hasEditableStyle(); |
1104 while (n) { | 1104 while (n) { |
1105 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1105 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) |
1106 break; | 1106 break; |
1107 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1107 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1108 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1108 while (n && n->hasEditableStyle() != startNodeIsEditable) |
1109 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1109 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1110 if (!n || !n->isDescendantOf(highestRoot)) | 1110 if (!n || !n->isDescendantOf(highestRoot)) |
1111 break; | 1111 break; |
1112 } | 1112 } |
1113 RenderObject* r = n->renderer(); | 1113 LayoutObject* r = n->renderer(); |
1114 if (!r) { | 1114 if (!r) { |
1115 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1115 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1116 continue; | 1116 continue; |
1117 } | 1117 } |
1118 RenderStyle* style = r->style(); | 1118 RenderStyle* style = r->style(); |
1119 if (style->visibility() != VISIBLE) { | 1119 if (style->visibility() != VISIBLE) { |
1120 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1120 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1121 continue; | 1121 continue; |
1122 } | 1122 } |
1123 | 1123 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 while (n) { | 1182 while (n) { |
1183 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1183 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) |
1184 break; | 1184 break; |
1185 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1185 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1186 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1186 while (n && n->hasEditableStyle() != startNodeIsEditable) |
1187 n = NodeTraversal::next(*n, stayInsideBlock); | 1187 n = NodeTraversal::next(*n, stayInsideBlock); |
1188 if (!n || !n->isDescendantOf(highestRoot)) | 1188 if (!n || !n->isDescendantOf(highestRoot)) |
1189 break; | 1189 break; |
1190 } | 1190 } |
1191 | 1191 |
1192 RenderObject* r = n->renderer(); | 1192 LayoutObject* r = n->renderer(); |
1193 if (!r) { | 1193 if (!r) { |
1194 n = NodeTraversal::next(*n, stayInsideBlock); | 1194 n = NodeTraversal::next(*n, stayInsideBlock); |
1195 continue; | 1195 continue; |
1196 } | 1196 } |
1197 RenderStyle* style = r->style(); | 1197 RenderStyle* style = r->style(); |
1198 if (style->visibility() != VISIBLE) { | 1198 if (style->visibility() != VISIBLE) { |
1199 n = NodeTraversal::next(*n, stayInsideBlock); | 1199 n = NodeTraversal::next(*n, stayInsideBlock); |
1200 continue; | 1200 continue; |
1201 } | 1201 } |
1202 | 1202 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc
tion) | 1383 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc
tion) |
1384 { | 1384 { |
1385 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); | 1385 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); |
1386 } | 1386 } |
1387 | 1387 |
1388 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
ction) | 1388 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
ction) |
1389 { | 1389 { |
1390 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); | 1390 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); |
1391 } | 1391 } |
1392 | 1392 |
1393 LayoutRect localCaretRectOfPosition(const PositionWithAffinity& position, Render
Object*& renderer) | 1393 LayoutRect localCaretRectOfPosition(const PositionWithAffinity& position, Layout
Object*& renderer) |
1394 { | 1394 { |
1395 if (position.position().isNull()) { | 1395 if (position.position().isNull()) { |
1396 renderer = nullptr; | 1396 renderer = nullptr; |
1397 return IntRect(); | 1397 return IntRect(); |
1398 } | 1398 } |
1399 Node* node = position.position().anchorNode(); | 1399 Node* node = position.position().anchorNode(); |
1400 | 1400 |
1401 renderer = node->renderer(); | 1401 renderer = node->renderer(); |
1402 if (!renderer) | 1402 if (!renderer) |
1403 return LayoutRect(); | 1403 return LayoutRect(); |
1404 | 1404 |
1405 InlineBox* inlineBox; | 1405 InlineBox* inlineBox; |
1406 int caretOffset; | 1406 int caretOffset; |
1407 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); | 1407 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); |
1408 | 1408 |
1409 if (inlineBox) | 1409 if (inlineBox) |
1410 renderer = &inlineBox->renderer(); | 1410 renderer = &inlineBox->renderer(); |
1411 | 1411 |
1412 return renderer->localCaretRect(inlineBox, caretOffset); | 1412 return renderer->localCaretRect(inlineBox, caretOffset); |
1413 } | 1413 } |
1414 | 1414 |
1415 } | 1415 } |
OLD | NEW |