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 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 | 1142 |
1143 m_lastTextNodeEndedWithCollapsedSpace = false; | 1143 m_lastTextNodeEndedWithCollapsedSpace = false; |
1144 m_hasEmitted = true; | 1144 m_hasEmitted = true; |
1145 } | 1145 } |
1146 | 1146 |
1147 void TextIterator::emitText(Node* textNode, int textStartOffset, int textEndOffs
et) | 1147 void TextIterator::emitText(Node* textNode, int textStartOffset, int textEndOffs
et) |
1148 { | 1148 { |
1149 emitText(textNode, m_node->renderer(), textStartOffset, textEndOffset); | 1149 emitText(textNode, m_node->renderer(), textStartOffset, textEndOffset); |
1150 } | 1150 } |
1151 | 1151 |
1152 PassRefPtr<Range> TextIterator::range() const | 1152 PassRefPtrWillBeRawPtr<Range> TextIterator::range() const |
1153 { | 1153 { |
1154 // use the current run information, if we have it | 1154 // use the current run information, if we have it |
1155 if (m_positionNode) { | 1155 if (m_positionNode) { |
1156 if (m_positionOffsetBaseNode) { | 1156 if (m_positionOffsetBaseNode) { |
1157 int index = m_positionOffsetBaseNode->nodeIndex(); | 1157 int index = m_positionOffsetBaseNode->nodeIndex(); |
1158 m_positionStartOffset += index; | 1158 m_positionStartOffset += index; |
1159 m_positionEndOffset += index; | 1159 m_positionEndOffset += index; |
1160 m_positionOffsetBaseNode = 0; | 1160 m_positionOffsetBaseNode = 0; |
1161 } | 1161 } |
1162 return Range::create(m_positionNode->document(), m_positionNode, m_posit
ionStartOffset, m_positionNode, m_positionEndOffset); | 1162 return Range::create(m_positionNode->document(), m_positionNode, m_posit
ionStartOffset, m_positionNode, m_positionEndOffset); |
1163 } | 1163 } |
1164 | 1164 |
1165 // otherwise, return the end of the overall range we were given | 1165 // otherwise, return the end of the overall range we were given |
1166 if (m_endContainer) | 1166 if (m_endContainer) |
1167 return Range::create(m_endContainer->document(), m_endContainer, m_endOf
fset, m_endContainer, m_endOffset); | 1167 return Range::create(m_endContainer->document(), m_endContainer, m_endOf
fset, m_endContainer, m_endOffset); |
1168 | 1168 |
1169 return nullptr; | 1169 return nullptr; |
1170 } | 1170 } |
1171 | 1171 |
1172 Node* TextIterator::node() const | 1172 Node* TextIterator::node() const |
1173 { | 1173 { |
1174 RefPtr<Range> textRange = range(); | 1174 RefPtrWillBeRawPtr<Range> textRange = range(); |
1175 if (!textRange) | 1175 if (!textRange) |
1176 return 0; | 1176 return 0; |
1177 | 1177 |
1178 Node* node = textRange->startContainer(); | 1178 Node* node = textRange->startContainer(); |
1179 if (!node) | 1179 if (!node) |
1180 return 0; | 1180 return 0; |
1181 if (node->offsetInCharacters()) | 1181 if (node->offsetInCharacters()) |
1182 return node; | 1182 return node; |
1183 | 1183 |
1184 return node->traverseToChildAt(textRange->startOffset()); | 1184 return node->traverseToChildAt(textRange->startOffset()); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 { | 1460 { |
1461 if (!next) | 1461 if (!next) |
1462 return false; | 1462 return false; |
1463 m_havePassedStartNode |= m_node == m_startNode; | 1463 m_havePassedStartNode |= m_node == m_startNode; |
1464 if (m_havePassedStartNode) | 1464 if (m_havePassedStartNode) |
1465 return false; | 1465 return false; |
1466 m_node = next; | 1466 m_node = next; |
1467 return true; | 1467 return true; |
1468 } | 1468 } |
1469 | 1469 |
1470 PassRefPtr<Range> SimplifiedBackwardsTextIterator::range() const | 1470 PassRefPtrWillBeRawPtr<Range> SimplifiedBackwardsTextIterator::range() const |
1471 { | 1471 { |
1472 if (m_positionNode) | 1472 if (m_positionNode) |
1473 return Range::create(m_positionNode->document(), m_positionNode, m_posit
ionStartOffset, m_positionNode, m_positionEndOffset); | 1473 return Range::create(m_positionNode->document(), m_positionNode, m_posit
ionStartOffset, m_positionNode, m_positionEndOffset); |
1474 | 1474 |
1475 return Range::create(m_startNode->document(), m_startNode, m_startOffset, m_
startNode, m_startOffset); | 1475 return Range::create(m_startNode->document(), m_startNode, m_startOffset, m_
startNode, m_startOffset); |
1476 } | 1476 } |
1477 | 1477 |
1478 // -------- | 1478 // -------- |
1479 | 1479 |
1480 CharacterIterator::CharacterIterator(const Range* range, TextIteratorBehaviorFla
gs behavior) | 1480 CharacterIterator::CharacterIterator(const Range* range, TextIteratorBehaviorFla
gs behavior) |
(...skipping 13 matching lines...) Expand all Loading... |
1494 { | 1494 { |
1495 initialize(); | 1495 initialize(); |
1496 } | 1496 } |
1497 | 1497 |
1498 void CharacterIterator::initialize() | 1498 void CharacterIterator::initialize() |
1499 { | 1499 { |
1500 while (!atEnd() && !m_textIterator.length()) | 1500 while (!atEnd() && !m_textIterator.length()) |
1501 m_textIterator.advance(); | 1501 m_textIterator.advance(); |
1502 } | 1502 } |
1503 | 1503 |
1504 PassRefPtr<Range> CharacterIterator::range() const | 1504 PassRefPtrWillBeRawPtr<Range> CharacterIterator::range() const |
1505 { | 1505 { |
1506 RefPtr<Range> r = m_textIterator.range(); | 1506 RefPtrWillBeRawPtr<Range> r = m_textIterator.range(); |
1507 if (!m_textIterator.atEnd()) { | 1507 if (!m_textIterator.atEnd()) { |
1508 if (m_textIterator.length() <= 1) { | 1508 if (m_textIterator.length() <= 1) { |
1509 ASSERT(!m_runOffset); | 1509 ASSERT(!m_runOffset); |
1510 } else { | 1510 } else { |
1511 Node* n = r->startContainer(); | 1511 Node* n = r->startContainer(); |
1512 ASSERT(n == r->endContainer()); | 1512 ASSERT(n == r->endContainer()); |
1513 int offset = r->startOffset() + m_runOffset; | 1513 int offset = r->startOffset() + m_runOffset; |
1514 r->setStart(n, offset, ASSERT_NO_EXCEPTION); | 1514 r->setStart(n, offset, ASSERT_NO_EXCEPTION); |
1515 r->setEnd(n, offset + 1, ASSERT_NO_EXCEPTION); | 1515 r->setEnd(n, offset + 1, ASSERT_NO_EXCEPTION); |
1516 } | 1516 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 count -= runLength; | 1556 count -= runLength; |
1557 m_offset += runLength; | 1557 m_offset += runLength; |
1558 } | 1558 } |
1559 } | 1559 } |
1560 | 1560 |
1561 // ran to the end of the m_textIterator... no more runs left | 1561 // ran to the end of the m_textIterator... no more runs left |
1562 m_atBreak = true; | 1562 m_atBreak = true; |
1563 m_runOffset = 0; | 1563 m_runOffset = 0; |
1564 } | 1564 } |
1565 | 1565 |
1566 static PassRefPtr<Range> characterSubrange(CharacterIterator& it, int offset, in
t length) | 1566 static PassRefPtrWillBeRawPtr<Range> characterSubrange(CharacterIterator& it, in
t offset, int length) |
1567 { | 1567 { |
1568 it.advance(offset); | 1568 it.advance(offset); |
1569 RefPtr<Range> start = it.range(); | 1569 RefPtrWillBeRawPtr<Range> start = it.range(); |
1570 | 1570 |
1571 if (length > 1) | 1571 if (length > 1) |
1572 it.advance(length - 1); | 1572 it.advance(length - 1); |
1573 RefPtr<Range> end = it.range(); | 1573 RefPtrWillBeRawPtr<Range> end = it.range(); |
1574 | 1574 |
1575 return Range::create(start->startContainer()->document(), | 1575 return Range::create(start->startContainer()->document(), |
1576 start->startContainer(), start->startOffset(), | 1576 start->startContainer(), start->startOffset(), |
1577 end->endContainer(), end->endOffset()); | 1577 end->endContainer(), end->endOffset()); |
1578 } | 1578 } |
1579 | 1579 |
1580 BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextI
teratorBehaviorFlags behavior) | 1580 BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextI
teratorBehaviorFlags behavior) |
1581 : m_offset(0) | 1581 : m_offset(0) |
1582 , m_runOffset(0) | 1582 , m_runOffset(0) |
1583 , m_atBreak(true) | 1583 , m_atBreak(true) |
1584 , m_textIterator(range, behavior) | 1584 , m_textIterator(range, behavior) |
1585 { | 1585 { |
1586 while (!atEnd() && !m_textIterator.length()) | 1586 while (!atEnd() && !m_textIterator.length()) |
1587 m_textIterator.advance(); | 1587 m_textIterator.advance(); |
1588 } | 1588 } |
1589 | 1589 |
1590 PassRefPtr<Range> BackwardsCharacterIterator::range() const | 1590 PassRefPtrWillBeRawPtr<Range> BackwardsCharacterIterator::range() const |
1591 { | 1591 { |
1592 RefPtr<Range> r = m_textIterator.range(); | 1592 RefPtrWillBeRawPtr<Range> r = m_textIterator.range(); |
1593 if (!m_textIterator.atEnd()) { | 1593 if (!m_textIterator.atEnd()) { |
1594 if (m_textIterator.length() <= 1) { | 1594 if (m_textIterator.length() <= 1) { |
1595 ASSERT(!m_runOffset); | 1595 ASSERT(!m_runOffset); |
1596 } else { | 1596 } else { |
1597 Node* n = r->startContainer(); | 1597 Node* n = r->startContainer(); |
1598 ASSERT(n == r->endContainer()); | 1598 ASSERT(n == r->endContainer()); |
1599 int offset = r->endOffset() - m_runOffset; | 1599 int offset = r->endOffset() - m_runOffset; |
1600 r->setStart(n, offset - 1, ASSERT_NO_EXCEPTION); | 1600 r->setStart(n, offset - 1, ASSERT_NO_EXCEPTION); |
1601 r->setEnd(n, offset, ASSERT_NO_EXCEPTION); | 1601 r->setEnd(n, offset, ASSERT_NO_EXCEPTION); |
1602 } | 1602 } |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 | 2031 |
2032 int TextIterator::rangeLength(const Range* r, bool forSelectionPreservation) | 2032 int TextIterator::rangeLength(const Range* r, bool forSelectionPreservation) |
2033 { | 2033 { |
2034 int length = 0; | 2034 int length = 0; |
2035 for (TextIterator it(r, forSelectionPreservation ? TextIteratorEmitsCharacte
rsBetweenAllVisiblePositions : TextIteratorDefaultBehavior); !it.atEnd(); it.adv
ance()) | 2035 for (TextIterator it(r, forSelectionPreservation ? TextIteratorEmitsCharacte
rsBetweenAllVisiblePositions : TextIteratorDefaultBehavior); !it.atEnd(); it.adv
ance()) |
2036 length += it.length(); | 2036 length += it.length(); |
2037 | 2037 |
2038 return length; | 2038 return length; |
2039 } | 2039 } |
2040 | 2040 |
2041 PassRefPtr<Range> TextIterator::subrange(Range* entireRange, int characterOffset
, int characterCount) | 2041 PassRefPtrWillBeRawPtr<Range> TextIterator::subrange(Range* entireRange, int cha
racterOffset, int characterCount) |
2042 { | 2042 { |
2043 CharacterIterator entireRangeIterator(entireRange); | 2043 CharacterIterator entireRangeIterator(entireRange); |
2044 return characterSubrange(entireRangeIterator, characterOffset, characterCoun
t); | 2044 return characterSubrange(entireRangeIterator, characterOffset, characterCoun
t); |
2045 } | 2045 } |
2046 | 2046 |
2047 // -------- | 2047 // -------- |
2048 | 2048 |
2049 String plainText(const Range* r, TextIteratorBehaviorFlags behavior) | 2049 String plainText(const Range* r, TextIteratorBehaviorFlags behavior) |
2050 { | 2050 { |
2051 // The initial buffer size can be critical for performance: https://bugs.web
kit.org/show_bug.cgi?id=81192 | 2051 // The initial buffer size can be critical for performance: https://bugs.web
kit.org/show_bug.cgi?id=81192 |
2052 static const unsigned initialCapacity = 1 << 15; | 2052 static const unsigned initialCapacity = 1 << 15; |
2053 | 2053 |
2054 unsigned bufferLength = 0; | 2054 unsigned bufferLength = 0; |
2055 StringBuilder builder; | 2055 StringBuilder builder; |
2056 builder.reserveCapacity(initialCapacity); | 2056 builder.reserveCapacity(initialCapacity); |
2057 | 2057 |
2058 for (TextIterator it(r, behavior); !it.atEnd(); it.advance()) { | 2058 for (TextIterator it(r, behavior); !it.atEnd(); it.advance()) { |
2059 it.appendTextToStringBuilder(builder); | 2059 it.appendTextToStringBuilder(builder); |
2060 bufferLength += it.length(); | 2060 bufferLength += it.length(); |
2061 } | 2061 } |
2062 | 2062 |
2063 if (!bufferLength) | 2063 if (!bufferLength) |
2064 return emptyString(); | 2064 return emptyString(); |
2065 | 2065 |
2066 return builder.toString(); | 2066 return builder.toString(); |
2067 } | 2067 } |
2068 | 2068 |
2069 static PassRefPtr<Range> collapsedToBoundary(const Range* range, bool forward) | 2069 static PassRefPtrWillBeRawPtr<Range> collapsedToBoundary(const Range* range, boo
l forward) |
2070 { | 2070 { |
2071 RefPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION); | 2071 RefPtrWillBeRawPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION); |
2072 result->collapse(!forward, ASSERT_NO_EXCEPTION); | 2072 result->collapse(!forward, ASSERT_NO_EXCEPTION); |
2073 return result.release(); | 2073 return result.release(); |
2074 } | 2074 } |
2075 | 2075 |
2076 static size_t findPlainTextInternal(CharacterIterator& it, const String& target,
FindOptions options, size_t& matchStart) | 2076 static size_t findPlainTextInternal(CharacterIterator& it, const String& target,
FindOptions options, size_t& matchStart) |
2077 { | 2077 { |
2078 matchStart = 0; | 2078 matchStart = 0; |
2079 size_t matchLength = 0; | 2079 size_t matchLength = 0; |
2080 | 2080 |
2081 SearchBuffer buffer(target, options); | 2081 SearchBuffer buffer(target, options); |
2082 | 2082 |
2083 if (buffer.needsMoreContext()) { | 2083 if (buffer.needsMoreContext()) { |
2084 RefPtr<Range> startRange = it.range(); | 2084 RefPtrWillBeRawPtr<Range> startRange = it.range(); |
2085 RefPtr<Range> beforeStartRange = startRange->ownerDocument().createRange
(); | 2085 RefPtrWillBeRawPtr<Range> beforeStartRange = startRange->ownerDocument()
.createRange(); |
2086 beforeStartRange->setEnd(startRange->startContainer(), startRange->start
Offset(), IGNORE_EXCEPTION); | 2086 beforeStartRange->setEnd(startRange->startContainer(), startRange->start
Offset(), IGNORE_EXCEPTION); |
2087 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.
get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { | 2087 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.
get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { |
2088 Vector<UChar, 1024> characters; | 2088 Vector<UChar, 1024> characters; |
2089 backwardsIterator.prependTextTo(characters); | 2089 backwardsIterator.prependTextTo(characters); |
2090 buffer.prependContext(characters.data(), characters.size()); | 2090 buffer.prependContext(characters.data(), characters.size()); |
2091 if (!buffer.needsMoreContext()) | 2091 if (!buffer.needsMoreContext()) |
2092 break; | 2092 break; |
2093 } | 2093 } |
2094 } | 2094 } |
2095 | 2095 |
(...skipping 18 matching lines...) Expand all Loading... |
2114 buffer.reachedBreak(); | 2114 buffer.reachedBreak(); |
2115 goto tryAgain; | 2115 goto tryAgain; |
2116 } | 2116 } |
2117 } | 2117 } |
2118 | 2118 |
2119 return matchLength; | 2119 return matchLength; |
2120 } | 2120 } |
2121 | 2121 |
2122 static const TextIteratorBehaviorFlags iteratorFlagsForFindPlainText = TextItera
torEntersTextControls | TextIteratorEntersAuthorShadowRoots; | 2122 static const TextIteratorBehaviorFlags iteratorFlagsForFindPlainText = TextItera
torEntersTextControls | TextIteratorEntersAuthorShadowRoots; |
2123 | 2123 |
2124 PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOp
tions options) | 2124 PassRefPtrWillBeRawPtr<Range> findPlainText(const Range* range, const String& ta
rget, FindOptions options) |
2125 { | 2125 { |
2126 // CharacterIterator requires renderers to be up-to-date | 2126 // CharacterIterator requires renderers to be up-to-date |
2127 range->ownerDocument().updateLayout(); | 2127 range->ownerDocument().updateLayout(); |
2128 | 2128 |
2129 // First, find the text. | 2129 // First, find the text. |
2130 size_t matchStart; | 2130 size_t matchStart; |
2131 size_t matchLength; | 2131 size_t matchLength; |
2132 { | 2132 { |
2133 CharacterIterator findIterator(range, iteratorFlagsForFindPlainText); | 2133 CharacterIterator findIterator(range, iteratorFlagsForFindPlainText); |
2134 matchLength = findPlainTextInternal(findIterator, target, options, match
Start); | 2134 matchLength = findPlainTextInternal(findIterator, target, options, match
Start); |
2135 if (!matchLength) | 2135 if (!matchLength) |
2136 return collapsedToBoundary(range, !(options & Backwards)); | 2136 return collapsedToBoundary(range, !(options & Backwards)); |
2137 } | 2137 } |
2138 | 2138 |
2139 // Then, find the document position of the start and the end of the text. | 2139 // Then, find the document position of the start and the end of the text. |
2140 CharacterIterator computeRangeIterator(range, iteratorFlagsForFindPlainText)
; | 2140 CharacterIterator computeRangeIterator(range, iteratorFlagsForFindPlainText)
; |
2141 return characterSubrange(computeRangeIterator, matchStart, matchLength); | 2141 return characterSubrange(computeRangeIterator, matchStart, matchLength); |
2142 } | 2142 } |
2143 | 2143 |
2144 PassRefPtr<Range> findPlainText(const Position& start, const Position& end, cons
t String& target, FindOptions options) | 2144 PassRefPtrWillBeRawPtr<Range> findPlainText(const Position& start, const Positio
n& end, const String& target, FindOptions options) |
2145 { | 2145 { |
2146 // CharacterIterator requires renderers to be up-to-date. | 2146 // CharacterIterator requires renderers to be up-to-date. |
2147 if (!start.inDocument()) | 2147 if (!start.inDocument()) |
2148 return nullptr; | 2148 return nullptr; |
2149 ASSERT(start.document() == end.document()); | 2149 ASSERT(start.document() == end.document()); |
2150 start.document()->updateLayout(); | 2150 start.document()->updateLayout(); |
2151 | 2151 |
2152 // FIXME: Reduce the code duplication with above (but how?). | 2152 // FIXME: Reduce the code duplication with above (but how?). |
2153 size_t matchStart; | 2153 size_t matchStart; |
2154 size_t matchLength; | 2154 size_t matchLength; |
2155 { | 2155 { |
2156 CharacterIterator findIterator(start, end, iteratorFlagsForFindPlainText
); | 2156 CharacterIterator findIterator(start, end, iteratorFlagsForFindPlainText
); |
2157 matchLength = findPlainTextInternal(findIterator, target, options, match
Start); | 2157 matchLength = findPlainTextInternal(findIterator, target, options, match
Start); |
2158 if (!matchLength) { | 2158 if (!matchLength) { |
2159 const Position& collapseTo = options & Backwards ? start : end; | 2159 const Position& collapseTo = options & Backwards ? start : end; |
2160 return Range::create(*start.document(), collapseTo, collapseTo); | 2160 return Range::create(*start.document(), collapseTo, collapseTo); |
2161 } | 2161 } |
2162 } | 2162 } |
2163 | 2163 |
2164 CharacterIterator computeRangeIterator(start, end, iteratorFlagsForFindPlain
Text); | 2164 CharacterIterator computeRangeIterator(start, end, iteratorFlagsForFindPlain
Text); |
2165 return characterSubrange(computeRangeIterator, matchStart, matchLength); | 2165 return characterSubrange(computeRangeIterator, matchStart, matchLength); |
2166 } | 2166 } |
2167 | 2167 |
2168 } | 2168 } |
OLD | NEW |