blob: f3d72ea02550749602368ad96424f0a8060ea80d [file] [log] [blame]
/*
* Copyright (C) 2004, 2006, 2009 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
* 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 THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_SIMPLIFIED_BACKWARDS_TEXT_ITERATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_SIMPLIFIED_BACKWARDS_TEXT_ITERATOR_H_
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h"
#include "third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
class LayoutText;
// Iterates through the DOM range, returning all the text, and 0-length
// boundaries at points where replaced elements break up the text flow. The text
// comes back in chunks so as to optimize for performance of the iteration.
template <typename Strategy>
class SimplifiedBackwardsTextIteratorAlgorithm {
STACK_ALLOCATED();
public:
// Note: Usage of |behavior| should be limited, e.g.
// - EmitsObjectReplacementCharacter
// - StopsOnFormControls
// Please ask editing-dev if you want to use other behaviors.
SimplifiedBackwardsTextIteratorAlgorithm(
const EphemeralRangeTemplate<Strategy>&,
const TextIteratorBehavior& = TextIteratorBehavior());
bool AtEnd() const { return !text_state_.PositionNode() || should_stop_; }
void Advance();
int length() const { return text_state_.length(); }
// Note: |characterAt()| returns characters in the reversed order, since
// the iterator is backwards. For example, if the current text is "abc",
// then |characterAt(0)| returns 'c'.
UChar CharacterAt(unsigned index) const;
const Node* GetNode() const { return node_; }
// Calculate the minimum |actualLength >= minLength| such that code units
// with offset range [position, position + actualLength) are whole code
// points. Prepend these code points to |output| and return |actualLength|.
int CopyTextTo(BackwardsTextBuffer* output,
int position,
int min_length) const;
int CopyTextTo(BackwardsTextBuffer* output, int position = 0) const;
// TODO(editing-dev): We should consider code sharing between |TextIterator|
// and |SimplifiedBackwardsTextIterator| for
// - StartContainer()
// - EndOffset()
// - StartContainer()
// - EndPosition()
// TODO(editing-dev): We should rename |StartContainer()| to
// |CurrentContainer()| as |TextIterator|.
const Node* StartContainer() const;
int EndOffset() const;
PositionTemplate<Strategy> StartPosition() const;
PositionTemplate<Strategy> EndPosition() const;
private:
void Init(const Node* start_node,
const Node* end_node,
int start_offset,
int end_offset);
void ExitNode();
bool HandleTextNode();
LayoutText* HandleFirstLetter(int& start_offset, int& offset_in_node);
bool HandleReplacedElement();
bool HandleNonTextNode();
bool AdvanceRespectingRange(const Node*);
bool IsBetweenSurrogatePair(int position) const;
// TODO(editing-dev): We should consider code sharing between |TextIterator|
// and |SimplifiedBackwardsTextIterator| for
// - EnsurePositionContainer()
// - StartOffset()
void EnsurePositionContainer() const;
int StartOffset() const;
TextIteratorBehavior behavior_;
// Contains state of emitted text.
TextIteratorTextState text_state_;
// Current position, not necessarily of the text being returned, but position
// as we walk through the DOM tree.
Member<const Node> node_;
int offset_;
bool handled_node_;
bool handled_children_;
FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_;
// End of the range.
Member<const Node> start_node_;
int start_offset_;
// Start of the range.
Member<const Node> end_node_;
int end_offset_;
// Whether |node_| has advanced beyond the iteration range (i.e. start_node_).
bool have_passed_start_node_;
// Should handle first-letter layoutObject in the next call to handleTextNode.
bool should_handle_first_letter_;
// Used when behavior_.StopOnFormControls() is true to determine if the
// iterator should keep advancing.
bool should_stop_;
};
extern template class CORE_EXTERN_TEMPLATE_EXPORT
SimplifiedBackwardsTextIteratorAlgorithm<EditingStrategy>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
SimplifiedBackwardsTextIteratorAlgorithm<EditingInFlatTreeStrategy>;
using SimplifiedBackwardsTextIterator =
SimplifiedBackwardsTextIteratorAlgorithm<EditingStrategy>;
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_SIMPLIFIED_BACKWARDS_TEXT_ITERATOR_H_