| 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 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1370 PassRefPtr<Range> CharacterIterator::range() const | 1370 PassRefPtr<Range> CharacterIterator::range() const | 
| 1371 { | 1371 { | 
| 1372     RefPtr<Range> r = m_textIterator.range(); | 1372     RefPtr<Range> r = m_textIterator.range(); | 
| 1373     if (!m_textIterator.atEnd()) { | 1373     if (!m_textIterator.atEnd()) { | 
| 1374         if (m_textIterator.length() <= 1) { | 1374         if (m_textIterator.length() <= 1) { | 
| 1375             ASSERT(m_runOffset == 0); | 1375             ASSERT(m_runOffset == 0); | 
| 1376         } else { | 1376         } else { | 
| 1377             Node* n = r->startContainer(); | 1377             Node* n = r->startContainer(); | 
| 1378             ASSERT(n == r->endContainer()); | 1378             ASSERT(n == r->endContainer()); | 
| 1379             int offset = r->startOffset() + m_runOffset; | 1379             int offset = r->startOffset() + m_runOffset; | 
| 1380             r->setStart(n, offset, ASSERT_NO_EXCEPTION_STATE); | 1380             r->setStart(n, offset, ASSERT_NO_EXCEPTION); | 
| 1381             r->setEnd(n, offset + 1, ASSERT_NO_EXCEPTION_STATE); | 1381             r->setEnd(n, offset + 1, ASSERT_NO_EXCEPTION); | 
| 1382         } | 1382         } | 
| 1383     } | 1383     } | 
| 1384     return r.release(); | 1384     return r.release(); | 
| 1385 } | 1385 } | 
| 1386 | 1386 | 
| 1387 void CharacterIterator::advance(int count) | 1387 void CharacterIterator::advance(int count) | 
| 1388 { | 1388 { | 
| 1389     if (count <= 0) { | 1389     if (count <= 0) { | 
| 1390         ASSERT(count == 0); | 1390         ASSERT(count == 0); | 
| 1391         return; | 1391         return; | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1469 PassRefPtr<Range> BackwardsCharacterIterator::range() const | 1469 PassRefPtr<Range> BackwardsCharacterIterator::range() const | 
| 1470 { | 1470 { | 
| 1471     RefPtr<Range> r = m_textIterator.range(); | 1471     RefPtr<Range> r = m_textIterator.range(); | 
| 1472     if (!m_textIterator.atEnd()) { | 1472     if (!m_textIterator.atEnd()) { | 
| 1473         if (m_textIterator.length() <= 1) | 1473         if (m_textIterator.length() <= 1) | 
| 1474             ASSERT(m_runOffset == 0); | 1474             ASSERT(m_runOffset == 0); | 
| 1475         else { | 1475         else { | 
| 1476             Node* n = r->startContainer(); | 1476             Node* n = r->startContainer(); | 
| 1477             ASSERT(n == r->endContainer()); | 1477             ASSERT(n == r->endContainer()); | 
| 1478             int offset = r->endOffset() - m_runOffset; | 1478             int offset = r->endOffset() - m_runOffset; | 
| 1479             r->setStart(n, offset - 1, ASSERT_NO_EXCEPTION_STATE); | 1479             r->setStart(n, offset - 1, ASSERT_NO_EXCEPTION); | 
| 1480             r->setEnd(n, offset, ASSERT_NO_EXCEPTION_STATE); | 1480             r->setEnd(n, offset, ASSERT_NO_EXCEPTION); | 
| 1481         } | 1481         } | 
| 1482     } | 1482     } | 
| 1483     return r.release(); | 1483     return r.release(); | 
| 1484 } | 1484 } | 
| 1485 | 1485 | 
| 1486 void BackwardsCharacterIterator::advance(int count) | 1486 void BackwardsCharacterIterator::advance(int count) | 
| 1487 { | 1487 { | 
| 1488     if (count <= 0) { | 1488     if (count <= 0) { | 
| 1489         ASSERT(!count); | 1489         ASSERT(!count); | 
| 1490         return; | 1490         return; | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1568 | 1568 | 
| 1569         // Look ahead to next chunk. If it is whitespace or a break, we can use 
      the previous stuff | 1569         // Look ahead to next chunk. If it is whitespace or a break, we can use 
      the previous stuff | 
| 1570         m_textIterator.advance(); | 1570         m_textIterator.advance(); | 
| 1571         if (m_textIterator.atEnd() || !m_textIterator.length() || isSpaceOrNewli
      ne(m_textIterator.characterAt(0))) { | 1571         if (m_textIterator.atEnd() || !m_textIterator.length() || isSpaceOrNewli
      ne(m_textIterator.characterAt(0))) { | 
| 1572             m_didLookAhead = true; | 1572             m_didLookAhead = true; | 
| 1573             return; | 1573             return; | 
| 1574         } | 1574         } | 
| 1575 | 1575 | 
| 1576         // Start gobbling chunks until we get to a suitable stopping point | 1576         // Start gobbling chunks until we get to a suitable stopping point | 
| 1577         m_textIterator.appendTextTo(m_buffer); | 1577         m_textIterator.appendTextTo(m_buffer); | 
| 1578         m_range->setEnd(m_textIterator.range()->endContainer(), m_textIterator.r
      ange()->endOffset(), IGNORE_EXCEPTION_STATE); | 1578         m_range->setEnd(m_textIterator.range()->endContainer(), m_textIterator.r
      ange()->endOffset(), IGNORE_EXCEPTION); | 
| 1579     } | 1579     } | 
| 1580 } | 1580 } | 
| 1581 | 1581 | 
| 1582 int WordAwareIterator::length() const | 1582 int WordAwareIterator::length() const | 
| 1583 { | 1583 { | 
| 1584     if (!m_buffer.isEmpty()) | 1584     if (!m_buffer.isEmpty()) | 
| 1585         return m_buffer.size(); | 1585         return m_buffer.size(); | 
| 1586     return m_textIterator.length(); | 1586     return m_textIterator.length(); | 
| 1587 } | 1587 } | 
| 1588 | 1588 | 
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2239     bool startRangeFound = false; | 2239     bool startRangeFound = false; | 
| 2240 | 2240 | 
| 2241     RefPtr<Range> textRunRange; | 2241     RefPtr<Range> textRunRange; | 
| 2242 | 2242 | 
| 2243     TextIterator it(rangeOfContents(scope).get(), forSelectionPreservation ? Tex
      tIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior
      ); | 2243     TextIterator it(rangeOfContents(scope).get(), forSelectionPreservation ? Tex
      tIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior
      ); | 
| 2244 | 2244 | 
| 2245     // FIXME: the atEnd() check shouldn't be necessary, workaround for <http://b
      ugs.webkit.org/show_bug.cgi?id=6289>. | 2245     // FIXME: the atEnd() check shouldn't be necessary, workaround for <http://b
      ugs.webkit.org/show_bug.cgi?id=6289>. | 
| 2246     if (rangeLocation == 0 && rangeLength == 0 && it.atEnd()) { | 2246     if (rangeLocation == 0 && rangeLength == 0 && it.atEnd()) { | 
| 2247         textRunRange = it.range(); | 2247         textRunRange = it.range(); | 
| 2248 | 2248 | 
| 2249         resultRange->setStart(textRunRange->startContainer(), 0, ASSERT_NO_EXCEP
      TION_STATE); | 2249         resultRange->setStart(textRunRange->startContainer(), 0, ASSERT_NO_EXCEP
      TION); | 
| 2250         resultRange->setEnd(textRunRange->startContainer(), 0, ASSERT_NO_EXCEPTI
      ON_STATE); | 2250         resultRange->setEnd(textRunRange->startContainer(), 0, ASSERT_NO_EXCEPTI
      ON); | 
| 2251 | 2251 | 
| 2252         return resultRange.release(); | 2252         return resultRange.release(); | 
| 2253     } | 2253     } | 
| 2254 | 2254 | 
| 2255     for (; !it.atEnd(); it.advance()) { | 2255     for (; !it.atEnd(); it.advance()) { | 
| 2256         int len = it.length(); | 2256         int len = it.length(); | 
| 2257         textRunRange = it.range(); | 2257         textRunRange = it.range(); | 
| 2258 | 2258 | 
| 2259         bool foundStart = rangeLocation >= docTextPosition && rangeLocation <= d
      ocTextPosition + len; | 2259         bool foundStart = rangeLocation >= docTextPosition && rangeLocation <= d
      ocTextPosition + len; | 
| 2260         bool foundEnd = rangeEnd >= docTextPosition && rangeEnd <= docTextPositi
      on + len; | 2260         bool foundEnd = rangeEnd >= docTextPosition && rangeEnd <= docTextPositi
      on + len; | 
| 2261 | 2261 | 
| 2262         // Fix textRunRange->endPosition(), but only if foundStart || foundEnd, 
      because it is only | 2262         // Fix textRunRange->endPosition(), but only if foundStart || foundEnd, 
      because it is only | 
| 2263         // in those cases that textRunRange is used. | 2263         // in those cases that textRunRange is used. | 
| 2264         if (foundEnd) { | 2264         if (foundEnd) { | 
| 2265             // FIXME: This is a workaround for the fact that the end of a run is
       often at the wrong | 2265             // FIXME: This is a workaround for the fact that the end of a run is
       often at the wrong | 
| 2266             // position for emitted '\n's. | 2266             // position for emitted '\n's. | 
| 2267             if (len == 1 && it.characterAt(0) == '\n') { | 2267             if (len == 1 && it.characterAt(0) == '\n') { | 
| 2268                 scope->document()->updateLayoutIgnorePendingStylesheets(); | 2268                 scope->document()->updateLayoutIgnorePendingStylesheets(); | 
| 2269                 it.advance(); | 2269                 it.advance(); | 
| 2270                 if (!it.atEnd()) { | 2270                 if (!it.atEnd()) { | 
| 2271                     RefPtr<Range> range = it.range(); | 2271                     RefPtr<Range> range = it.range(); | 
| 2272                     textRunRange->setEnd(range->startContainer(), range->startOf
      fset(), ASSERT_NO_EXCEPTION_STATE); | 2272                     textRunRange->setEnd(range->startContainer(), range->startOf
      fset(), ASSERT_NO_EXCEPTION); | 
| 2273                 } else { | 2273                 } else { | 
| 2274                     Position runStart = textRunRange->startPosition(); | 2274                     Position runStart = textRunRange->startPosition(); | 
| 2275                     Position runEnd = VisiblePosition(runStart).next().deepEquiv
      alent(); | 2275                     Position runEnd = VisiblePosition(runStart).next().deepEquiv
      alent(); | 
| 2276                     if (runEnd.isNotNull()) | 2276                     if (runEnd.isNotNull()) | 
| 2277                         textRunRange->setEnd(runEnd.containerNode(), runEnd.comp
      uteOffsetInContainerNode(), ASSERT_NO_EXCEPTION_STATE); | 2277                         textRunRange->setEnd(runEnd.containerNode(), runEnd.comp
      uteOffsetInContainerNode(), ASSERT_NO_EXCEPTION); | 
| 2278                 } | 2278                 } | 
| 2279             } | 2279             } | 
| 2280         } | 2280         } | 
| 2281 | 2281 | 
| 2282         if (foundStart) { | 2282         if (foundStart) { | 
| 2283             startRangeFound = true; | 2283             startRangeFound = true; | 
| 2284             if (textRunRange->startContainer()->isTextNode()) { | 2284             if (textRunRange->startContainer()->isTextNode()) { | 
| 2285                 int offset = rangeLocation - docTextPosition; | 2285                 int offset = rangeLocation - docTextPosition; | 
| 2286                 resultRange->setStart(textRunRange->startContainer(), offset + t
      extRunRange->startOffset(), IGNORE_EXCEPTION_STATE); | 2286                 resultRange->setStart(textRunRange->startContainer(), offset + t
      extRunRange->startOffset(), IGNORE_EXCEPTION); | 
| 2287             } else { | 2287             } else { | 
| 2288                 if (rangeLocation == docTextPosition) | 2288                 if (rangeLocation == docTextPosition) | 
| 2289                     resultRange->setStart(textRunRange->startContainer(), textRu
      nRange->startOffset(), IGNORE_EXCEPTION_STATE); | 2289                     resultRange->setStart(textRunRange->startContainer(), textRu
      nRange->startOffset(), IGNORE_EXCEPTION); | 
| 2290                 else | 2290                 else | 
| 2291                     resultRange->setStart(textRunRange->endContainer(), textRunR
      ange->endOffset(), IGNORE_EXCEPTION_STATE); | 2291                     resultRange->setStart(textRunRange->endContainer(), textRunR
      ange->endOffset(), IGNORE_EXCEPTION); | 
| 2292             } | 2292             } | 
| 2293         } | 2293         } | 
| 2294 | 2294 | 
| 2295         if (foundEnd) { | 2295         if (foundEnd) { | 
| 2296             if (textRunRange->startContainer()->isTextNode()) { | 2296             if (textRunRange->startContainer()->isTextNode()) { | 
| 2297                 int offset = rangeEnd - docTextPosition; | 2297                 int offset = rangeEnd - docTextPosition; | 
| 2298                 resultRange->setEnd(textRunRange->startContainer(), offset + tex
      tRunRange->startOffset(), IGNORE_EXCEPTION_STATE); | 2298                 resultRange->setEnd(textRunRange->startContainer(), offset + tex
      tRunRange->startOffset(), IGNORE_EXCEPTION); | 
| 2299             } else { | 2299             } else { | 
| 2300                 if (rangeEnd == docTextPosition) | 2300                 if (rangeEnd == docTextPosition) | 
| 2301                     resultRange->setEnd(textRunRange->startContainer(), textRunR
      ange->startOffset(), IGNORE_EXCEPTION_STATE); | 2301                     resultRange->setEnd(textRunRange->startContainer(), textRunR
      ange->startOffset(), IGNORE_EXCEPTION); | 
| 2302                 else | 2302                 else | 
| 2303                     resultRange->setEnd(textRunRange->endContainer(), textRunRan
      ge->endOffset(), IGNORE_EXCEPTION_STATE); | 2303                     resultRange->setEnd(textRunRange->endContainer(), textRunRan
      ge->endOffset(), IGNORE_EXCEPTION); | 
| 2304             } | 2304             } | 
| 2305             docTextPosition += len; | 2305             docTextPosition += len; | 
| 2306             break; | 2306             break; | 
| 2307         } | 2307         } | 
| 2308         docTextPosition += len; | 2308         docTextPosition += len; | 
| 2309     } | 2309     } | 
| 2310 | 2310 | 
| 2311     if (!startRangeFound) | 2311     if (!startRangeFound) | 
| 2312         return 0; | 2312         return 0; | 
| 2313 | 2313 | 
| 2314     if (rangeLength != 0 && rangeEnd > docTextPosition) { // rangeEnd is out of 
      bounds | 2314     if (rangeLength != 0 && rangeEnd > docTextPosition) { // rangeEnd is out of 
      bounds | 
| 2315         resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffse
      t(), IGNORE_EXCEPTION_STATE); | 2315         resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffse
      t(), IGNORE_EXCEPTION); | 
| 2316     } | 2316     } | 
| 2317 | 2317 | 
| 2318     return resultRange.release(); | 2318     return resultRange.release(); | 
| 2319 } | 2319 } | 
| 2320 | 2320 | 
| 2321 bool TextIterator::getLocationAndLengthFromRange(Node* scope, const Range* range
      , size_t& location, size_t& length) | 2321 bool TextIterator::getLocationAndLengthFromRange(Node* scope, const Range* range
      , size_t& location, size_t& length) | 
