diff options
Diffstat (limited to 'Source/WebCore/editing/TextIterator.cpp')
-rw-r--r-- | Source/WebCore/editing/TextIterator.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/Source/WebCore/editing/TextIterator.cpp b/Source/WebCore/editing/TextIterator.cpp index 1b25c87..c3be277 100644 --- a/Source/WebCore/editing/TextIterator.cpp +++ b/Source/WebCore/editing/TextIterator.cpp @@ -28,6 +28,7 @@ #include "TextIterator.h" #include "Document.h" +#include "Frame.h" #include "HTMLElement.h" #include "HTMLNames.h" #include "htmlediting.h" @@ -256,6 +257,7 @@ TextIterator::TextIterator() , m_emitsTextWithoutTranscoding(false) , m_handledFirstLetter(false) , m_ignoresStyleVisibility(false) + , m_emitsObjectReplacementCharacters(false) { } @@ -274,6 +276,7 @@ TextIterator::TextIterator(const Range* r, TextIteratorBehavior behavior) , m_emitsTextWithoutTranscoding(behavior & TextIteratorEmitsTextsWithoutTranscoding) , m_handledFirstLetter(false) , m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility) + , m_emitsObjectReplacementCharacters(behavior & TextIteratorEmitsObjectReplacementCharacters) { if (!r) return; @@ -638,6 +641,11 @@ bool TextIterator::handleReplacedElement() m_hasEmitted = true; + if (m_emitsObjectReplacementCharacters && renderer && renderer->isReplaced()) { + emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node, 0, 1); + return true; + } + if (m_emitsCharactersBetweenAllVisiblePositions) { // We want replaced elements to behave like punctuation for boundary // finding, and to simply take up space for the selection preservation @@ -2369,6 +2377,38 @@ PassRefPtr<Range> TextIterator::rangeFromLocationAndLength(Element* scope, int r return resultRange.release(); } +bool TextIterator::locationAndLengthFromRange(const Range* range, size_t& location, size_t& length) +{ + location = notFound; + length = 0; + + if (!range->startContainer()) + return false; + + Element* selectionRoot = range->ownerDocument()->frame()->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : range->ownerDocument()->documentElement(); + + // The critical assumption is that this only gets called with ranges that + // concentrate on a given area containing the selection root. This is done + // because of text fields and textareas. The DOM for those is not + // directly in the document DOM, so ensure that the range does not cross a + // boundary of one of those. + if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope)) + return false; + if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope)) + return false; + + RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset()); + ASSERT(testRange->startContainer() == scope); + location = TextIterator::rangeLength(testRange.get()); + + ExceptionCode ec; + testRange->setEnd(range->endContainer(), range->endOffset(), ec); + ASSERT(testRange->startContainer() == scope); + length = TextIterator::rangeLength(testRange.get()) - location; + return true; +} + // -------- UChar* plainTextToMallocAllocatedBuffer(const Range* r, unsigned& bufferLength, bool isDisplayString, TextIteratorBehavior defaultBehavior) |