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 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 PassRefPtr<Range> TextIterator::range() const | 1043 PassRefPtr<Range> TextIterator::range() const |
1044 { | 1044 { |
1045 // use the current run information, if we have it | 1045 // use the current run information, if we have it |
1046 if (m_positionNode) { | 1046 if (m_positionNode) { |
1047 if (m_positionOffsetBaseNode) { | 1047 if (m_positionOffsetBaseNode) { |
1048 int index = m_positionOffsetBaseNode->nodeIndex(); | 1048 int index = m_positionOffsetBaseNode->nodeIndex(); |
1049 m_positionStartOffset += index; | 1049 m_positionStartOffset += index; |
1050 m_positionEndOffset += index; | 1050 m_positionEndOffset += index; |
1051 m_positionOffsetBaseNode = 0; | 1051 m_positionOffsetBaseNode = 0; |
1052 } | 1052 } |
1053 return Range::create(&m_positionNode->document(), m_positionNode, m_posi
tionStartOffset, m_positionNode, m_positionEndOffset); | 1053 return Range::create(m_positionNode->document(), m_positionNode, m_posit
ionStartOffset, m_positionNode, m_positionEndOffset); |
1054 } | 1054 } |
1055 | 1055 |
1056 // otherwise, return the end of the overall range we were given | 1056 // otherwise, return the end of the overall range we were given |
1057 if (m_endContainer) | 1057 if (m_endContainer) |
1058 return Range::create(&m_endContainer->document(), m_endContainer, m_endO
ffset, m_endContainer, m_endOffset); | 1058 return Range::create(m_endContainer->document(), m_endContainer, m_endOf
fset, m_endContainer, m_endOffset); |
1059 | 1059 |
1060 return 0; | 1060 return 0; |
1061 } | 1061 } |
1062 | 1062 |
1063 Node* TextIterator::node() const | 1063 Node* TextIterator::node() const |
1064 { | 1064 { |
1065 RefPtr<Range> textRange = range(); | 1065 RefPtr<Range> textRange = range(); |
1066 if (!textRange) | 1066 if (!textRange) |
1067 return 0; | 1067 return 0; |
1068 | 1068 |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 m_havePassedStartNode |= m_node == m_startNode; | 1344 m_havePassedStartNode |= m_node == m_startNode; |
1345 if (m_havePassedStartNode) | 1345 if (m_havePassedStartNode) |
1346 return false; | 1346 return false; |
1347 m_node = next; | 1347 m_node = next; |
1348 return true; | 1348 return true; |
1349 } | 1349 } |
1350 | 1350 |
1351 PassRefPtr<Range> SimplifiedBackwardsTextIterator::range() const | 1351 PassRefPtr<Range> SimplifiedBackwardsTextIterator::range() const |
1352 { | 1352 { |
1353 if (m_positionNode) | 1353 if (m_positionNode) |
1354 return Range::create(&m_positionNode->document(), m_positionNode, m_posi
tionStartOffset, m_positionNode, m_positionEndOffset); | 1354 return Range::create(m_positionNode->document(), m_positionNode, m_posit
ionStartOffset, m_positionNode, m_positionEndOffset); |
1355 | 1355 |
1356 return Range::create(&m_startNode->document(), m_startNode, m_startOffset, m
_startNode, m_startOffset); | 1356 return Range::create(m_startNode->document(), m_startNode, m_startOffset, m_
startNode, m_startOffset); |
1357 } | 1357 } |
1358 | 1358 |
1359 // -------- | 1359 // -------- |
1360 | 1360 |
1361 CharacterIterator::CharacterIterator(const Range* r, TextIteratorBehavior behavi
or) | 1361 CharacterIterator::CharacterIterator(const Range* r, TextIteratorBehavior behavi
or) |
1362 : m_offset(0) | 1362 : m_offset(0) |
1363 , m_runOffset(0) | 1363 , m_runOffset(0) |
1364 , m_atBreak(true) | 1364 , m_atBreak(true) |
1365 , m_textIterator(r, behavior) | 1365 , m_textIterator(r, behavior) |
1366 { | 1366 { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 | 1445 |
1446 static PassRefPtr<Range> characterSubrange(CharacterIterator& it, int offset, in
t length) | 1446 static PassRefPtr<Range> characterSubrange(CharacterIterator& it, int offset, in
t length) |
1447 { | 1447 { |
1448 it.advance(offset); | 1448 it.advance(offset); |
1449 RefPtr<Range> start = it.range(); | 1449 RefPtr<Range> start = it.range(); |
1450 | 1450 |
1451 if (length > 1) | 1451 if (length > 1) |
1452 it.advance(length - 1); | 1452 it.advance(length - 1); |
1453 RefPtr<Range> end = it.range(); | 1453 RefPtr<Range> end = it.range(); |
1454 | 1454 |
1455 return Range::create(&start->startContainer()->document(), | 1455 return Range::create(start->startContainer()->document(), |
1456 start->startContainer(), start->startOffset(), | 1456 start->startContainer(), start->startOffset(), |
1457 end->endContainer(), end->endOffset()); | 1457 end->endContainer(), end->endOffset()); |
1458 } | 1458 } |
1459 | 1459 |
1460 BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextI
teratorBehavior behavior) | 1460 BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextI
teratorBehavior behavior) |
1461 : m_offset(0) | 1461 : m_offset(0) |
1462 , m_runOffset(0) | 1462 , m_runOffset(0) |
1463 , m_atBreak(true) | 1463 , m_atBreak(true) |
1464 , m_textIterator(range, behavior) | 1464 , m_textIterator(range, behavior) |
1465 { | 1465 { |
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2330 // The critical assumption is that this only gets called with ranges that | 2330 // The critical assumption is that this only gets called with ranges that |
2331 // concentrate on a given area containing the selection root. This is done | 2331 // concentrate on a given area containing the selection root. This is done |
2332 // because of text fields and textareas. The DOM for those is not | 2332 // because of text fields and textareas. The DOM for those is not |
2333 // directly in the document DOM, so ensure that the range does not cross a | 2333 // directly in the document DOM, so ensure that the range does not cross a |
2334 // boundary of one of those. | 2334 // boundary of one of those. |
2335 if (range->startContainer() != scope && !range->startContainer()->isDescenda
ntOf(scope)) | 2335 if (range->startContainer() != scope && !range->startContainer()->isDescenda
ntOf(scope)) |
2336 return false; | 2336 return false; |
2337 if (range->endContainer() != scope && !range->endContainer()->isDescendantOf
(scope)) | 2337 if (range->endContainer() != scope && !range->endContainer()->isDescendantOf
(scope)) |
2338 return false; | 2338 return false; |
2339 | 2339 |
2340 RefPtr<Range> testRange = Range::create(&scope->document(), scope, 0, range-
>startContainer(), range->startOffset()); | 2340 RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->
startContainer(), range->startOffset()); |
2341 ASSERT(testRange->startContainer() == scope); | 2341 ASSERT(testRange->startContainer() == scope); |
2342 location = TextIterator::rangeLength(testRange.get()); | 2342 location = TextIterator::rangeLength(testRange.get()); |
2343 | 2343 |
2344 testRange->setEnd(range->endContainer(), range->endOffset(), IGNORE_EXCEPTIO
N); | 2344 testRange->setEnd(range->endContainer(), range->endOffset(), IGNORE_EXCEPTIO
N); |
2345 ASSERT(testRange->startContainer() == scope); | 2345 ASSERT(testRange->startContainer() == scope); |
2346 length = TextIterator::rangeLength(testRange.get()) - location; | 2346 length = TextIterator::rangeLength(testRange.get()) - location; |
2347 return true; | 2347 return true; |
2348 } | 2348 } |
2349 | 2349 |
2350 // -------- | 2350 // -------- |
(...skipping 13 matching lines...) Expand all Loading... |
2364 for (TextIterator it(r, behavior); !it.atEnd(); it.advance()) { | 2364 for (TextIterator it(r, behavior); !it.atEnd(); it.advance()) { |
2365 it.appendTextToStringBuilder(builder); | 2365 it.appendTextToStringBuilder(builder); |
2366 bufferLength += it.length(); | 2366 bufferLength += it.length(); |
2367 } | 2367 } |
2368 | 2368 |
2369 if (!bufferLength) | 2369 if (!bufferLength) |
2370 return emptyString(); | 2370 return emptyString(); |
2371 | 2371 |
2372 String result = builder.toString(); | 2372 String result = builder.toString(); |
2373 | 2373 |
2374 if (isDisplayString && r->ownerDocument()) | 2374 if (isDisplayString) |
2375 r->ownerDocument()->displayStringModifiedByEncoding(result); | 2375 r->ownerDocument().displayStringModifiedByEncoding(result); |
2376 | 2376 |
2377 return result; | 2377 return result; |
2378 } | 2378 } |
2379 | 2379 |
2380 static PassRefPtr<Range> collapsedToBoundary(const Range* range, bool forward) | 2380 static PassRefPtr<Range> collapsedToBoundary(const Range* range, bool forward) |
2381 { | 2381 { |
2382 RefPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION); | 2382 RefPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION); |
2383 result->collapse(!forward, ASSERT_NO_EXCEPTION); | 2383 result->collapse(!forward, ASSERT_NO_EXCEPTION); |
2384 return result.release(); | 2384 return result.release(); |
2385 } | 2385 } |
2386 | 2386 |
2387 static size_t findPlainText(CharacterIterator& it, const String& target, FindOpt
ions options, size_t& matchStart) | 2387 static size_t findPlainText(CharacterIterator& it, const String& target, FindOpt
ions options, size_t& matchStart) |
2388 { | 2388 { |
2389 matchStart = 0; | 2389 matchStart = 0; |
2390 size_t matchLength = 0; | 2390 size_t matchLength = 0; |
2391 | 2391 |
2392 SearchBuffer buffer(target, options); | 2392 SearchBuffer buffer(target, options); |
2393 | 2393 |
2394 if (buffer.needsMoreContext()) { | 2394 if (buffer.needsMoreContext()) { |
2395 RefPtr<Range> startRange = it.range(); | 2395 RefPtr<Range> startRange = it.range(); |
2396 RefPtr<Range> beforeStartRange = startRange->ownerDocument()->createRang
e(); | 2396 RefPtr<Range> beforeStartRange = startRange->ownerDocument().createRange
(); |
2397 beforeStartRange->setEnd(startRange->startContainer(), startRange->start
Offset(), IGNORE_EXCEPTION); | 2397 beforeStartRange->setEnd(startRange->startContainer(), startRange->start
Offset(), IGNORE_EXCEPTION); |
2398 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.
get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { | 2398 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.
get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { |
2399 Vector<UChar, 1024> characters; | 2399 Vector<UChar, 1024> characters; |
2400 backwardsIterator.prependTextTo(characters); | 2400 backwardsIterator.prependTextTo(characters); |
2401 buffer.prependContext(characters.data(), characters.size()); | 2401 buffer.prependContext(characters.data(), characters.size()); |
2402 if (!buffer.needsMoreContext()) | 2402 if (!buffer.needsMoreContext()) |
2403 break; | 2403 break; |
2404 } | 2404 } |
2405 } | 2405 } |
2406 | 2406 |
(...skipping 19 matching lines...) Expand all Loading... |
2426 goto tryAgain; | 2426 goto tryAgain; |
2427 } | 2427 } |
2428 } | 2428 } |
2429 | 2429 |
2430 return matchLength; | 2430 return matchLength; |
2431 } | 2431 } |
2432 | 2432 |
2433 PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOp
tions options) | 2433 PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOp
tions options) |
2434 { | 2434 { |
2435 // CharacterIterator requires renderers to be up-to-date | 2435 // CharacterIterator requires renderers to be up-to-date |
2436 range->ownerDocument()->updateLayout(); | 2436 range->ownerDocument().updateLayout(); |
2437 | 2437 |
2438 // First, find the text. | 2438 // First, find the text. |
2439 size_t matchStart; | 2439 size_t matchStart; |
2440 size_t matchLength; | 2440 size_t matchLength; |
2441 { | 2441 { |
2442 CharacterIterator findIterator(range, TextIteratorEntersTextControls); | 2442 CharacterIterator findIterator(range, TextIteratorEntersTextControls); |
2443 matchLength = findPlainText(findIterator, target, options, matchStart); | 2443 matchLength = findPlainText(findIterator, target, options, matchStart); |
2444 if (!matchLength) | 2444 if (!matchLength) |
2445 return collapsedToBoundary(range, !(options & Backwards)); | 2445 return collapsedToBoundary(range, !(options & Backwards)); |
2446 } | 2446 } |
2447 | 2447 |
2448 // Then, find the document position of the start and the end of the text. | 2448 // Then, find the document position of the start and the end of the text. |
2449 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
); | 2449 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
); |
2450 return characterSubrange(computeRangeIterator, matchStart, matchLength); | 2450 return characterSubrange(computeRangeIterator, matchStart, matchLength); |
2451 } | 2451 } |
2452 | 2452 |
2453 } | 2453 } |
OLD | NEW |