| 2322 { | 2322 { | 
| 2323     location = notFound; | 2323     location = notFound; | 
| 2324     length = 0; | 2324     length = 0; | 
| 2325 | 2325 | 
| 2326     if (!range->startContainer()) | 2326     if (!range->startContainer()) | 
| 2327         return false; | 2327         return false; | 
| 2328 | 2328 | 
| 2329     // The critical assumption is that this only gets called with ranges that | 2329     // The critical assumption is that this only gets called with ranges that | 
| 2330     // concentrate on a given area containing the selection root. This is done | 2330     // concentrate on a given area containing the selection root. This is done | 
| 2331     // because of text fields and textareas. The DOM for those is not | 2331     // because of text fields and textareas. The DOM for those is not | 
| 2332     // directly in the document DOM, so ensure that the range does not cross a | 2332     // directly in the document DOM, so ensure that the range does not cross a | 
| 2333     // boundary of one of those. | 2333     // boundary of one of those. | 
| 2334     if (range->startContainer() != scope && !range->startContainer()->isDescenda
      ntOf(scope)) | 2334     if (range->startContainer() != scope && !range->startContainer()->isDescenda
      ntOf(scope)) | 
| 2335         return false; | 2335         return false; | 
| 2336     if (range->endContainer() != scope && !range->endContainer()->isDescendantOf
      (scope)) | 2336     if (range->endContainer() != scope && !range->endContainer()->isDescendantOf
      (scope)) | 
| 2337         return false; | 2337         return false; | 
| 2338 | 2338 | 
| 2339     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->
      startContainer(), range->startOffset()); | 2339     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->
      startContainer(), range->startOffset()); | 
