OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. |
3 * Copyright (C) 2005 Alexey Proskuryakov. | 3 * Copyright (C) 2005 Alexey Proskuryakov. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeFor(const ContainerNode
& scope, GetRangeFor getRangeFor) const | 70 PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeFor(const ContainerNode
& scope, GetRangeFor getRangeFor) const |
71 { | 71 { |
72 ASSERT(isNotNull()); | 72 ASSERT(isNotNull()); |
73 | 73 |
74 RefPtrWillBeRawPtr<Range> resultRange = scope.document().createRange(); | 74 RefPtrWillBeRawPtr<Range> resultRange = scope.document().createRange(); |
75 | 75 |
76 size_t docTextPosition = 0; | 76 size_t docTextPosition = 0; |
77 bool startRangeFound = false; | 77 bool startRangeFound = false; |
78 | 78 |
79 RefPtrWillBeRawPtr<Range> textRunRange = nullptr; | 79 Position textRunStartPosition; |
| 80 Position textRunEndPosition; |
80 | 81 |
81 TextIteratorBehaviorFlags behaviorFlags = TextIteratorEmitsObjectReplacement
Character; | 82 TextIteratorBehaviorFlags behaviorFlags = TextIteratorEmitsObjectReplacement
Character; |
82 if (getRangeFor == ForSelection) | 83 if (getRangeFor == ForSelection) |
83 behaviorFlags |= TextIteratorEmitsCharactersBetweenAllVisiblePositions; | 84 behaviorFlags |= TextIteratorEmitsCharactersBetweenAllVisiblePositions; |
84 TextIterator it(rangeOfContents(const_cast<ContainerNode*>(&scope)).get(), b
ehaviorFlags); | 85 TextIterator it(rangeOfContents(const_cast<ContainerNode*>(&scope)).get(), b
ehaviorFlags); |
85 | 86 |
86 // FIXME: the atEnd() check shouldn't be necessary, workaround for <http://b
ugs.webkit.org/show_bug.cgi?id=6289>. | 87 // FIXME: the atEnd() check shouldn't be necessary, workaround for <http://b
ugs.webkit.org/show_bug.cgi?id=6289>. |
87 if (!start() && !length() && it.atEnd()) { | 88 if (!start() && !length() && it.atEnd()) { |
88 resultRange->setStart(it.startContainer(), 0, ASSERT_NO_EXCEPTION); | 89 resultRange->setStart(it.startContainer(), 0, ASSERT_NO_EXCEPTION); |
89 resultRange->setEnd(it.startContainer(), 0, ASSERT_NO_EXCEPTION); | 90 resultRange->setEnd(it.startContainer(), 0, ASSERT_NO_EXCEPTION); |
90 return resultRange.release(); | 91 return resultRange.release(); |
91 } | 92 } |
92 | 93 |
93 for (; !it.atEnd(); it.advance()) { | 94 for (; !it.atEnd(); it.advance()) { |
94 int len = it.length(); | 95 int len = it.length(); |
95 textRunRange = it.range(); | 96 |
| 97 textRunStartPosition = it.startPosition(); |
| 98 textRunEndPosition = it.endPosition(); |
96 | 99 |
97 bool foundStart = start() >= docTextPosition && start() <= docTextPositi
on + len; | 100 bool foundStart = start() >= docTextPosition && start() <= docTextPositi
on + len; |
98 bool foundEnd = end() >= docTextPosition && end() <= docTextPosition + l
en; | 101 bool foundEnd = end() >= docTextPosition && end() <= docTextPosition + l
en; |
99 | 102 |
100 // Fix textRunRange->endPosition(), but only if foundStart || foundEnd,
because it is only | 103 // Fix textRunRange->endPosition(), but only if foundStart || foundEnd,
because it is only |
101 // in those cases that textRunRange is used. | 104 // in those cases that textRunRange is used. |
102 if (foundEnd) { | 105 if (foundEnd) { |
103 // FIXME: This is a workaround for the fact that the end of a run | 106 // FIXME: This is a workaround for the fact that the end of a run |
104 // is often at the wrong position for emitted '\n's or if the | 107 // is often at the wrong position for emitted '\n's or if the |
105 // renderer of the current node is a replaced element. | 108 // renderer of the current node is a replaced element. |
106 if (len == 1 && (it.characterAt(0) == '\n' || it.isInsideReplacedEle
ment())) { | 109 if (len == 1 && (it.characterAt(0) == '\n' || it.isInsideReplacedEle
ment())) { |
107 it.advance(); | 110 it.advance(); |
108 if (!it.atEnd()) { | 111 if (!it.atEnd()) { |
109 RefPtrWillBeRawPtr<Range> range = it.range(); | 112 textRunEndPosition = it.startPosition(); |
110 textRunRange->setEnd(range->startContainer(), range->startOf
fset(), ASSERT_NO_EXCEPTION); | |
111 } else { | 113 } else { |
112 Position runStart = textRunRange->startPosition(); | 114 Position runEnd = VisiblePosition(textRunStartPosition).next
().deepEquivalent(); |
113 Position runEnd = VisiblePosition(runStart).next().deepEquiv
alent(); | |
114 if (runEnd.isNotNull()) | 115 if (runEnd.isNotNull()) |
115 textRunRange->setEnd(runEnd.containerNode(), runEnd.comp
uteOffsetInContainerNode(), ASSERT_NO_EXCEPTION); | 116 textRunEndPosition = createLegacyEditingPosition(runEnd.
containerNode(), runEnd.computeOffsetInContainerNode()); |
116 } | 117 } |
117 } | 118 } |
118 } | 119 } |
119 | 120 |
120 if (foundStart) { | 121 if (foundStart) { |
121 startRangeFound = true; | 122 startRangeFound = true; |
122 if (textRunRange->startContainer()->isTextNode()) { | 123 if (textRunStartPosition.containerNode()->isTextNode()) { |
123 int offset = start() - docTextPosition; | 124 int offset = start() - docTextPosition; |
124 resultRange->setStart(textRunRange->startContainer(), offset + t
extRunRange->startOffset(), IGNORE_EXCEPTION); | 125 resultRange->setStart(textRunStartPosition.containerNode(), offs
et + textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); |
125 } else { | 126 } else { |
126 if (start() == docTextPosition) | 127 if (start() == docTextPosition) |
127 resultRange->setStart(textRunRange->startContainer(), textRu
nRange->startOffset(), IGNORE_EXCEPTION); | 128 resultRange->setStart(textRunStartPosition.containerNode(),
textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); |
128 else | 129 else |
129 resultRange->setStart(textRunRange->endContainer(), textRunR
ange->endOffset(), IGNORE_EXCEPTION); | 130 resultRange->setStart(textRunEndPosition.containerNode(), te
xtRunEndPosition.offsetInContainerNode(), IGNORE_EXCEPTION); |
130 } | 131 } |
131 } | 132 } |
132 | 133 |
133 if (foundEnd) { | 134 if (foundEnd) { |
134 if (textRunRange->startContainer()->isTextNode()) { | 135 if (textRunStartPosition.containerNode()->isTextNode()) { |
135 int offset = end() - docTextPosition; | 136 int offset = end() - docTextPosition; |
136 resultRange->setEnd(textRunRange->startContainer(), offset + tex
tRunRange->startOffset(), IGNORE_EXCEPTION); | 137 resultRange->setEnd(textRunStartPosition.containerNode(), offset
+ textRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); |
137 } else { | 138 } else { |
138 if (end() == docTextPosition) | 139 if (end() == docTextPosition) |
139 resultRange->setEnd(textRunRange->startContainer(), textRunR
ange->startOffset(), IGNORE_EXCEPTION); | 140 resultRange->setEnd(textRunStartPosition.containerNode(), te
xtRunStartPosition.offsetInContainerNode(), IGNORE_EXCEPTION); |
140 else | 141 else |
141 resultRange->setEnd(textRunRange->endContainer(), textRunRan
ge->endOffset(), IGNORE_EXCEPTION); | 142 resultRange->setEnd(textRunEndPosition.containerNode(), text
RunEndPosition.offsetInContainerNode(), IGNORE_EXCEPTION); |
142 } | 143 } |
143 docTextPosition += len; | 144 docTextPosition += len; |
144 break; | 145 break; |
145 } | 146 } |
146 docTextPosition += len; | 147 docTextPosition += len; |
147 } | 148 } |
148 | 149 |
149 if (!startRangeFound) | 150 if (!startRangeFound) |
150 return nullptr; | 151 return nullptr; |
151 | 152 |
152 if (length() && end() > docTextPosition) { // end() is out of bounds | 153 if (length() && end() > docTextPosition) { // end() is out of bounds |
153 resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffse
t(), IGNORE_EXCEPTION); | 154 resultRange->setEnd(textRunEndPosition.containerNode(), textRunEndPositi
on.offsetInContainerNode(), IGNORE_EXCEPTION); |
154 } | 155 } |
155 | 156 |
156 return resultRange.release(); | 157 return resultRange.release(); |
157 } | 158 } |
158 | 159 |
159 PlainTextRange PlainTextRange::create(const ContainerNode& scope, const Range& r
ange) | 160 PlainTextRange PlainTextRange::create(const ContainerNode& scope, const Range& r
ange) |
160 { | 161 { |
161 if (!range.startContainer()) | 162 if (!range.startContainer()) |
162 return PlainTextRange(); | 163 return PlainTextRange(); |
163 | 164 |
(...skipping 12 matching lines...) Expand all Loading... |
176 size_t start = TextIterator::rangeLength(testRange.get()); | 177 size_t start = TextIterator::rangeLength(testRange.get()); |
177 | 178 |
178 testRange->setEnd(range.endContainer(), range.endOffset(), IGNORE_EXCEPTION)
; | 179 testRange->setEnd(range.endContainer(), range.endOffset(), IGNORE_EXCEPTION)
; |
179 ASSERT(testRange->startContainer() == &scope); | 180 ASSERT(testRange->startContainer() == &scope); |
180 size_t end = TextIterator::rangeLength(testRange.get()); | 181 size_t end = TextIterator::rangeLength(testRange.get()); |
181 | 182 |
182 return PlainTextRange(start, end); | 183 return PlainTextRange(start, end); |
183 } | 184 } |
184 | 185 |
185 } | 186 } |
OLD | NEW |