| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
Function searchFunction) | 450 static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
Function searchFunction) |
| 451 { | 451 { |
| 452 Position pos = c.deepEquivalent(); | 452 Position pos = c.deepEquivalent(); |
| 453 Node* boundary = pos.parentEditingBoundary(); | 453 Node* boundary = pos.parentEditingBoundary(); |
| 454 if (!boundary) | 454 if (!boundary) |
| 455 return VisiblePosition(); | 455 return VisiblePosition(); |
| 456 | 456 |
| 457 Document& d = boundary->document(); | 457 Document& d = boundary->document(); |
| 458 Position start = createLegacyEditingPosition(boundary, 0).parentAnchoredEqui
valent(); | 458 Position start = createLegacyEditingPosition(boundary, 0).parentAnchoredEqui
valent(); |
| 459 Position end = pos.parentAnchoredEquivalent(); | 459 Position end = pos.parentAnchoredEquivalent(); |
| 460 RefPtrWillBeRawPtr<Range> searchRange = Range::create(d); | |
| 461 | 460 |
| 462 Vector<UChar, 1024> string; | 461 Vector<UChar, 1024> string; |
| 463 unsigned suffixLength = 0; | 462 unsigned suffixLength = 0; |
| 464 | 463 |
| 465 TrackExceptionState exceptionState; | 464 TrackExceptionState exceptionState; |
| 466 if (requiresContextForWordBoundary(c.characterBefore())) { | 465 if (requiresContextForWordBoundary(c.characterBefore())) { |
| 467 RefPtrWillBeRawPtr<Range> forwardsScanRange(d.createRange()); | 466 RefPtrWillBeRawPtr<Range> forwardsScanRange(d.createRange()); |
| 468 forwardsScanRange->setEndAfter(boundary, exceptionState); | 467 forwardsScanRange->setEndAfter(boundary, exceptionState); |
| 469 forwardsScanRange->setStart(end.deprecatedNode(), end.deprecatedEditingO
ffset(), exceptionState); | 468 forwardsScanRange->setStart(end.deprecatedNode(), end.deprecatedEditingO
ffset(), exceptionState); |
| 470 TextIterator forwardsIterator(forwardsScanRange.get()); | 469 TextIterator forwardsIterator(forwardsScanRange.get()); |
| 471 while (!forwardsIterator.atEnd()) { | 470 while (!forwardsIterator.atEnd()) { |
| 472 Vector<UChar, 1024> characters; | 471 Vector<UChar, 1024> characters; |
| 473 forwardsIterator.appendTextTo(characters); | 472 forwardsIterator.appendTextTo(characters); |
| 474 int i = endOfFirstWordBoundaryContext(characters.data(), characters.
size()); | 473 int i = endOfFirstWordBoundaryContext(characters.data(), characters.
size()); |
| 475 string.append(characters.data(), i); | 474 string.append(characters.data(), i); |
| 476 suffixLength += i; | 475 suffixLength += i; |
| 477 if (static_cast<unsigned>(i) < characters.size()) | 476 if (static_cast<unsigned>(i) < characters.size()) |
| 478 break; | 477 break; |
| 479 forwardsIterator.advance(); | 478 forwardsIterator.advance(); |
| 480 } | 479 } |
| 481 } | 480 } |
| 482 | 481 |
| 483 searchRange->setStart(start.deprecatedNode(), start.deprecatedEditingOffset(
), exceptionState); | |
| 484 searchRange->setEnd(end.deprecatedNode(), end.deprecatedEditingOffset(), exc
eptionState); | |
| 485 | |
| 486 ASSERT(!exceptionState.hadException()); | 482 ASSERT(!exceptionState.hadException()); |
| 487 if (exceptionState.hadException()) | 483 if (exceptionState.hadException()) |
| 488 return VisiblePosition(); | 484 return VisiblePosition(); |
| 489 | 485 |
| 490 SimplifiedBackwardsTextIterator it(searchRange.get()); | 486 SimplifiedBackwardsTextIterator it(start, end); |
| 491 unsigned next = 0; | 487 unsigned next = 0; |
| 492 bool needMoreContext = false; | 488 bool needMoreContext = false; |
| 493 while (!it.atEnd()) { | 489 while (!it.atEnd()) { |
| 494 bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node(
)->renderer()->style()->textSecurity() != TSNONE; | 490 bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node(
)->renderer()->style()->textSecurity() != TSNONE; |
| 495 // iterate to get chunks until the searchFunction returns a non-zero val
ue. | 491 // iterate to get chunks until the searchFunction returns a non-zero val
ue. |
| 496 if (!inTextSecurityMode) | 492 if (!inTextSecurityMode) |
| 497 it.prependTextTo(string); | 493 it.prependTextTo(string); |
| 498 else { | 494 else { |
| 499 // Treat bullets used in the text security mode as regular character
s when looking for boundaries | 495 // Treat bullets used in the text security mode as regular character
s when looking for boundaries |
| 500 Vector<UChar, 1024> iteratorString; | 496 Vector<UChar, 1024> iteratorString; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 515 | 511 |
| 516 if (!next) | 512 if (!next) |
| 517 return VisiblePosition(it.atEnd() ? it.startPosition() : pos, DOWNSTREAM
); | 513 return VisiblePosition(it.atEnd() ? it.startPosition() : pos, DOWNSTREAM
); |
| 518 | 514 |
| 519 Node* node = it.startContainer(); | 515 Node* node = it.startContainer(); |
| 520 if ((node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffse
t()) || (node->renderer() && node->renderer()->isBR() && !next)) | 516 if ((node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffse
t()) || (node->renderer() && node->renderer()->isBR() && !next)) |
| 521 // The next variable contains a usable index into a text node | 517 // The next variable contains a usable index into a text node |
| 522 return VisiblePosition(createLegacyEditingPosition(node, next), DOWNSTRE
AM); | 518 return VisiblePosition(createLegacyEditingPosition(node, next), DOWNSTRE
AM); |
| 523 | 519 |
| 524 // Use the character iterator to translate the next value into a DOM positio
n. | 520 // Use the character iterator to translate the next value into a DOM positio
n. |
| 525 BackwardsCharacterIterator charIt(searchRange.get()); | 521 BackwardsCharacterIterator charIt(start, end); |
| 526 charIt.advance(string.size() - suffixLength - next); | 522 charIt.advance(string.size() - suffixLength - next); |
| 527 // FIXME: charIt can get out of shadow host. | 523 // FIXME: charIt can get out of shadow host. |
| 528 return VisiblePosition(charIt.endPosition(), DOWNSTREAM); | 524 return VisiblePosition(charIt.endPosition(), DOWNSTREAM); |
| 529 } | 525 } |
| 530 | 526 |
| 531 static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
tion searchFunction) | 527 static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
tion searchFunction) |
| 532 { | 528 { |
| 533 Position pos = c.deepEquivalent(); | 529 Position pos = c.deepEquivalent(); |
| 534 Node* boundary = pos.parentEditingBoundary(); | 530 Node* boundary = pos.parentEditingBoundary(); |
| 535 if (!boundary) | 531 if (!boundary) |
| 536 return VisiblePosition(); | 532 return VisiblePosition(); |
| 537 | 533 |
| 538 Document& d = boundary->document(); | 534 Document& d = boundary->document(); |
| 539 RefPtrWillBeRawPtr<Range> searchRange(d.createRange()); | |
| 540 Position start(pos.parentAnchoredEquivalent()); | 535 Position start(pos.parentAnchoredEquivalent()); |
| 541 | 536 |
| 542 Vector<UChar, 1024> string; | 537 Vector<UChar, 1024> string; |
| 543 unsigned prefixLength = 0; | 538 unsigned prefixLength = 0; |
| 544 | 539 |
| 545 if (requiresContextForWordBoundary(c.characterAfter())) { | 540 if (requiresContextForWordBoundary(c.characterAfter())) { |
| 546 RefPtrWillBeRawPtr<Range> backwardsScanRange(d.createRange()); | 541 RefPtrWillBeRawPtr<Range> backwardsScanRange(d.createRange()); |
| 547 backwardsScanRange->setEnd(start.deprecatedNode(), start.deprecatedEditi
ngOffset(), IGNORE_EXCEPTION); | 542 backwardsScanRange->setEnd(start.deprecatedNode(), start.deprecatedEditi
ngOffset(), IGNORE_EXCEPTION); |
| 548 SimplifiedBackwardsTextIterator backwardsIterator(backwardsScanRange.get
()); | 543 SimplifiedBackwardsTextIterator backwardsIterator(backwardsScanRange.get
()); |
| 549 while (!backwardsIterator.atEnd()) { | 544 while (!backwardsIterator.atEnd()) { |
| 550 Vector<UChar, 1024> characters; | 545 Vector<UChar, 1024> characters; |
| 551 backwardsIterator.prependTextTo(characters); | 546 backwardsIterator.prependTextTo(characters); |
| 552 int length = characters.size(); | 547 int length = characters.size(); |
| 553 int i = startOfLastWordBoundaryContext(characters.data(), length); | 548 int i = startOfLastWordBoundaryContext(characters.data(), length); |
| 554 string.prepend(characters.data() + i, length - i); | 549 string.prepend(characters.data() + i, length - i); |
| 555 prefixLength += length - i; | 550 prefixLength += length - i; |
| 556 if (i > 0) | 551 if (i > 0) |
| 557 break; | 552 break; |
| 558 backwardsIterator.advance(); | 553 backwardsIterator.advance(); |
| 559 } | 554 } |
| 560 } | 555 } |
| 561 | 556 |
| 562 searchRange->selectNodeContents(boundary, IGNORE_EXCEPTION); | 557 Position searchStart = createLegacyEditingPosition(start.deprecatedNode(), s
tart.deprecatedEditingOffset()); |
| 563 searchRange->setStart(start.deprecatedNode(), start.deprecatedEditingOffset(
), IGNORE_EXCEPTION); | 558 RangeBoundaryPoint searchEndPoint(boundary); |
| 564 TextIterator it(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisi
blePositions); | 559 searchEndPoint.setToEndOfNode(*boundary); |
| 560 Position searchEnd = searchEndPoint.toPosition(); |
| 561 TextIterator it(searchStart, searchEnd, TextIteratorEmitsCharactersBetweenAl
lVisiblePositions); |
| 565 const unsigned invalidOffset = static_cast<unsigned>(-1); | 562 const unsigned invalidOffset = static_cast<unsigned>(-1); |
| 566 unsigned next = invalidOffset; | 563 unsigned next = invalidOffset; |
| 567 bool needMoreContext = false; | 564 bool needMoreContext = false; |
| 568 while (!it.atEnd()) { | 565 while (!it.atEnd()) { |
| 569 // Keep asking the iterator for chunks until the search function | 566 // Keep asking the iterator for chunks until the search function |
| 570 // returns an end value not equal to the length of the string passed to
it. | 567 // returns an end value not equal to the length of the string passed to
it. |
| 571 bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node(
)->renderer()->style()->textSecurity() != TSNONE; | 568 bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node(
)->renderer()->style()->textSecurity() != TSNONE; |
| 572 if (!inTextSecurityMode) | 569 if (!inTextSecurityMode) |
| 573 it.appendTextTo(string); | 570 it.appendTextTo(string); |
| 574 else { | 571 else { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 586 // The last search returned the end of the buffer and asked for more con
text, | 583 // The last search returned the end of the buffer and asked for more con
text, |
| 587 // but there is no further text. Force a search with what's available. | 584 // but there is no further text. Force a search with what's available. |
| 588 next = searchFunction(string.data(), string.size(), prefixLength, DontHa
veMoreContext, needMoreContext); | 585 next = searchFunction(string.data(), string.size(), prefixLength, DontHa
veMoreContext, needMoreContext); |
| 589 ASSERT(!needMoreContext); | 586 ASSERT(!needMoreContext); |
| 590 } | 587 } |
| 591 | 588 |
| 592 if (it.atEnd() && next == string.size()) { | 589 if (it.atEnd() && next == string.size()) { |
| 593 pos = it.startPosition(); | 590 pos = it.startPosition(); |
| 594 } else if (next != invalidOffset && next != prefixLength) { | 591 } else if (next != invalidOffset && next != prefixLength) { |
| 595 // Use the character iterator to translate the next value into a DOM pos
ition. | 592 // Use the character iterator to translate the next value into a DOM pos
ition. |
| 596 CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersB
etweenAllVisiblePositions); | 593 CharacterIterator charIt(searchStart, searchEnd, TextIteratorEmitsCharac
tersBetweenAllVisiblePositions); |
| 597 charIt.advance(next - prefixLength - 1); | 594 charIt.advance(next - prefixLength - 1); |
| 598 pos = charIt.endPosition(); | 595 pos = charIt.endPosition(); |
| 599 | 596 |
| 600 if (charIt.characterAt(0) == '\n') { | 597 if (charIt.characterAt(0) == '\n') { |
| 601 // FIXME: workaround for collapsed range (where only start position
is correct) emitted for some emitted newlines (see rdar://5192593) | 598 // FIXME: workaround for collapsed range (where only start position
is correct) emitted for some emitted newlines (see rdar://5192593) |
| 602 VisiblePosition visPos = VisiblePosition(pos); | 599 VisiblePosition visPos = VisiblePosition(pos); |
| 603 if (visPos == VisiblePosition(charIt.startPosition())) { | 600 if (visPos == VisiblePosition(charIt.startPosition())) { |
| 604 charIt.advance(1); | 601 charIt.advance(1); |
| 605 pos = charIt.startPosition(); | 602 pos = charIt.startPosition(); |
| 606 } | 603 } |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 int caretOffset; | 1403 int caretOffset; |
| 1407 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); | 1404 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); |
| 1408 | 1405 |
| 1409 if (inlineBox) | 1406 if (inlineBox) |
| 1410 renderer = &inlineBox->renderer(); | 1407 renderer = &inlineBox->renderer(); |
| 1411 | 1408 |
| 1412 return renderer->localCaretRect(inlineBox, caretOffset); | 1409 return renderer->localCaretRect(inlineBox, caretOffset); |
| 1413 } | 1410 } |
| 1414 | 1411 |
| 1415 } | 1412 } |
| OLD | NEW |