Commit c8070f46 authored by xiaochengh's avatar xiaochengh Committed by Commit Bot

Reorganize member initialization code of TextIterator

This patch reorganizes the initialization of TextIterator for better code
health.

1. Members originally initialized in the function body of TextIterator::ctor
   are changed to be initialized in the initialization list. Some wrapper
   functions are created for members with non-trivial initialization.
   - start_container_
   - start_offset_
   - end_container_
   - end_offset_
   - end_node_
   - past_end_node_
   - node_
   - iteration_progress_
   - shadow_depth_

2. Members with trivial initialization are initialized in class declaration
   instead of ctor:
   - needs_another_new_line_
   - needs_handle_replaced_element_
   - should_stop_
   - handle_shadow_root_

BUG=721957
TEST=n/a; no behavioral change

Review-Url: https://codereview.chromium.org/2921483002
Cr-Commit-Position: refs/heads/master@{#476393}
parent 9bf01e4d
...@@ -85,6 +85,24 @@ static bool NotSkipping(const Node& node) { ...@@ -85,6 +85,24 @@ static bool NotSkipping(const Node& node) {
(node.IsShadowRoot() && node.OwnerShadowHost()->GetLayoutObject()); (node.IsShadowRoot() && node.OwnerShadowHost()->GetLayoutObject());
} }
template <typename Strategy>
Node* StartNode(Node* start_container, int start_offset) {
if (start_container->IsCharacterDataNode())
return start_container;
if (Node* child = Strategy::ChildAt(*start_container, start_offset))
return child;
if (!start_offset)
return start_container;
return Strategy::NextSkippingChildren(*start_container);
}
template <typename Strategy>
Node* EndNode(const Node& end_container, int end_offset) {
if (!end_container.IsCharacterDataNode() && end_offset > 0)
return Strategy::ChildAt(end_container, end_offset - 1);
return nullptr;
}
// This function is like Range::pastLastNode, except for the fact that it can // This function is like Range::pastLastNode, except for the fact that it can
// climb up out of shadow trees and ignores all nodes that will be skipped in // climb up out of shadow trees and ignores all nodes that will be skipped in
// |advance()|. // |advance()|.
...@@ -144,7 +162,6 @@ bool IsRenderedAsTable(const Node* node) { ...@@ -144,7 +162,6 @@ bool IsRenderedAsTable(const Node* node) {
} // namespace } // namespace
// TODO(xiaochengh): Most members should be initialized in-place, not here.
template <typename Strategy> template <typename Strategy>
TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm( TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm(
const EphemeralRangeTemplate<Strategy>& range, const EphemeralRangeTemplate<Strategy>& range,
...@@ -158,20 +175,21 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm( ...@@ -158,20 +175,21 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm(
const PositionTemplate<Strategy>& start, const PositionTemplate<Strategy>& start,
const PositionTemplate<Strategy>& end, const PositionTemplate<Strategy>& end,
const TextIteratorBehavior& behavior) const TextIteratorBehavior& behavior)
: start_container_(nullptr), : start_container_(start.ComputeContainerNode()),
start_offset_(0), start_offset_(start.ComputeOffsetInContainerNode()),
end_container_(nullptr), end_container_(end.ComputeContainerNode()),
end_offset_(0), end_offset_(end.ComputeOffsetInContainerNode()),
needs_another_newline_(false), end_node_(EndNode<Strategy>(*end_container_, end_offset_)),
needs_handle_replaced_element_(false), past_end_node_(PastLastNode<Strategy>(*end_container_, end_offset_)),
last_text_node_(nullptr), node_(StartNode<Strategy>(start_container_, start_offset_)),
iteration_progress_(kHandledNone),
shadow_depth_(
ShadowDepthOf<Strategy>(*start_container_, *end_container_)),
behavior_(AdjustBehaviorFlags<Strategy>(behavior)), behavior_(AdjustBehaviorFlags<Strategy>(behavior)),
should_stop_(false),
handle_shadow_root_(false),
text_state_(behavior_), text_state_(behavior_),
text_node_handler_(behavior_, &text_state_) { text_node_handler_(behavior_, &text_state_) {
DCHECK(start.IsNotNull()); DCHECK(start_container_);
DCHECK(end.IsNotNull()); DCHECK(end_container_);
// TODO(dglazkov): TextIterator should not be created for documents that don't // TODO(dglazkov): TextIterator should not be created for documents that don't
// have a frame, but it currently still happens in some cases. See // have a frame, but it currently still happens in some cases. See
...@@ -183,43 +201,10 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm( ...@@ -183,43 +201,10 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm(
// in release build. // in release build.
CHECK_LE(start, end); CHECK_LE(start, end);
Node* const start_container = start.ComputeContainerNode();
const int start_offset = start.ComputeOffsetInContainerNode();
Node* const end_container = end.ComputeContainerNode();
const int end_offset = end.ComputeOffsetInContainerNode();
// Remember the range - this does not change.
start_container_ = start_container;
start_offset_ = start_offset;
end_container_ = end_container;
end_offset_ = end_offset;
end_node_ =
end_container && !end_container->IsCharacterDataNode() && end_offset > 0
? Strategy::ChildAt(*end_container, end_offset - 1)
: nullptr;
shadow_depth_ = ShadowDepthOf<Strategy>(*start_container, *end_container);
// Set up the current node for processing.
if (start_container->IsCharacterDataNode())
node_ = start_container;
else if (Node* child = Strategy::ChildAt(*start_container, start_offset))
node_ = child;
else if (!start_offset)
node_ = start_container;
else
node_ = Strategy::NextSkippingChildren(*start_container);
if (!node_) if (!node_)
return; return;
fully_clipped_stack_.SetUpFullyClippedStack(node_); fully_clipped_stack_.SetUpFullyClippedStack(node_);
iteration_progress_ = kHandledNone;
// Calculate first out of bounds node.
past_end_node_ = end_container
? PastLastNode<Strategy>(*end_container, end_offset)
: nullptr;
// Identify the first run. // Identify the first run.
Advance(); Advance();
......
...@@ -194,6 +194,16 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm { ...@@ -194,6 +194,16 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm {
int position, int position,
int copy_length) const; int copy_length) const;
// The range.
const Member<Node> start_container_;
const int start_offset_;
const Member<Node> end_container_;
const int end_offset_;
// |m_endNode| stores |Strategy::childAt(*m_endContainer, m_endOffset - 1)|,
// if it exists, or |nullptr| otherwise.
const Member<Node> end_node_;
const Member<Node> past_end_node_;
// Current position, not necessarily of the text being returned, but position // Current position, not necessarily of the text being returned, but position
// as we walk through the DOM tree. // as we walk through the DOM tree.
Member<Node> node_; Member<Node> node_;
...@@ -201,20 +211,10 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm { ...@@ -201,20 +211,10 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm {
FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_; FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_;
int shadow_depth_; int shadow_depth_;
// The range.
Member<Node> start_container_;
int start_offset_;
Member<Node> end_container_;
int end_offset_;
// |m_endNode| stores |Strategy::childAt(*m_endContainer, m_endOffset - 1)|,
// if it exists, or |nullptr| otherwise.
Member<Node> end_node_;
Member<Node> past_end_node_;
// Used when there is still some pending text from the current node; when // Used when there is still some pending text from the current node; when
// these are false, we go back to normal iterating. // these are false, we go back to normal iterating.
bool needs_another_newline_; bool needs_another_newline_ = false;
bool needs_handle_replaced_element_; bool needs_handle_replaced_element_ = false;
Member<Text> last_text_node_; Member<Text> last_text_node_;
...@@ -222,10 +222,10 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm { ...@@ -222,10 +222,10 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm {
// Used when stopsOnFormControls() is true to determine if the iterator should // Used when stopsOnFormControls() is true to determine if the iterator should
// keep advancing. // keep advancing.
bool should_stop_; bool should_stop_ = false;
// Used for use counter |InnerTextWithShadowTree| and // Used for use counter |InnerTextWithShadowTree| and
// |SelectionToStringWithShadowTree|, we should not use other purpose. // |SelectionToStringWithShadowTree|, we should not use other purpose.
bool handle_shadow_root_; bool handle_shadow_root_ = false;
// Contains state of emitted text. // Contains state of emitted text.
TextIteratorTextState text_state_; TextIteratorTextState text_state_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment