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