summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/editing/TextIterator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/editing/TextIterator.cpp')
-rw-r--r--Source/WebCore/editing/TextIterator.cpp40
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)