| 2340     ASSERT(testRange->startContainer() == scope); | 2340     ASSERT(testRange->startContainer() == scope); | 
| 2341     location = TextIterator::rangeLength(testRange.get()); | 2341     location = TextIterator::rangeLength(testRange.get()); | 
| 2342 | 2342 | 
| 2343     testRange->setEnd(range->endContainer(), range->endOffset(), IGNORE_EXCEPTIO
      N_STATE); | 2343     testRange->setEnd(range->endContainer(), range->endOffset(), IGNORE_EXCEPTIO
      N); | 
| 2344     ASSERT(testRange->startContainer() == scope); | 2344     ASSERT(testRange->startContainer() == scope); | 
| 2345     length = TextIterator::rangeLength(testRange.get()) - location; | 2345     length = TextIterator::rangeLength(testRange.get()) - location; | 
| 2346     return true; | 2346     return true; | 
| 2347 } | 2347 } | 
| 2348 | 2348 | 
| 2349 // -------- | 2349 // -------- | 
| 2350 | 2350 | 
| 2351 String plainText(const Range* r, TextIteratorBehavior defaultBehavior, bool isDi
      splayString) | 2351 String plainText(const Range* r, TextIteratorBehavior defaultBehavior, bool isDi
      splayString) | 
| 2352 { | 2352 { | 
| 2353     // The initial buffer size can be critical for performance: https://bugs.web
      kit.org/show_bug.cgi?id=81192 | 2353     // The initial buffer size can be critical for performance: https://bugs.web
      kit.org/show_bug.cgi?id=81192 | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 2371     String result = builder.toString(); | 2371     String result = builder.toString(); | 
| 2372 | 2372 | 
| 2373     if (isDisplayString && r->ownerDocument()) | 2373     if (isDisplayString && r->ownerDocument()) | 
| 2374         r->ownerDocument()->displayStringModifiedByEncoding(result); | 2374         r->ownerDocument()->displayStringModifiedByEncoding(result); | 
| 2375 | 2375 | 
| 2376     return result; | 2376     return result; | 
| 2377 } | 2377 } | 
| 2378 | 2378 | 
| 2379 static PassRefPtr<Range> collapsedToBoundary(const Range* range, bool forward) | 2379 static PassRefPtr<Range> collapsedToBoundary(const Range* range, bool forward) | 
| 2380 { | 2380 { | 
| 2381     RefPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION_STATE); | 2381     RefPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION); | 
| 2382     result->collapse(!forward, ASSERT_NO_EXCEPTION_STATE); | 2382     result->collapse(!forward, ASSERT_NO_EXCEPTION); | 
| 2383     return result.release(); | 2383     return result.release(); | 
| 2384 } | 2384 } | 
| 2385 | 2385 | 
| 2386 static size_t findPlainText(CharacterIterator& it, const String& target, FindOpt
      ions options, size_t& matchStart) | 2386 static size_t findPlainText(CharacterIterator& it, const String& target, FindOpt
      ions options, size_t& matchStart) | 
