| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 if (editable == current->rendererIsEditable(editableType)) | 72 if (editable == current->rendererIsEditable(editableType)) |
| 73 return current; | 73 return current; |
| 74 current = current->nextLeafNode(); | 74 current = current->nextLeafNode(); |
| 75 } | 75 } |
| 76 return nullptr; | 76 return nullptr; |
| 77 } | 77 } |
| 78 | 78 |
| 79 // FIXME: consolidate with code in previousLinePosition. | 79 // FIXME: consolidate with code in previousLinePosition. |
| 80 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Position& visiblePosition, EditableType editableType) | 80 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Position& visiblePosition, EditableType editableType) |
| 81 { | 81 { |
| 82 Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), ed
itableType); | 82 Handle<Node> highestRoot = highestEditableRoot(visiblePosition.deepEquivalen
t(), editableType); |
| 83 Handle<Node> previousNode = previousLeafWithSameEditability(adoptRawResult(n
ode), editableType); | 83 Handle<Node> previousNode = previousLeafWithSameEditability(adoptRawResult(n
ode), editableType); |
| 84 | 84 |
| 85 while (previousNode && inSameLine(firstPositionInOrBeforeNode(previousNode.r
aw()), visiblePosition)) { | 85 while (true) { |
| 86 HandleScope scope; | 86 HandleScope scope; |
| 87 if (!previousNode || !inSameLine(firstPositionInOrBeforeNode(previousNod
e), visiblePosition)) |
| 88 break; |
| 87 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); | 89 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); |
| 88 } | 90 } |
| 89 | 91 |
| 90 while (previousNode && !previousNode->isShadowRoot()) { | 92 while (previousNode && !previousNode->isShadowRoot()) { |
| 91 HandleScope scope; | 93 HandleScope scope; |
| 92 if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode.raw()),
editableType) != highestRoot) | 94 if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), edita
bleType) != highestRoot) |
| 93 break; | 95 break; |
| 94 | 96 |
| 95 Position pos = previousNode->hasTagName(brTag) ? positionBeforeNode(prev
iousNode) : createLegacyEditingPosition(previousNode, caretMaxOffset(previousNod
e.raw())); | 97 Position pos = previousNode->hasTagName(brTag) ? positionBeforeNode(prev
iousNode) : createLegacyEditingPosition(previousNode, caretMaxOffset(previousNod
e)); |
| 96 | 98 |
| 97 if (pos.isCandidate()) | 99 if (pos.isCandidate()) |
| 98 return pos; | 100 return pos; |
| 99 | 101 |
| 100 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); | 102 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); |
| 101 } | 103 } |
| 102 return Position(); | 104 return Position(); |
| 103 } | 105 } |
| 104 | 106 |
| 105 static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi
tion& visiblePosition, EditableType editableType) | 107 static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi
tion& visiblePosition, EditableType editableType) |
| 106 { | 108 { |
| 107 Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), ed
itableType); | 109 Handle<Node> highestRoot = highestEditableRoot(visiblePosition.deepEquivalen
t(), editableType); |
| 108 Handle<Node> nextNode = nextLeafWithSameEditability(adoptRawResult(node), ed
itableType); | 110 Handle<Node> nextNode = nextLeafWithSameEditability(adoptRawResult(node), ed
itableType); |
| 109 while (nextNode && inSameLine(firstPositionInOrBeforeNode(nextNode.raw()), v
isiblePosition)) { | 111 while (true) { |
| 110 HandleScope scope; | 112 HandleScope scope; |
| 113 if (!nextNode || !inSameLine(firstPositionInOrBeforeNode(nextNode), visi
blePosition)) |
| 114 break; |
| 111 nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable); | 115 nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable); |
| 112 } | 116 } |
| 113 | 117 |
| 114 while (nextNode && !nextNode->isShadowRoot()) { | 118 while (nextNode && !nextNode->isShadowRoot()) { |
| 115 HandleScope scope; | 119 HandleScope scope; |
| 116 if (highestEditableRoot(firstPositionInOrBeforeNode(nextNode.raw()), edi
tableType) != highestRoot) | 120 if (highestEditableRoot(firstPositionInOrBeforeNode(nextNode), editableT
ype) != highestRoot) |
| 117 break; | 121 break; |
| 118 | 122 |
| 119 Position pos; | 123 Position pos; |
| 120 pos = createLegacyEditingPosition(nextNode, caretMinOffset(nextNode.raw(
))); | 124 pos = createLegacyEditingPosition(nextNode, caretMinOffset(nextNode)); |
| 121 | 125 |
| 122 if (pos.isCandidate()) | 126 if (pos.isCandidate()) |
| 123 return pos; | 127 return pos; |
| 124 | 128 |
| 125 nextNode = nextLeafWithSameEditability(nextNode, editableType); | 129 nextNode = nextLeafWithSameEditability(nextNode, editableType); |
| 126 } | 130 } |
| 127 return Position(); | 131 return Position(); |
| 128 } | 132 } |
| 129 | 133 |
| 130 class CachedLogicallyOrderedLeafBoxes { | 134 class CachedLogicallyOrderedLeafBoxes { |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 : positionBeforeNode(startNode); | 768 : positionBeforeNode(startNode); |
| 765 } | 769 } |
| 766 | 770 |
| 767 static VisiblePosition startOfLine(const VisiblePosition& c, LineEndpointComputa
tionMode mode) | 771 static VisiblePosition startOfLine(const VisiblePosition& c, LineEndpointComputa
tionMode mode) |
| 768 { | 772 { |
| 769 // TODO: this is the current behavior that might need to be fixed. | 773 // TODO: this is the current behavior that might need to be fixed. |
| 770 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. | 774 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. |
| 771 VisiblePosition visPos = startPositionForLine(c, mode); | 775 VisiblePosition visPos = startPositionForLine(c, mode); |
| 772 | 776 |
| 773 if (mode == UseLogicalOrdering) { | 777 if (mode == UseLogicalOrdering) { |
| 774 if (Node* editableRoot = highestEditableRoot(c.deepEquivalent())) { | 778 if (Handle<Node> editableRoot = highestEditableRoot(c.deepEquivalent()))
{ |
| 775 if (!editableRoot->contains(visPos.deepEquivalent().containerNode())
) | 779 if (!editableRoot->contains(visPos.deepEquivalent().containerNode())
) |
| 776 return firstPositionInNode(adoptRawResult(editableRoot)); | 780 return firstPositionInNode(editableRoot); |
| 777 } | 781 } |
| 778 } | 782 } |
| 779 | 783 |
| 780 return c.honorEditingBoundaryAtOrBefore(visPos); | 784 return c.honorEditingBoundaryAtOrBefore(visPos); |
| 781 } | 785 } |
| 782 | 786 |
| 783 // FIXME: Rename this function to reflect the fact it ignores bidi levels. | 787 // FIXME: Rename this function to reflect the fact it ignores bidi levels. |
| 784 VisiblePosition startOfLine(const VisiblePosition& currentPosition) | 788 VisiblePosition startOfLine(const VisiblePosition& currentPosition) |
| 785 { | 789 { |
| 786 return startOfLine(currentPosition, UseInlineBoxOrdering); | 790 return startOfLine(currentPosition, UseInlineBoxOrdering); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 | 864 |
| 861 if (mode == UseLogicalOrdering) { | 865 if (mode == UseLogicalOrdering) { |
| 862 // Make sure the end of line is at the same line as the given input posi
tion. For a wrapping line, the logical end | 866 // Make sure the end of line is at the same line as the given input posi
tion. For a wrapping line, the logical end |
| 863 // position for the not-last-2-lines might incorrectly hand back the log
ical beginning of the next line. | 867 // position for the not-last-2-lines might incorrectly hand back the log
ical beginning of the next line. |
| 864 // For example, <div contenteditable dir="rtl" style="line-break:before-
white-space">abcdefg abcdefg abcdefg | 868 // For example, <div contenteditable dir="rtl" style="line-break:before-
white-space">abcdefg abcdefg abcdefg |
| 865 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc
defg abcdefg </div> | 869 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc
defg abcdefg </div> |
| 866 // In this case, use the previous position of the computed logical end p
osition. | 870 // In this case, use the previous position of the computed logical end p
osition. |
| 867 if (!inSameLogicalLine(c, visPos)) | 871 if (!inSameLogicalLine(c, visPos)) |
| 868 visPos = visPos.previous(); | 872 visPos = visPos.previous(); |
| 869 | 873 |
| 870 if (Node* editableRoot = highestEditableRoot(c.deepEquivalent())) { | 874 if (Handle<Node> editableRoot = highestEditableRoot(c.deepEquivalent()))
{ |
| 871 if (!editableRoot->contains(visPos.deepEquivalent().containerNode())
) | 875 if (!editableRoot->contains(visPos.deepEquivalent().containerNode())
) |
| 872 return lastPositionInNode(adoptRawResult(editableRoot)); | 876 return lastPositionInNode(editableRoot); |
| 873 } | 877 } |
| 874 | 878 |
| 875 return c.honorEditingBoundaryAtOrAfter(visPos); | 879 return c.honorEditingBoundaryAtOrAfter(visPos); |
| 876 } | 880 } |
| 877 | 881 |
| 878 // Make sure the end of line is at the same line as the given input position
. Else use the previous position to | 882 // Make sure the end of line is at the same line as the given input position
. Else use the previous position to |
| 879 // obtain end of line. This condition happens when the input position is bef
ore the space character at the end | 883 // obtain end of line. This condition happens when the input position is bef
ore the space character at the end |
| 880 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine
would incorrectly hand back a position | 884 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine
would incorrectly hand back a position |
| 881 // in the next line instead. This fix is to account for the discrepancy betw
een lines with webkit-line-break:after-white-space style | 885 // in the next line instead. This fix is to account for the discrepancy betw
een lines with webkit-line-break:after-white-space style |
| 882 // versus lines without that style, which would break before a space by defa
ult. | 886 // versus lines without that style, which would break before a space by defa
ult. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 if (!root) | 968 if (!root) |
| 965 return position; | 969 return position; |
| 966 } | 970 } |
| 967 } | 971 } |
| 968 | 972 |
| 969 if (root) { | 973 if (root) { |
| 970 // FIXME: Can be wrong for multi-column layout and with transforms. | 974 // FIXME: Can be wrong for multi-column layout and with transforms. |
| 971 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); | 975 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); |
| 972 RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 976 RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); |
| 973 Handle<Node> node = renderer->node(); | 977 Handle<Node> node = renderer->node(); |
| 974 if (node && editingIgnoresContent(node.raw())) | 978 if (node && editingIgnoresContent(node)) |
| 975 return positionInParentBeforeNode(node); | 979 return positionInParentBeforeNode(node); |
| 976 return renderer->positionForPoint(pointInLine); | 980 return renderer->positionForPoint(pointInLine); |
| 977 } | 981 } |
| 978 | 982 |
| 979 // Could not find a previous line. This means we must already be on the firs
t line. | 983 // Could not find a previous line. This means we must already be on the firs
t line. |
| 980 // Move to the start of the content in this block, which effectively moves u
s | 984 // Move to the start of the content in this block, which effectively moves u
s |
| 981 // to the start of the line we're on. | 985 // to the start of the line we're on. |
| 982 Handle<Element> rootElement = node->rendererIsEditable(editableType) ? node-
>rootEditableElement(editableType) : node->document()->documentElement(); | 986 Handle<Element> rootElement = node->rendererIsEditable(editableType) ? node-
>rootEditableElement(editableType) : node->document()->documentElement(); |
| 983 if (!rootElement) | 987 if (!rootElement) |
| 984 return VisiblePosition(); | 988 return VisiblePosition(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 if (!root) | 1026 if (!root) |
| 1023 return position; | 1027 return position; |
| 1024 } | 1028 } |
| 1025 } | 1029 } |
| 1026 | 1030 |
| 1027 if (root) { | 1031 if (root) { |
| 1028 // FIXME: Can be wrong for multi-column layout and with transforms. | 1032 // FIXME: Can be wrong for multi-column layout and with transforms. |
| 1029 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); | 1033 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); |
| 1030 RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 1034 RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); |
| 1031 Handle<Node> node = renderer->node(); | 1035 Handle<Node> node = renderer->node(); |
| 1032 if (node && editingIgnoresContent(node.raw())) | 1036 if (node && editingIgnoresContent(node)) |
| 1033 return positionInParentBeforeNode(node); | 1037 return positionInParentBeforeNode(node); |
| 1034 return renderer->positionForPoint(pointInLine); | 1038 return renderer->positionForPoint(pointInLine); |
| 1035 } | 1039 } |
| 1036 | 1040 |
| 1037 // Could not find a next line. This means we must already be on the last lin
e. | 1041 // Could not find a next line. This means we must already be on the last lin
e. |
| 1038 // Move to the end of the content in this block, which effectively moves us | 1042 // Move to the end of the content in this block, which effectively moves us |
| 1039 // to the end of the line we're on. | 1043 // to the end of the line we're on. |
| 1040 Handle<Element> rootElement = node->rendererIsEditable(editableType) ? node-
>rootEditableElement(editableType) : node->document()->documentElement(); | 1044 Handle<Element> rootElement = node->rendererIsEditable(editableType) ? node-
>rootEditableElement(editableType) : node->document()->documentElement(); |
| 1041 if (!rootElement) | 1045 if (!rootElement) |
| 1042 return VisiblePosition(); | 1046 return VisiblePosition(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 } | 1102 } |
| 1099 | 1103 |
| 1100 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi
ngRule boundaryCrossingRule) | 1104 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi
ngRule boundaryCrossingRule) |
| 1101 { | 1105 { |
| 1102 Position p = c.deepEquivalent(); | 1106 Position p = c.deepEquivalent(); |
| 1103 Handle<Node> startNode = p.deprecatedNode(); | 1107 Handle<Node> startNode = p.deprecatedNode(); |
| 1104 | 1108 |
| 1105 if (!startNode) | 1109 if (!startNode) |
| 1106 return VisiblePosition(); | 1110 return VisiblePosition(); |
| 1107 | 1111 |
| 1108 if (isRenderedAsNonInlineTableImageOrHR(startNode.raw())) | 1112 if (isRenderedAsNonInlineTableImageOrHR(startNode)) |
| 1109 return positionBeforeNode(startNode); | 1113 return positionBeforeNode(startNode); |
| 1110 | 1114 |
| 1111 Handle<Node> startBlock = enclosingBlock(startNode.raw()); | 1115 Handle<Node> startBlock = enclosingBlock(startNode); |
| 1112 | 1116 |
| 1113 Handle<Node> node = startNode; | 1117 Handle<Node> node = startNode; |
| 1114 Node* highestRoot = highestEditableRoot(p); | 1118 Handle<Node> highestRoot = highestEditableRoot(p); |
| 1115 int offset = p.deprecatedEditingOffset(); | 1119 int offset = p.deprecatedEditingOffset(); |
| 1116 Position::AnchorType type = p.anchorType(); | 1120 Position::AnchorType type = p.anchorType(); |
| 1117 | 1121 |
| 1118 Handle<Node> n = startNode; | 1122 Handle<Node> n = startNode; |
| 1119 while (n) { | 1123 while (n) { |
| 1120 #if ENABLE(USERSELECT_ALL) | 1124 #if ENABLE(USERSELECT_ALL) |
| 1121 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->rendererIsEditable() != startNode->rendererIsEditable(
)) | 1125 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->rendererIsEditable() != startNode->rendererIsEditable(
)) |
| 1122 #else | 1126 #else |
| 1123 if (boundaryCrossingRule == CannotCrossEditingBoundary && n->rendererIsE
ditable() != startNode->rendererIsEditable()) | 1127 if (boundaryCrossingRule == CannotCrossEditingBoundary && n->rendererIsE
ditable() != startNode->rendererIsEditable()) |
| 1124 #endif | 1128 #endif |
| 1125 break; | 1129 break; |
| 1126 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1130 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
| 1127 while (n && n->rendererIsEditable() != startNode->rendererIsEditable
()) | 1131 while (n && n->rendererIsEditable() != startNode->rendererIsEditable
()) |
| 1128 n = NodeTraversal::previousPostOrder(n, startBlock); | 1132 n = NodeTraversal::previousPostOrder(n, startBlock); |
| 1129 if (!n || !n->isDescendantOf(highestRoot)) | 1133 if (!n || !n->isDescendantOf(highestRoot.raw())) |
| 1130 break; | 1134 break; |
| 1131 } | 1135 } |
| 1132 RenderObject* r = n->renderer(); | 1136 RenderObject* r = n->renderer(); |
| 1133 if (!r) { | 1137 if (!r) { |
| 1134 n = NodeTraversal::previousPostOrder(n, startBlock); | 1138 n = NodeTraversal::previousPostOrder(n, startBlock); |
| 1135 continue; | 1139 continue; |
| 1136 } | 1140 } |
| 1137 RenderStyle* style = r->style(); | 1141 RenderStyle* style = r->style(); |
| 1138 if (style->visibility() != VISIBLE) { | 1142 if (style->visibility() != VISIBLE) { |
| 1139 n = NodeTraversal::previousPostOrder(n, startBlock); | 1143 n = NodeTraversal::previousPostOrder(n, startBlock); |
| 1140 continue; | 1144 continue; |
| 1141 } | 1145 } |
| 1142 | 1146 |
| 1143 if (r->isBR() || isBlock(n.raw())) | 1147 if (r->isBR() || isBlock(n)) |
| 1144 break; | 1148 break; |
| 1145 | 1149 |
| 1146 if (r->isText() && toRenderText(r)->renderedTextLength()) { | 1150 if (r->isText() && toRenderText(r)->renderedTextLength()) { |
| 1147 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); | 1151 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); |
| 1148 type = Position::PositionIsOffsetInAnchor; | 1152 type = Position::PositionIsOffsetInAnchor; |
| 1149 if (style->preserveNewline()) { | 1153 if (style->preserveNewline()) { |
| 1150 const UChar* chars = toRenderText(r)->characters(); | 1154 const UChar* chars = toRenderText(r)->characters(); |
| 1151 int i = toRenderText(r)->textLength(); | 1155 int i = toRenderText(r)->textLength(); |
| 1152 int o = offset; | 1156 int o = offset; |
| 1153 if (n == startNode && o < i) | 1157 if (n == startNode && o < i) |
| 1154 i = max(0, o); | 1158 i = max(0, o); |
| 1155 while (--i >= 0) { | 1159 while (--i >= 0) { |
| 1156 if (chars[i] == '\n') | 1160 if (chars[i] == '\n') |
| 1157 return VisiblePosition(Position(toText(n.raw()), i + 1),
DOWNSTREAM); | 1161 return VisiblePosition(Position(toText(n.raw()), i + 1),
DOWNSTREAM); |
| 1158 } | 1162 } |
| 1159 } | 1163 } |
| 1160 node = n; | 1164 node = n; |
| 1161 offset = 0; | 1165 offset = 0; |
| 1162 n = NodeTraversal::previousPostOrder(n, startBlock); | 1166 n = NodeTraversal::previousPostOrder(n, startBlock); |
| 1163 } else if (editingIgnoresContent(n.raw()) || isTableElement(n.raw())) { | 1167 } else if (editingIgnoresContent(n) || isTableElement(n)) { |
| 1164 node = n; | 1168 node = n; |
| 1165 type = Position::PositionIsBeforeAnchor; | 1169 type = Position::PositionIsBeforeAnchor; |
| 1166 n = n->previousSibling() ? n->previousSibling() : NodeTraversal::pre
viousPostOrder(n, startBlock); | 1170 n = n->previousSibling() ? n->previousSibling() : NodeTraversal::pre
viousPostOrder(n, startBlock); |
| 1167 } else | 1171 } else |
| 1168 n = NodeTraversal::previousPostOrder(n, startBlock); | 1172 n = NodeTraversal::previousPostOrder(n, startBlock); |
| 1169 } | 1173 } |
| 1170 | 1174 |
| 1171 if (type == Position::PositionIsOffsetInAnchor) { | 1175 if (type == Position::PositionIsOffsetInAnchor) { |
| 1172 ASSERT(type == Position::PositionIsOffsetInAnchor || !offset); | 1176 ASSERT(type == Position::PositionIsOffsetInAnchor || !offset); |
| 1173 return VisiblePosition(Position(node, offset, type), DOWNSTREAM); | 1177 return VisiblePosition(Position(node, offset, type), DOWNSTREAM); |
| 1174 } | 1178 } |
| 1175 | 1179 |
| 1176 return VisiblePosition(Position(node, type), DOWNSTREAM); | 1180 return VisiblePosition(Position(node, type), DOWNSTREAM); |
| 1177 } | 1181 } |
| 1178 | 1182 |
| 1179 VisiblePosition endOfParagraph(const VisiblePosition &c, EditingBoundaryCrossing
Rule boundaryCrossingRule) | 1183 VisiblePosition endOfParagraph(const VisiblePosition &c, EditingBoundaryCrossing
Rule boundaryCrossingRule) |
| 1180 { | 1184 { |
| 1181 if (c.isNull()) | 1185 if (c.isNull()) |
| 1182 return VisiblePosition(); | 1186 return VisiblePosition(); |
| 1183 | 1187 |
| 1184 Position p = c.deepEquivalent(); | 1188 Position p = c.deepEquivalent(); |
| 1185 Handle<Node> startNode = p.deprecatedNode(); | 1189 Handle<Node> startNode = p.deprecatedNode(); |
| 1186 | 1190 |
| 1187 if (isRenderedAsNonInlineTableImageOrHR(startNode.raw())) | 1191 if (isRenderedAsNonInlineTableImageOrHR(startNode)) |
| 1188 return positionAfterNode(startNode); | 1192 return positionAfterNode(startNode); |
| 1189 | 1193 |
| 1190 Handle<Node> startBlock = enclosingBlock(startNode.raw()); | 1194 Handle<Node> startBlock = enclosingBlock(startNode); |
| 1191 Handle<Node> stayInsideBlock = startBlock; | 1195 Handle<Node> stayInsideBlock = startBlock; |
| 1192 | 1196 |
| 1193 Handle<Node> node = startNode; | 1197 Handle<Node> node = startNode; |
| 1194 Handle<Node> highestRoot = adoptRawResult(highestEditableRoot(p)); | 1198 Handle<Node> highestRoot = highestEditableRoot(p); |
| 1195 int offset = p.deprecatedEditingOffset(); | 1199 int offset = p.deprecatedEditingOffset(); |
| 1196 Position::AnchorType type = p.anchorType(); | 1200 Position::AnchorType type = p.anchorType(); |
| 1197 | 1201 |
| 1198 Handle<Node> n = startNode; | 1202 Handle<Node> n = startNode; |
| 1199 while (n) { | 1203 while (n) { |
| 1200 #if ENABLE(USERSELECT_ALL) | 1204 #if ENABLE(USERSELECT_ALL) |
| 1201 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n.raw()) && n->rendererIsEditable() != startNode->rendererIsEdi
table()) | 1205 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n.raw()) && n->rendererIsEditable() != startNode->rendererIsEdi
table()) |
| 1202 #else | 1206 #else |
| 1203 if (boundaryCrossingRule == CannotCrossEditingBoundary && n->rendererIsE
ditable() != startNode->rendererIsEditable()) | 1207 if (boundaryCrossingRule == CannotCrossEditingBoundary && n->rendererIsE
ditable() != startNode->rendererIsEditable()) |
| 1204 #endif | 1208 #endif |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1216 if (!r) { | 1220 if (!r) { |
| 1217 n = NodeTraversal::next(n, stayInsideBlock); | 1221 n = NodeTraversal::next(n, stayInsideBlock); |
| 1218 continue; | 1222 continue; |
| 1219 } | 1223 } |
| 1220 RenderStyle* style = r->style(); | 1224 RenderStyle* style = r->style(); |
| 1221 if (style->visibility() != VISIBLE) { | 1225 if (style->visibility() != VISIBLE) { |
| 1222 n = NodeTraversal::next(n, stayInsideBlock); | 1226 n = NodeTraversal::next(n, stayInsideBlock); |
| 1223 continue; | 1227 continue; |
| 1224 } | 1228 } |
| 1225 | 1229 |
| 1226 if (r->isBR() || isBlock(n.raw())) | 1230 if (r->isBR() || isBlock(n)) |
| 1227 break; | 1231 break; |
| 1228 | 1232 |
| 1229 // FIXME: We avoid returning a position where the renderer can't accept
the caret. | 1233 // FIXME: We avoid returning a position where the renderer can't accept
the caret. |
| 1230 if (r->isText() && toRenderText(r)->renderedTextLength()) { | 1234 if (r->isText() && toRenderText(r)->renderedTextLength()) { |
| 1231 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); | 1235 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); |
| 1232 int length = toRenderText(r)->textLength(); | 1236 int length = toRenderText(r)->textLength(); |
| 1233 type = Position::PositionIsOffsetInAnchor; | 1237 type = Position::PositionIsOffsetInAnchor; |
| 1234 if (style->preserveNewline()) { | 1238 if (style->preserveNewline()) { |
| 1235 const UChar* chars = toRenderText(r)->characters(); | 1239 const UChar* chars = toRenderText(r)->characters(); |
| 1236 int o = n == startNode ? offset : 0; | 1240 int o = n == startNode ? offset : 0; |
| 1237 for (int i = o; i < length; ++i) { | 1241 for (int i = o; i < length; ++i) { |
| 1238 if (chars[i] == '\n') | 1242 if (chars[i] == '\n') |
| 1239 return VisiblePosition(Position(toText(n.raw()), i), DOW
NSTREAM); | 1243 return VisiblePosition(Position(toText(n.raw()), i), DOW
NSTREAM); |
| 1240 } | 1244 } |
| 1241 } | 1245 } |
| 1242 node = n; | 1246 node = n; |
| 1243 offset = r->caretMaxOffset(); | 1247 offset = r->caretMaxOffset(); |
| 1244 n = NodeTraversal::next(n, stayInsideBlock); | 1248 n = NodeTraversal::next(n, stayInsideBlock); |
| 1245 } else if (editingIgnoresContent(n.raw()) || isTableElement(n.raw())) { | 1249 } else if (editingIgnoresContent(n) || isTableElement(n)) { |
| 1246 node = n; | 1250 node = n; |
| 1247 type = Position::PositionIsAfterAnchor; | 1251 type = Position::PositionIsAfterAnchor; |
| 1248 n = NodeTraversal::nextSkippingChildren(n, stayInsideBlock); | 1252 n = NodeTraversal::nextSkippingChildren(n, stayInsideBlock); |
| 1249 } else | 1253 } else |
| 1250 n = NodeTraversal::next(n, stayInsideBlock); | 1254 n = NodeTraversal::next(n, stayInsideBlock); |
| 1251 } | 1255 } |
| 1252 | 1256 |
| 1253 if (type == Position::PositionIsOffsetInAnchor) | 1257 if (type == Position::PositionIsOffsetInAnchor) |
| 1254 return VisiblePosition(Position(node, offset, type), DOWNSTREAM); | 1258 return VisiblePosition(Position(node, offset, type), DOWNSTREAM); |
| 1255 | 1259 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 } while (inSameParagraph(p, pos)); | 1310 } while (inSameParagraph(p, pos)); |
| 1307 return pos; | 1311 return pos; |
| 1308 } | 1312 } |
| 1309 | 1313 |
| 1310 // --------- | 1314 // --------- |
| 1311 | 1315 |
| 1312 VisiblePosition startOfBlock(const VisiblePosition& visiblePosition, EditingBoun
daryCrossingRule rule) | 1316 VisiblePosition startOfBlock(const VisiblePosition& visiblePosition, EditingBoun
daryCrossingRule rule) |
| 1313 { | 1317 { |
| 1314 Position position = visiblePosition.deepEquivalent(); | 1318 Position position = visiblePosition.deepEquivalent(); |
| 1315 Handle<Node> startBlock; | 1319 Handle<Node> startBlock; |
| 1316 if (!position.containerNode() || !(startBlock = enclosingBlock(position.cont
ainerNode().handle().raw(), rule))) | 1320 if (!position.containerNode() || !(startBlock = enclosingBlock(position.cont
ainerNode(), rule))) |
| 1317 return VisiblePosition(); | 1321 return VisiblePosition(); |
| 1318 return firstPositionInNode(startBlock); | 1322 return firstPositionInNode(startBlock); |
| 1319 } | 1323 } |
| 1320 | 1324 |
| 1321 VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBounda
ryCrossingRule rule) | 1325 VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBounda
ryCrossingRule rule) |
| 1322 { | 1326 { |
| 1323 Position position = visiblePosition.deepEquivalent(); | 1327 Position position = visiblePosition.deepEquivalent(); |
| 1324 Handle<Node> endBlock; | 1328 Handle<Node> endBlock; |
| 1325 if (!position.containerNode() || !(endBlock = enclosingBlock(position.contai
nerNode().handle().raw(), rule))) | 1329 if (!position.containerNode() || !(endBlock = enclosingBlock(position.contai
nerNode(), rule))) |
| 1326 return VisiblePosition(); | 1330 return VisiblePosition(); |
| 1327 return lastPositionInNode(endBlock); | 1331 return lastPositionInNode(endBlock); |
| 1328 } | 1332 } |
| 1329 | 1333 |
| 1330 bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b) | 1334 bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b) |
| 1331 { | 1335 { |
| 1332 return !a.isNull() && enclosingBlock(a.deepEquivalent().containerNode().hand
le().raw()) == enclosingBlock(b.deepEquivalent().containerNode().handle().raw())
; | 1336 return !a.isNull() && enclosingBlock(a.deepEquivalent().containerNode()) ==
enclosingBlock(b.deepEquivalent().containerNode()); |
| 1333 } | 1337 } |
| 1334 | 1338 |
| 1335 bool isStartOfBlock(const VisiblePosition &pos) | 1339 bool isStartOfBlock(const VisiblePosition &pos) |
| 1336 { | 1340 { |
| 1337 return pos.isNotNull() && pos == startOfBlock(pos, CanCrossEditingBoundary); | 1341 return pos.isNotNull() && pos == startOfBlock(pos, CanCrossEditingBoundary); |
| 1338 } | 1342 } |
| 1339 | 1343 |
| 1340 bool isEndOfBlock(const VisiblePosition &pos) | 1344 bool isEndOfBlock(const VisiblePosition &pos) |
| 1341 { | 1345 { |
| 1342 return pos.isNotNull() && pos == endOfBlock(pos, CanCrossEditingBoundary); | 1346 return pos.isNotNull() && pos == endOfBlock(pos, CanCrossEditingBoundary); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 | 1396 |
| 1393 bool isEndOfDocument(const VisiblePosition &p) | 1397 bool isEndOfDocument(const VisiblePosition &p) |
| 1394 { | 1398 { |
| 1395 return p.isNotNull() && p.next(CanCrossEditingBoundary).isNull(); | 1399 return p.isNotNull() && p.next(CanCrossEditingBoundary).isNull(); |
| 1396 } | 1400 } |
| 1397 | 1401 |
| 1398 // --------- | 1402 // --------- |
| 1399 | 1403 |
| 1400 VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition) | 1404 VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition) |
| 1401 { | 1405 { |
| 1402 Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent()); | 1406 Handle<Node> highestRoot = highestEditableRoot(visiblePosition.deepEquivalen
t()); |
| 1403 if (!highestRoot) | 1407 if (!highestRoot) |
| 1404 return VisiblePosition(); | 1408 return VisiblePosition(); |
| 1405 | 1409 |
| 1406 return firstPositionInNode(adoptRawResult(highestRoot)); | 1410 return firstPositionInNode(highestRoot); |
| 1407 } | 1411 } |
| 1408 | 1412 |
| 1409 VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition) | 1413 VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition) |
| 1410 { | 1414 { |
| 1411 Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent()); | 1415 Handle<Node> highestRoot = highestEditableRoot(visiblePosition.deepEquivalen
t()); |
| 1412 if (!highestRoot) | 1416 if (!highestRoot) |
| 1413 return VisiblePosition(); | 1417 return VisiblePosition(); |
| 1414 | 1418 |
| 1415 return lastPositionInNode(adoptRawResult(highestRoot)); | 1419 return lastPositionInNode(highestRoot); |
| 1416 } | 1420 } |
| 1417 | 1421 |
| 1418 bool isEndOfEditableOrNonEditableContent(const VisiblePosition &p) | 1422 bool isEndOfEditableOrNonEditableContent(const VisiblePosition &p) |
| 1419 { | 1423 { |
| 1420 return p.isNotNull() && p.next().isNull(); | 1424 return p.isNotNull() && p.next().isNull(); |
| 1421 } | 1425 } |
| 1422 | 1426 |
| 1423 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc
tion) | 1427 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc
tion) |
| 1424 { | 1428 { |
| 1425 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); | 1429 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); |
| 1426 } | 1430 } |
| 1427 | 1431 |
| 1428 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
ction) | 1432 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
ction) |
| 1429 { | 1433 { |
| 1430 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); | 1434 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); |
| 1431 } | 1435 } |
| 1432 | 1436 |
| 1433 } | 1437 } |
| OLD | NEW |