Index: Source/WebCore/editing/TextIterator.cpp |
=================================================================== |
--- Source/WebCore/editing/TextIterator.cpp (revision 93498) |
+++ Source/WebCore/editing/TextIterator.cpp (working copy) |
@@ -603,21 +603,30 @@ |
} |
} |
+static inline RenderText* firstRenderTextInFirstLetter(RenderObject* firstLetter) |
+{ |
+ if (!firstLetter) |
+ return 0; |
+ |
+ // FIXME: Should this check descendent objects? |
+ for (RenderObject* current = firstLetter->firstChild(); current; current = current->nextSibling()) { |
+ if (current->isText()) |
+ return toRenderText(current); |
+ } |
+ return 0; |
+} |
+ |
void TextIterator::handleTextNodeFirstLetter(RenderTextFragment* renderer) |
{ |
if (renderer->firstLetter()) { |
RenderObject* r = renderer->firstLetter(); |
if (r->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) |
return; |
- for (RenderObject *currChild = r->firstChild(); currChild; currChild->nextSibling()) { |
- if (currChild->isText()) { |
- RenderText* firstLetter = toRenderText(currChild); |
- m_handledFirstLetter = true; |
- m_remainingTextBox = m_textBox; |
- m_textBox = firstLetter->firstTextBox(); |
- m_firstLetterText = firstLetter; |
- return; |
- } |
+ if (RenderText* firstLetter = firstRenderTextInFirstLetter(r)) { |
+ m_handledFirstLetter = true; |
+ m_remainingTextBox = m_textBox; |
+ m_textBox = firstLetter->firstTextBox(); |
+ m_firstLetterText = firstLetter; |
} |
} |
m_handledFirstLetter = true; |
@@ -1043,14 +1052,46 @@ |
SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator() |
: m_behavior(TextIteratorDefaultBehavior) |
, m_node(0) |
+ , m_offset(0) |
+ , m_handledNode(false) |
+ , m_handledChildren(false) |
+ , m_startNode(0) |
+ , m_startOffset(0) |
+ , m_endNode(0) |
+ , m_endOffset(0) |
, m_positionNode(0) |
+ , m_positionStartOffset(0) |
+ , m_positionEndOffset(0) |
+ , m_textCharacters(0) |
+ , m_textLength(0) |
+ , m_lastTextNode(0) |
+ , m_lastCharacter(0) |
+ , m_singleCharacterBuffer(0) |
+ , m_havePassedStartNode(false) |
+ , m_shouldHandleFirstLetter(false) |
{ |
} |
SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, TextIteratorBehavior behavior) |
: m_behavior(behavior) |
, m_node(0) |
+ , m_offset(0) |
+ , m_handledNode(false) |
+ , m_handledChildren(false) |
+ , m_startNode(0) |
+ , m_startOffset(0) |
+ , m_endNode(0) |
+ , m_endOffset(0) |
, m_positionNode(0) |
+ , m_positionStartOffset(0) |
+ , m_positionEndOffset(0) |
+ , m_textCharacters(0) |
+ , m_textLength(0) |
+ , m_lastTextNode(0) |
+ , m_lastCharacter(0) |
+ , m_singleCharacterBuffer(0) |
+ , m_havePassedStartNode(false) |
+ , m_shouldHandleFirstLetter(false) |
{ |
ASSERT(m_behavior == TextIteratorDefaultBehavior); |
@@ -1178,25 +1219,64 @@ |
{ |
m_lastTextNode = m_node; |
- RenderText* renderer = toRenderText(m_node->renderer()); |
- String str = renderer->text(); |
+ int startOffset; |
+ int offsetInNode; |
+ RenderText* renderer = handleFirstLetter(startOffset, offsetInNode); |
+ if (!renderer) |
+ return true; |
- if (!renderer->firstTextBox() && str.length() > 0) |
+ String text = renderer->text(); |
+ if (!renderer->firstTextBox() && text.length() > 0) |
return true; |
m_positionEndOffset = m_offset; |
- |
- m_offset = (m_node == m_startNode) ? m_startOffset : 0; |
+ m_offset = startOffset + offsetInNode; |
m_positionNode = m_node; |
m_positionStartOffset = m_offset; |
+ |
+ ASSERT(0 <= m_positionStartOffset - offsetInNode && m_positionStartOffset - offsetInNode <= static_cast<int>(text.length())); |
+ ASSERT(1 <= m_positionEndOffset - offsetInNode && m_positionEndOffset - offsetInNode <= static_cast<int>(text.length())); |
+ ASSERT(m_positionStartOffset <= m_positionEndOffset); |
+ |
m_textLength = m_positionEndOffset - m_positionStartOffset; |
- m_textCharacters = str.characters() + m_positionStartOffset; |
+ m_textCharacters = text.characters() + (m_positionStartOffset - offsetInNode); |
+ ASSERT(m_textCharacters >= text.characters()); |
+ ASSERT(m_textCharacters + m_textLength <= text.characters() + static_cast<int>(text.length())); |
- m_lastCharacter = str[m_positionEndOffset - 1]; |
+ m_lastCharacter = text[m_positionEndOffset - 1]; |
- return true; |
+ return !m_shouldHandleFirstLetter; |
} |
+RenderText* SimplifiedBackwardsTextIterator::handleFirstLetter(int& startOffset, int& offsetInNode) |
+{ |
+ RenderText* renderer = toRenderText(m_node->renderer()); |
+ startOffset = (m_node == m_startNode) ? m_startOffset : 0; |
+ |
+ if (!renderer->isTextFragment()) { |
+ offsetInNode = 0; |
+ return renderer; |
+ } |
+ |
+ RenderTextFragment* fragment = toRenderTextFragment(renderer); |
+ int offsetAfterFirstLetter = fragment->start(); |
+ if (startOffset >= offsetAfterFirstLetter) { |
+ ASSERT(!m_shouldHandleFirstLetter); |
+ offsetInNode = offsetAfterFirstLetter; |
+ return renderer; |
+ } |
+ |
+ if (!m_shouldHandleFirstLetter && offsetAfterFirstLetter < m_offset) { |
+ m_shouldHandleFirstLetter = true; |
+ offsetInNode = offsetAfterFirstLetter; |
+ return renderer; |
+ } |
+ |
+ m_shouldHandleFirstLetter = false; |
+ offsetInNode = 0; |
+ return firstRenderTextInFirstLetter(fragment->firstLetter()); |
+} |
+ |
bool SimplifiedBackwardsTextIterator::handleReplacedElement() |
{ |
unsigned index = m_node->nodeIndex(); |