| 2387 { | 2387 { | 
| 2388     matchStart = 0; | 2388     matchStart = 0; | 
| 2389     size_t matchLength = 0; | 2389     size_t matchLength = 0; | 
| 2390 | 2390 | 
| 2391     SearchBuffer buffer(target, options); | 2391     SearchBuffer buffer(target, options); | 
| 2392 | 2392 | 
| 2393     if (buffer.needsMoreContext()) { | 2393     if (buffer.needsMoreContext()) { | 
| 2394         RefPtr<Range> startRange = it.range(); | 2394         RefPtr<Range> startRange = it.range(); | 
| 2395         RefPtr<Range> beforeStartRange = startRange->ownerDocument()->createRang
      e(); | 2395         RefPtr<Range> beforeStartRange = startRange->ownerDocument()->createRang
      e(); | 
| 2396         beforeStartRange->setEnd(startRange->startContainer(), startRange->start
      Offset(), IGNORE_EXCEPTION_STATE); | 2396         beforeStartRange->setEnd(startRange->startContainer(), startRange->start
      Offset(), IGNORE_EXCEPTION); | 
| 2397         for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.
      get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { | 2397         for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.
      get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { | 
| 2398             Vector<UChar, 1024> characters; | 2398             Vector<UChar, 1024> characters; | 
| 2399             backwardsIterator.prependTextTo(characters); | 2399             backwardsIterator.prependTextTo(characters); | 
| 2400             buffer.prependContext(characters.data(), characters.size()); | 2400             buffer.prependContext(characters.data(), characters.size()); | 
| 2401             if (!buffer.needsMoreContext()) | 2401             if (!buffer.needsMoreContext()) | 
| 2402                 break; | 2402                 break; | 
| 2403         } | 2403         } | 
| 2404     } | 2404     } | 
| 2405 | 2405 | 
| 2406     while (!it.atEnd()) { | 2406     while (!it.atEnd()) { | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2443         if (!matchLength) | 2443         if (!matchLength) | 
| 2444             return collapsedToBoundary(range, !(options & Backwards)); | 2444             return collapsedToBoundary(range, !(options & Backwards)); | 
| 2445     } | 2445     } | 
| 2446 | 2446 | 
| 2447     // Then, find the document position of the start and the end of the text. | 2447     // Then, find the document position of the start and the end of the text. | 
| 2448     CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
      ); | 2448     CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
      ); | 
| 2449     return characterSubrange(computeRangeIterator, matchStart, matchLength); | 2449     return characterSubrange(computeRangeIterator, matchStart, matchLength); | 
| 2450 } | 2450 } | 
| 2451 | 2451 | 
| 2452 } | 2452 } | 
| OLD | NEW | 
|---|