summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/editing/TextIterator.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/editing/TextIterator.cpp96
1 files changed, 56 insertions, 40 deletions
diff --git a/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp b/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp
index aee34df72f..a1b3bc578b 100644
--- a/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp
+++ b/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp
@@ -42,6 +42,7 @@
#include "visible_units.h"
#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
+#include "TextBreakIteratorInternalICU.h"
#include <unicode/usearch.h>
#endif
@@ -143,7 +144,7 @@ unsigned BitStack::size() const
// --------
-static inline Node* parentOrShadowParent(Node* node)
+static inline Node* parentCrossingShadowBoundaries(Node* node)
{
if (Node* parent = node->parentNode())
return parent;
@@ -155,20 +156,50 @@ static inline Node* parentOrShadowParent(Node* node)
static unsigned depthCrossingShadowBoundaries(Node* node)
{
unsigned depth = 0;
- for (Node* parent = parentOrShadowParent(node); parent; parent = parentOrShadowParent(parent))
+ for (Node* parent = parentCrossingShadowBoundaries(node); parent; parent = parentCrossingShadowBoundaries(parent))
++depth;
return depth;
}
#endif
+// This function is like Range::pastLastNode, except for the fact that it can climb up out of shadow trees.
+static Node* nextInPreOrderCrossingShadowBoundaries(Node* rangeEndContainer, int rangeEndOffset)
+{
+ if (!rangeEndContainer)
+ return 0;
+ if (rangeEndOffset >= 0 && !rangeEndContainer->offsetInCharacters()) {
+ if (Node* next = rangeEndContainer->childNode(rangeEndOffset))
+ return next;
+ }
+ for (Node* node = rangeEndContainer; node; node = parentCrossingShadowBoundaries(node)) {
+ if (Node* next = node->nextSibling())
+ return next;
+ }
+ return 0;
+}
+
+static Node* previousInPostOrderCrossingShadowBoundaries(Node* rangeStartContainer, int rangeStartOffset)
+{
+ if (!rangeStartContainer)
+ return 0;
+ if (rangeStartOffset > 0 && !rangeStartContainer->offsetInCharacters()) {
+ if (Node* previous = rangeStartContainer->childNode(rangeStartOffset - 1))
+ return previous;
+ }
+ for (Node* node = rangeStartContainer; node; node = parentCrossingShadowBoundaries(node)) {
+ if (Node* previous = node->previousSibling())
+ return previous;
+ }
+ return 0;
+}
+
+// --------
+
static inline bool fullyClipsContents(Node* node)
{
RenderObject* renderer = node->renderer();
- if (!renderer || !renderer->isBox())
- return false;
- RenderStyle* style = renderer->style();
- if (style->overflowX() == OVISIBLE && style->overflowY() == OVISIBLE)
+ if (!renderer || !renderer->isBox() || !renderer->hasOverflowClip())
return false;
return toRenderBox(renderer)->size().isEmpty();
}
@@ -195,7 +226,7 @@ static void setUpFullyClippedStack(BitStack& stack, Node* node)
{
// Put the nodes in a vector so we can iterate in reverse order.
Vector<Node*, 100> ancestry;
- for (Node* parent = parentOrShadowParent(node); parent; parent = parentOrShadowParent(parent))
+ for (Node* parent = parentCrossingShadowBoundaries(node); parent; parent = parentCrossingShadowBoundaries(parent))
ancestry.append(parent);
// Call pushFullyClippedState on each node starting with the earliest ancestor.
@@ -265,7 +296,7 @@ TextIterator::TextIterator(const Range* r, bool emitCharactersBetweenAllVisibleP
m_handledChildren = false;
// calculate first out of bounds node
- m_pastEndNode = r->pastLastNode();
+ m_pastEndNode = nextInPreOrderCrossingShadowBoundaries(endContainer, endOffset);
// initialize node processing state
m_needAnotherNewline = false;
@@ -352,14 +383,14 @@ void TextIterator::advance()
next = m_node->nextSibling();
if (!next) {
bool pastEnd = m_node->traverseNextNode() == m_pastEndNode;
- Node* parentNode = parentOrShadowParent(m_node);
+ Node* parentNode = parentCrossingShadowBoundaries(m_node);
while (!next && parentNode) {
if ((pastEnd && parentNode == m_endContainer) || m_endContainer->isDescendantOf(parentNode))
return;
bool haveRenderer = m_node->renderer();
m_node = parentNode;
m_fullyClippedStack.pop();
- parentNode = parentOrShadowParent(m_node);
+ parentNode = parentCrossingShadowBoundaries(m_node);
if (haveRenderer)
exitNode();
if (m_positionNode) {
@@ -883,14 +914,14 @@ Node* TextIterator::node() const
// --------
-SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator() : m_positionNode(0)
+SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator()
+ : m_positionNode(0)
{
}
SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r)
+ : m_positionNode(0)
{
- m_positionNode = 0;
-
if (!r)
return;
@@ -932,15 +963,8 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r)
m_lastTextNode = 0;
m_lastCharacter = '\n';
-
- if (startOffset == 0 || !startNode->firstChild()) {
- m_pastStartNode = startNode->previousSibling();
- while (!m_pastStartNode && startNode->parentNode()) {
- startNode = startNode->parentNode();
- m_pastStartNode = startNode->previousSibling();
- }
- } else
- m_pastStartNode = startNode->childNode(startOffset - 1);
+
+ m_pastStartNode = previousInPostOrderCrossingShadowBoundaries(startNode, startOffset);
advance();
}
@@ -987,7 +1011,7 @@ void SimplifiedBackwardsTextIterator::advance()
// Exit all other containers.
next = m_node->previousSibling();
while (!next) {
- Node* parentNode = parentOrShadowParent(m_node);
+ Node* parentNode = parentCrossingShadowBoundaries(m_node);
if (!parentNode)
break;
m_node = parentNode;
@@ -1053,26 +1077,22 @@ bool SimplifiedBackwardsTextIterator::handleNonTextNode()
{
// We can use a linefeed in place of a tab because this simple iterator is only used to
// find boundaries, not actual content. A linefeed breaks words, sentences, and paragraphs.
- if (shouldEmitNewlineForNode(m_node) ||
- shouldEmitNewlineAfterNode(m_node) ||
- shouldEmitTabBeforeNode(m_node)) {
+ if (shouldEmitNewlineForNode(m_node) || shouldEmitNewlineAfterNode(m_node) || shouldEmitTabBeforeNode(m_node)) {
unsigned index = m_node->nodeIndex();
- // The start of this emitted range is wrong, ensuring correctness would require
- // VisiblePositions and so would be slow. previousBoundary expects this.
+ // The start of this emitted range is wrong. Ensuring correctness would require
+ // VisiblePositions and so would be slow. previousBoundary expects this.
emitCharacter('\n', m_node->parentNode(), index + 1, index + 1);
}
-
return true;
}
void SimplifiedBackwardsTextIterator::exitNode()
{
- if (shouldEmitNewlineForNode(m_node) ||
- shouldEmitNewlineBeforeNode(m_node) ||
- shouldEmitTabBeforeNode(m_node))
- // The start of this emitted range is wrong, ensuring correctness would require
- // VisiblePositions and so would be slow. previousBoundary expects this.
+ if (shouldEmitNewlineForNode(m_node) || shouldEmitNewlineBeforeNode(m_node) || shouldEmitTabBeforeNode(m_node)) {
+ // The start of this emitted range is wrong. Ensuring correctness would require
+ // VisiblePositions and so would be slow. previousBoundary expects this.
emitCharacter('\n', m_node, 0, 0);
+ }
}
void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int startOffset, int endOffset)
@@ -1386,13 +1406,9 @@ static UStringSearch* createSearcher()
// Provide a non-empty pattern and non-empty text so usearch_open will not fail,
// but it doesn't matter exactly what it is, since we don't perform any searches
// without setting both the pattern and the text.
-
- // Pass empty string for the locale for now to get the Unicode Collation Algorithm,
- // rather than something locale-specific.
-
UErrorCode status = U_ZERO_ERROR;
- UStringSearch* searcher = usearch_open(&newlineCharacter, 1, &newlineCharacter, 1, "", 0, &status);
- ASSERT(status == U_ZERO_ERROR);
+ UStringSearch* searcher = usearch_open(&newlineCharacter, 1, &newlineCharacter, 1, currentSearchLocaleID(), 0, &status);
+ ASSERT(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING);
return searcher;
}