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 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1022 if (!endTextBox->isLineBreak()) | 1022 if (!endTextBox->isLineBreak()) |
1023 endOffset += endTextBox->len(); | 1023 endOffset += endTextBox->len(); |
1024 pos = Position(toText(endNode), endOffset); | 1024 pos = Position(toText(endNode), endOffset); |
1025 } else { | 1025 } else { |
1026 pos = positionAfterNode(endNode); | 1026 pos = positionAfterNode(endNode); |
1027 } | 1027 } |
1028 | 1028 |
1029 return createVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); | 1029 return createVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); |
1030 } | 1030 } |
1031 | 1031 |
1032 // TODO(yosin) Rename this function to reflect the fact it ignores bidi levels. | |
1033 VisiblePosition endOfLine(const VisiblePosition& currentPosition) | |
1034 { | |
1035 // TODO(yosin) this is the current behavior that might need to be fixed. | |
1036 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. | |
1037 VisiblePosition visPos = endPositionForLine(currentPosition, UseInlineBoxOrd ering); | |
1038 | |
1039 // Make sure the end of line is at the same line as the given input | |
1040 // position. Else use the previous position to obtain end of line. This | |
1041 // condition happens when the input position is before the space character | |
1042 // at the end of a soft-wrapped non-editable line. In this scenario, | |
1043 // |endPositionForLine()| would incorrectly hand back a position in the next | |
1044 // line instead. This fix is to account for the discrepancy between lines | |
1045 // with "webkit-line-break:after-white-space" style versus lines without | |
1046 // that style, which would break before a space by default. | |
1047 if (!inSameLine(currentPosition, visPos)) { | |
1048 visPos = previousPositionOf(currentPosition); | |
1049 if (visPos.isNull()) | |
1050 return VisiblePosition(); | |
1051 visPos = endPositionForLine(visPos, UseInlineBoxOrdering); | |
1052 } | |
1053 | |
1054 return honorEditingBoundaryAtOrAfter(visPos, currentPosition.deepEquivalent( )); | |
1055 } | |
1056 | |
1032 static bool inSameLogicalLine(const VisiblePosition& a, const VisiblePosition& b ) | 1057 static bool inSameLogicalLine(const VisiblePosition& a, const VisiblePosition& b ) |
1033 { | 1058 { |
1034 return a.isNotNull() && logicalStartOfLine(a).deepEquivalent() == logicalSta rtOfLine(b).deepEquivalent(); | 1059 return a.isNotNull() && logicalStartOfLine(a).deepEquivalent() == logicalSta rtOfLine(b).deepEquivalent(); |
1035 } | 1060 } |
1036 | 1061 |
1037 static VisiblePosition endOfLine(const VisiblePosition& c, LineEndpointComputati onMode mode) | 1062 VisiblePosition logicalEndOfLine(const VisiblePosition& currentPosition) |
1038 { | 1063 { |
1039 // TODO: this is the current behavior that might need to be fixed. | 1064 // TODO(yosin) this is the current behavior that might need to be fixed. |
1040 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. | 1065 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. |
1041 VisiblePosition visPos = endPositionForLine(c, mode); | 1066 VisiblePosition visPos = endPositionForLine(currentPosition, UseLogicalOrder ing); |
1042 | 1067 |
1043 if (mode == UseLogicalOrdering) { | 1068 // Make sure the end of line is at the same line as the given input |
1044 // Make sure the end of line is at the same line as the given input posi tion. For a wrapping line, the logical end | 1069 // position. For a wrapping line, the logical end position for the |
1045 // position for the not-last-2-lines might incorrectly hand back the log ical beginning of the next line. | 1070 // not-last-2-lines might incorrectly hand back the logical beginning of the |
1046 // For example, <div contenteditable dir="rtl" style="line-break:before- white-space">abcdefg abcdefg abcdefg | 1071 // next line. For example, |
1047 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc defg abcdefg </div> | 1072 // <div contenteditable dir="rtl" style="line-break:before-white-space">xyz |
1048 // In this case, use the previous position of the computed logical end p osition. | 1073 // a xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz </div> |
hajimehoshi
2015/09/09 10:59:09
Why did you change this comment?
yosin_UTC9
2015/09/09 11:08:49
to fit into 80 chars
in previous line.
hajimehoshi
2015/09/09 11:11:26
Hm, you could keep abcdefg, but that's OK to me
| |
1049 if (!inSameLogicalLine(c, visPos)) | 1074 // In this case, use the previous position of the computed logical end |
1050 visPos = previousPositionOf(visPos); | 1075 // position. |
1076 if (!inSameLogicalLine(currentPosition, visPos)) | |
1077 visPos = previousPositionOf(visPos); | |
1051 | 1078 |
1052 if (ContainerNode* editableRoot = highestEditableRoot(c.deepEquivalent() )) { | 1079 if (ContainerNode* editableRoot = highestEditableRoot(currentPosition.deepEq uivalent())) { |
1053 if (!editableRoot->contains(visPos.deepEquivalent().computeContainer Node())) | 1080 if (!editableRoot->contains(visPos.deepEquivalent().computeContainerNode ())) |
1054 return createVisiblePosition(lastPositionInNode(editableRoot)); | 1081 return createVisiblePosition(lastPositionInNode(editableRoot)); |
1055 } | |
1056 | |
1057 return honorEditingBoundaryAtOrAfter(visPos, c.deepEquivalent()); | |
1058 } | 1082 } |
1059 | 1083 |
1060 // Make sure the end of line is at the same line as the given input position . Else use the previous position to | 1084 return honorEditingBoundaryAtOrAfter(visPos, currentPosition.deepEquivalent( )); |
1061 // obtain end of line. This condition happens when the input position is bef ore the space character at the end | |
1062 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine would incorrectly hand back a position | |
1063 // in the next line instead. This fix is to account for the discrepancy betw een lines with webkit-line-break:after-white-space style | |
1064 // versus lines without that style, which would break before a space by defa ult. | |
1065 if (!inSameLine(c, visPos)) { | |
1066 visPos = previousPositionOf(c); | |
1067 if (visPos.isNull()) | |
1068 return VisiblePosition(); | |
1069 visPos = endPositionForLine(visPos, UseInlineBoxOrdering); | |
1070 } | |
1071 | |
1072 return honorEditingBoundaryAtOrAfter(visPos, c.deepEquivalent()); | |
1073 } | |
1074 | |
1075 // FIXME: Rename this function to reflect the fact it ignores bidi levels. | |
1076 VisiblePosition endOfLine(const VisiblePosition& currentPosition) | |
1077 { | |
1078 return endOfLine(currentPosition, UseInlineBoxOrdering); | |
1079 } | |
1080 | |
1081 VisiblePosition logicalEndOfLine(const VisiblePosition& currentPosition) | |
1082 { | |
1083 return endOfLine(currentPosition, UseLogicalOrdering); | |
1084 } | 1085 } |
1085 | 1086 |
1086 template <typename Strategy> | 1087 template <typename Strategy> |
1087 bool inSameLineAlgorithm(const PositionWithAffinityTemplate<Strategy>& position1 , const PositionWithAffinityTemplate<Strategy>& position2) | 1088 bool inSameLineAlgorithm(const PositionWithAffinityTemplate<Strategy>& position1 , const PositionWithAffinityTemplate<Strategy>& position2) |
1088 { | 1089 { |
1089 if (position1.isNull() || position2.isNull()) | 1090 if (position1.isNull() || position2.isNull()) |
1090 return false; | 1091 return false; |
1091 PositionWithAffinityTemplate<Strategy> startOfLine1 = startOfLine(position1) ; | 1092 PositionWithAffinityTemplate<Strategy> startOfLine1 = startOfLine(position1) ; |
1092 PositionWithAffinityTemplate<Strategy> startOfLine2 = startOfLine(position2) ; | 1093 PositionWithAffinityTemplate<Strategy> startOfLine2 = startOfLine(position2) ; |
1093 if (startOfLine1 == startOfLine2) | 1094 if (startOfLine1 == startOfLine2) |
(...skipping 1932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3026 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale nt()); | 3027 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale nt()); |
3027 case CanSkipOverEditingBoundary: | 3028 case CanSkipOverEditingBoundary: |
3028 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent ()); | 3029 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent ()); |
3029 } | 3030 } |
3030 | 3031 |
3031 ASSERT_NOT_REACHED(); | 3032 ASSERT_NOT_REACHED(); |
3032 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent() ); | 3033 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent() ); |
3033 } | 3034 } |
3034 | 3035 |
3035 } // namespace blink | 3036 } // namespace blink |
OLD | NEW |