diff options
author | John Reck <jreck@google.com> | 2012-02-23 13:40:23 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-02-23 13:40:23 -0800 |
commit | 49be9fd5f37bd2633874b9b4236d965933ab24cb (patch) | |
tree | 686962ce413ea8866fd1761114ec26b4e127eba9 /Source/WebCore | |
parent | a5460bb8f4d5cad3f45fad39d1745bf31c2b2dac (diff) | |
parent | 773979f92560dd1aead375c82fd75b584a141e5d (diff) | |
download | external_webkit-49be9fd5f37bd2633874b9b4236d965933ab24cb.zip external_webkit-49be9fd5f37bd2633874b9b4236d965933ab24cb.tar.gz external_webkit-49be9fd5f37bd2633874b9b4236d965933ab24cb.tar.bz2 |
Merge "Support address detection"
Diffstat (limited to 'Source/WebCore')
-rw-r--r-- | Source/WebCore/Android.mk | 1 | ||||
-rw-r--r-- | Source/WebCore/dom/DOMTextContentWalker.cpp | 90 | ||||
-rw-r--r-- | Source/WebCore/dom/DOMTextContentWalker.h | 60 | ||||
-rw-r--r-- | Source/WebCore/editing/TextIterator.cpp | 71 | ||||
-rw-r--r-- | Source/WebCore/editing/TextIterator.h | 22 |
5 files changed, 241 insertions, 3 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index bdf6410..d6c899e 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -124,6 +124,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ dom/DOMImplementation.cpp \ dom/DOMStringList.cpp \ dom/DOMStringMap.cpp \ + dom/DOMTextContentWalker.cpp \ dom/DatasetDOMStringMap.cpp \ dom/DecodedDataDocumentParser.cpp \ dom/DeviceMotionController.cpp \ diff --git a/Source/WebCore/dom/DOMTextContentWalker.cpp b/Source/WebCore/dom/DOMTextContentWalker.cpp new file mode 100644 index 0000000..ccbe1ec --- /dev/null +++ b/Source/WebCore/dom/DOMTextContentWalker.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DOMTextContentWalker.h" + +#if OS(ANDROID) + +#include "Range.h" +#include "TextIterator.h" +#include "VisiblePosition.h" +#include "VisibleSelection.h" +#include "visible_units.h" + +namespace WebCore { + +static PassRefPtr<Range> getRange(const Position& start, const Position& end) +{ + return VisibleSelection(start.parentAnchoredEquivalent(), end.parentAnchoredEquivalent(), DOWNSTREAM).firstRange(); +} + +DOMTextContentWalker::DOMTextContentWalker(const VisiblePosition& position, unsigned maxLength) + : m_hitOffsetInContent(0) +{ + const unsigned halfMaxLength = maxLength / 2; + CharacterIterator forwardChar(makeRange(position, endOfDocument(position)).get(), TextIteratorStopsOnFormControls); + forwardChar.advance(maxLength - halfMaxLength); + + // No forward contents, started inside form control. + RefPtr<Range> range = getRange(position.deepEquivalent(), forwardChar.range()->startPosition()); + if (!range.get() || range->text().length() == 0) + return; + + BackwardsCharacterIterator backwardsChar(makeRange(startOfDocument(position), position).get(), TextIteratorStopsOnFormControls); + backwardsChar.advance(halfMaxLength); + + m_hitOffsetInContent = getRange(backwardsChar.range()->endPosition(), position.deepEquivalent())->text().length(); + m_contentRange = getRange(backwardsChar.range()->endPosition(), forwardChar.range()->startPosition()); +} + +PassRefPtr<Range> DOMTextContentWalker::contentOffsetsToRange(unsigned startInContent, unsigned endInContent) +{ + if (startInContent >= endInContent || endInContent > content().length()) + return 0; + + CharacterIterator iterator(m_contentRange.get()); + iterator.advance(startInContent); + + Position start = iterator.range()->startPosition(); + iterator.advance(endInContent - startInContent); + Position end = iterator.range()->startPosition(); + return getRange(start, end); +} + +String DOMTextContentWalker::content() const +{ + if (m_contentRange) + return m_contentRange->text(); + return String(); +} + +unsigned DOMTextContentWalker::hitOffsetInContent() const +{ + return m_hitOffsetInContent; +} + +} // namespace WebCore + +#endif // OS(ANDROID) diff --git a/Source/WebCore/dom/DOMTextContentWalker.h b/Source/WebCore/dom/DOMTextContentWalker.h new file mode 100644 index 0000000..0d4259b --- /dev/null +++ b/Source/WebCore/dom/DOMTextContentWalker.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DOMTextContentWalker_h +#define DOMTextContentWalker_h + +#if OS(ANDROID) + +#include "PlatformString.h" + +namespace WebCore { + +class Range; +class VisiblePosition; + +// Explore the DOM tree to find the text contents up to a limit +// around a position in a given text node. +class DOMTextContentWalker { + WTF_MAKE_NONCOPYABLE(DOMTextContentWalker); +public: + DOMTextContentWalker(const VisiblePosition& position, unsigned maxLength); + + String content() const; + unsigned hitOffsetInContent() const; + + // Convert start/end positions in the content text string into a text range. + PassRefPtr<Range> contentOffsetsToRange(unsigned startInContent, unsigned endInContent); + +private: + RefPtr<Range> m_contentRange; + size_t m_hitOffsetInContent; +}; + +} // namespace WebCore + +#endif // OS(ANDROID) + +#endif // DOMTextContentWalker_h + diff --git a/Source/WebCore/editing/TextIterator.cpp b/Source/WebCore/editing/TextIterator.cpp index c3be277..3aa68af 100644 --- a/Source/WebCore/editing/TextIterator.cpp +++ b/Source/WebCore/editing/TextIterator.cpp @@ -239,6 +239,20 @@ static void setUpFullyClippedStack(BitStack& stack, Node* node) ASSERT(stack.size() == 1 + depthCrossingShadowBoundaries(node)); } +#if OS(ANDROID) +static bool checkFormControlElement(Node* startNode) +{ + Node* node = startNode; + while (node) { + if (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()) + return true; + node = node->parentNode(); + } + return false; +} +#endif + + // -------- TextIterator::TextIterator() @@ -258,6 +272,10 @@ TextIterator::TextIterator() , m_handledFirstLetter(false) , m_ignoresStyleVisibility(false) , m_emitsObjectReplacementCharacters(false) +#if OS(ANDROID) + , m_stopsOnFormControls(false) + , m_shouldStop(false) +#endif { } @@ -277,6 +295,10 @@ TextIterator::TextIterator(const Range* r, TextIteratorBehavior behavior) , m_handledFirstLetter(false) , m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility) , m_emitsObjectReplacementCharacters(behavior & TextIteratorEmitsObjectReplacementCharacters) +#if OS(ANDROID) + , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls) + , m_shouldStop(false) +#endif { if (!r) return; @@ -334,8 +356,21 @@ TextIterator::~TextIterator() { } +bool TextIterator::atEnd() const +{ +#if OS(ANDROID) + return !m_positionNode || m_shouldStop; +#else + return !m_positionNode; +#endif +} + void TextIterator::advance() { +#if OS(ANDROID) + if (m_shouldStop) + return; +#endif // reset the run information m_positionNode = 0; m_textLength = 0; @@ -368,6 +403,10 @@ void TextIterator::advance() } while (m_node && m_node != m_pastEndNode) { +#if OS(ANDROID) + if (!m_shouldStop && m_stopsOnFormControls && checkFormControlElement(m_node)) + m_shouldStop = true; +#endif // if the range ends at offset 0 of an element, represent the // position, but not the content, of that element e.g. if the // node is a blockflow element, emit a newline that @@ -1034,6 +1073,10 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator() : m_behavior(TextIteratorDefaultBehavior) , m_node(0) , m_positionNode(0) +#if OS(ANDROID) + , m_stopsOnFormControls(false) + , m_shouldStop(false) +#endif { } @@ -1041,8 +1084,16 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, : m_behavior(behavior) , m_node(0) , m_positionNode(0) +#if OS(ANDROID) + , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls) + , m_shouldStop(false) +#endif { +#if OS(ANDROID) + ASSERT(m_behavior == TextIteratorDefaultBehavior || m_behavior == TextIteratorStopsOnFormControls); +#else ASSERT(m_behavior == TextIteratorDefaultBehavior); +#endif if (!r) return; @@ -1091,10 +1142,30 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, advance(); } +bool SimplifiedBackwardsTextIterator::atEnd() const +{ +#if OS(ANDROID) + return !m_positionNode || m_shouldStop; +#else + return !m_positionNode; +#endif +} + void SimplifiedBackwardsTextIterator::advance() { ASSERT(m_positionNode); +#if OS(ANDROID) + if (m_shouldStop) + return; + + // Prevent changing the iterator position if a form control element was found and advance should stop on it. + if (m_stopsOnFormControls && checkFormControlElement(m_node)) { + m_shouldStop = true; + return; + } +#endif + m_positionNode = 0; m_textLength = 0; diff --git a/Source/WebCore/editing/TextIterator.h b/Source/WebCore/editing/TextIterator.h index 9fe4ceb..c4fc264 100644 --- a/Source/WebCore/editing/TextIterator.h +++ b/Source/WebCore/editing/TextIterator.h @@ -42,7 +42,10 @@ enum TextIteratorBehavior { TextIteratorEntersTextControls = 1 << 1, TextIteratorEmitsTextsWithoutTranscoding = 1 << 2, TextIteratorIgnoresStyleVisibility = 1 << 3, - TextIteratorEmitsObjectReplacementCharacters = 1 << 4 + TextIteratorEmitsObjectReplacementCharacters = 1 << 4, +#if OS(ANDROID) + TextIteratorStopsOnFormControls = 1 << 6 +#endif }; // FIXME: Can't really answer this question correctly without knowing the white-space mode. @@ -88,7 +91,7 @@ public: ~TextIterator(); explicit TextIterator(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior); - bool atEnd() const { return !m_positionNode; } + bool atEnd() const; void advance(); int length() const { return m_textLength; } @@ -182,6 +185,12 @@ private: bool m_ignoresStyleVisibility; // Used when emitting the special 0xFFFC character is required. bool m_emitsObjectReplacementCharacters; +#if OS(ANDROID) + // Used when the iteration should stop if form controls are reached. + bool m_stopsOnFormControls; + // Used when m_stopsOnFormControls is set to determine if the iterator should keep advancing. + bool m_shouldStop; +#endif }; // Iterates through the DOM range, returning all the text, and 0-length boundaries @@ -192,7 +201,7 @@ public: SimplifiedBackwardsTextIterator(); explicit SimplifiedBackwardsTextIterator(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior); - bool atEnd() const { return !m_positionNode; } + bool atEnd() const; void advance(); int length() const { return m_textLength; } @@ -240,6 +249,13 @@ private: // Whether m_node has advanced beyond the iteration range (i.e. m_startNode). bool m_havePassedStartNode; + +#if OS(ANDROID) + // Used when the iteration should stop if form controls are reached. + bool m_stopsOnFormControls; + // Used when m_stopsOnFormControls is set to determine if the iterator should keep advancing. + bool m_shouldStop; +#endif }; // Builds on the text iterator, adding a character position so we can walk one |