diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/editing/TextIterator.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/editing/TextIterator.cpp | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp b/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp index a1b3bc578..f82a9726c 100644 --- a/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp +++ b/src/3rdparty/webkit/WebCore/editing/TextIterator.cpp @@ -57,7 +57,7 @@ using namespace HTMLNames; // Keeps enough of the previous text to be able to search in the future, but no more. // Non-breaking spaces are always equal to normal spaces. // Case folding is also done if <isCaseSensitive> is false. -class SearchBuffer : Noncopyable { +class SearchBuffer : public Noncopyable { public: SearchBuffer(const String& target, bool isCaseSensitive); ~SearchBuffer(); @@ -1393,8 +1393,40 @@ const UChar* WordAwareIterator::characters() const // -------- +static inline UChar foldQuoteMark(UChar c) +{ + switch (c) { + case hebrewPunctuationGershayim: + case leftDoubleQuotationMark: + case rightDoubleQuotationMark: + return '"'; + case hebrewPunctuationGeresh: + case leftSingleQuotationMark: + case rightSingleQuotationMark: + return '\''; + default: + return c; + } +} + +static inline void foldQuoteMarks(String& s) +{ + s.replace(hebrewPunctuationGeresh, '\''); + s.replace(hebrewPunctuationGershayim, '"'); + s.replace(leftDoubleQuotationMark, '"'); + s.replace(leftSingleQuotationMark, '\''); + s.replace(rightDoubleQuotationMark, '"'); + s.replace(rightSingleQuotationMark, '\''); +} + #if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION +static inline void foldQuoteMarks(UChar* data, size_t length) +{ + for (size_t i = 0; i < length; ++i) + data[i] = foldQuoteMark(data[i]); +} + static const size_t minimumSearchBufferSize = 8192; #ifndef NDEBUG @@ -1408,7 +1440,7 @@ static UStringSearch* createSearcher() // without setting both the pattern and the text. UErrorCode 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); + ASSERT(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING || status == U_USING_DEFAULT_WARNING); return searcher; } @@ -1440,7 +1472,12 @@ inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive) { ASSERT(!m_target.isEmpty()); - size_t targetLength = target.length(); + // FIXME: We'd like to tailor the searcher to fold quote marks for us instead + // of doing it in a separate replacement pass here, but ICU doesn't offer a way + // to add tailoring on top of the locale-specific tailoring as of this writing. + foldQuoteMarks(m_target); + + size_t targetLength = m_target.length(); m_buffer.reserveInitialCapacity(max(targetLength * 8, minimumSearchBufferSize)); m_overlap = m_buffer.capacity() / 4; @@ -1480,9 +1517,11 @@ inline size_t SearchBuffer::append(const UChar* characters, size_t length) m_buffer.shrink(m_overlap); } - size_t usableLength = min(m_buffer.capacity() - m_buffer.size(), length); + size_t oldLength = m_buffer.size(); + size_t usableLength = min(m_buffer.capacity() - oldLength, length); ASSERT(usableLength); m_buffer.append(characters, usableLength); + foldQuoteMarks(m_buffer.data() + oldLength, usableLength); return usableLength; } @@ -1549,6 +1588,7 @@ inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive) { ASSERT(!m_target.isEmpty()); m_target.replace(noBreakSpace, ' '); + foldQuoteMarks(m_target); } inline SearchBuffer::~SearchBuffer() @@ -1568,7 +1608,7 @@ inline bool SearchBuffer::atBreak() const inline void SearchBuffer::append(UChar c, bool isStart) { - m_buffer[m_cursor] = c == noBreakSpace ? ' ' : c; + m_buffer[m_cursor] = c == noBreakSpace ? ' ' : foldQuoteMark(c); m_isCharacterStartBuffer[m_cursor] = isStart; if (++m_cursor == m_target.length()) { m_cursor = 0; @@ -1875,11 +1915,6 @@ tryAgain: PassRefPtr<Range> findPlainText(const Range* range, const String& target, bool forward, bool caseSensitive) { - // We can't search effectively for a string that's entirely made of collapsible - // whitespace, so we won't even try. This also takes care of the empty string case. - if (isAllCollapsibleWhitespace(target)) - return collapsedToBoundary(range, forward); - // First, find the text. size_t matchStart; size_t matchLength; |