Index: third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp |
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp |
index 5b1c1a49fb8d07110d0ce48a0cbede631293c814..63417b445365c5aa86ad7e1cfd85c5a76d4ebf6e 100644 |
--- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp |
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp |
@@ -152,29 +152,27 @@ bool IsRenderedAsTable(const Node* node) { |
} // namespace |
+TextIteratorTextNodeHandler::TextIteratorTextNodeHandler( |
+ const TextIteratorBehavior& behavior, |
+ TextIteratorTextState* text_state) |
+ : behavior_(behavior), text_state_(*text_state) {} |
+ |
template <typename Strategy> |
TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm( |
const PositionTemplate<Strategy>& start, |
const PositionTemplate<Strategy>& end, |
const TextIteratorBehavior& behavior) |
- : offset_(0), |
- start_container_(nullptr), |
+ : start_container_(nullptr), |
start_offset_(0), |
end_container_(nullptr), |
end_offset_(0), |
needs_another_newline_(false), |
- text_box_(nullptr), |
- remaining_text_box_(nullptr), |
- first_letter_text_(nullptr), |
last_text_node_(nullptr), |
- last_text_node_ended_with_collapsed_space_(false), |
- sorted_text_boxes_position_(0), |
behavior_(AdjustBehaviorFlags<Strategy>(behavior)), |
- needs_handle_pre_formatted_text_node_(false), |
- handled_first_letter_(false), |
should_stop_(false), |
handle_shadow_root_(false), |
- text_state_(behavior_) { |
+ text_state_(behavior_), |
+ text_node_handler_(behavior_, &text_state_) { |
DCHECK(start.IsNotNull()); |
DCHECK(end.IsNotNull()); |
@@ -195,6 +193,22 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm( |
end.ComputeContainerNode(), end.ComputeOffsetInContainerNode()); |
} |
+void TextIteratorTextNodeHandler::Initialize(Node* start_container, |
+ int start_offset, |
+ Node* end_container, |
+ int end_offset) { |
+ // This function should be called only once. |
+ DCHECK(!start_container_); |
yosin_UTC9
2017/05/29 09:12:59
nit: Please add DCHECK(start_container) and DCHECK
Xiaocheng
2017/05/30 03:01:49
This has been DCHECKed in TI::Initialize.
|
+ DCHECK_EQ(start_offset_, 0); |
+ DCHECK(!end_container_); |
+ DCHECK_EQ(end_offset_, 0); |
+ |
+ start_container_ = start_container; |
+ start_offset_ = start_offset; |
+ end_container_ = end_container; |
+ end_offset_ = end_offset; |
+} |
+ |
template <typename Strategy> |
void TextIteratorAlgorithm<Strategy>::Initialize(Node* start_container, |
int start_offset, |
@@ -203,6 +217,9 @@ void TextIteratorAlgorithm<Strategy>::Initialize(Node* start_container, |
DCHECK(start_container); |
DCHECK(end_container); |
+ text_node_handler_.Initialize(start_container, start_offset, end_container, |
+ end_offset); |
+ |
// Remember the range - this does not change. |
start_container_ = start_container; |
start_offset_ = start_offset; |
@@ -264,8 +281,7 @@ bool TextIteratorAlgorithm<Strategy>::IsInsideAtomicInlineElement() const { |
return layout_object && layout_object->IsAtomicInlineLevel(); |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::HandleRemainingTextRuns() { |
+bool TextIteratorTextNodeHandler::HandleRemainingTextRuns() { |
if (ShouldProceedToRemainingText()) |
ProceedToRemainingText(); |
// Handle remembered text box |
@@ -307,7 +323,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() { |
return; |
} |
- if (HandleRemainingTextRuns()) |
+ if (text_node_handler_.HandleRemainingTextRuns()) |
return; |
while (node_ && (node_ != past_end_node_ || shadow_depth_ > 0)) { |
@@ -511,8 +527,7 @@ static bool HasVisibleTextNode(LayoutText* layout_object) { |
EVisibility::kVisible; |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::ShouldHandleFirstLetter( |
+bool TextIteratorTextNodeHandler::ShouldHandleFirstLetter( |
const LayoutText& layout_text) const { |
if (handled_first_letter_) |
return false; |
@@ -522,8 +537,7 @@ bool TextIteratorAlgorithm<Strategy>::ShouldHandleFirstLetter( |
return offset_ < static_cast<int>(text_fragment.TextStartOffset()); |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::HandlePreFormattedTextNode() { |
+void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() { |
// TODO(xiaochengh): Get rid of repeated computation of these fields. |
LayoutText* const layout_object = text_node_->GetLayoutObject(); |
const String str = layout_object->GetText(); |
@@ -592,8 +606,11 @@ bool TextIteratorAlgorithm<Strategy>::HandleTextNode() { |
DCHECK_NE(last_text_node_, node_) |
<< "We should never call HandleTextNode on the same node twice"; |
last_text_node_ = ToText(node_); |
+ return text_node_handler_.HandleTextNode(ToText(node_)); |
+} |
- text_node_ = ToText(node_); |
+bool TextIteratorTextNodeHandler::HandleTextNode(Text* node) { |
+ text_node_ = node; |
offset_ = text_node_ == start_container_ ? start_offset_ : 0; |
handled_first_letter_ = false; |
first_letter_text_ = nullptr; |
@@ -646,8 +663,7 @@ bool TextIteratorAlgorithm<Strategy>::HandleTextNode() { |
} |
// Restore the collapsed space for copy & paste. See http://crbug.com/318925 |
-template <typename Strategy> |
-size_t TextIteratorAlgorithm<Strategy>::RestoreCollapsedTrailingSpace( |
+size_t TextIteratorTextNodeHandler::RestoreCollapsedTrailingSpace( |
InlineTextBox* next_text_box, |
size_t subrun_end) { |
if (next_text_box || !text_box_->Root().NextRootBox() || |
@@ -675,8 +691,7 @@ size_t TextIteratorAlgorithm<Strategy>::RestoreCollapsedTrailingSpace( |
return subrun_end; |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
+void TextIteratorTextNodeHandler::HandleTextBox() { |
LayoutText* layout_object = |
first_letter_text_ ? first_letter_text_ : text_node_->GetLayoutObject(); |
const unsigned text_start_offset = layout_object->TextStartOffset(); |
@@ -814,8 +829,7 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
} |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::ShouldProceedToRemainingText() const { |
+bool TextIteratorTextNodeHandler::ShouldProceedToRemainingText() const { |
if (text_box_ || !remaining_text_box_) |
return false; |
if (text_node_ != end_container_) |
@@ -823,16 +837,14 @@ bool TextIteratorAlgorithm<Strategy>::ShouldProceedToRemainingText() const { |
return offset_ < end_offset_; |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::ProceedToRemainingText() { |
+void TextIteratorTextNodeHandler::ProceedToRemainingText() { |
text_box_ = remaining_text_box_; |
remaining_text_box_ = 0; |
first_letter_text_ = nullptr; |
offset_ = text_node_->GetLayoutObject()->TextStartOffset(); |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::HandleTextNodeFirstLetter( |
+void TextIteratorTextNodeHandler::HandleTextNodeFirstLetter( |
LayoutTextFragment* layout_object) { |
handled_first_letter_ = true; |
@@ -873,8 +885,7 @@ bool TextIteratorAlgorithm<Strategy>::SupportsAltText(Node* node) { |
return false; |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::FixLeadingWhiteSpaceForReplacedElement( |
+bool TextIteratorTextNodeHandler::FixLeadingWhiteSpaceForReplacedElement( |
Node* parent) { |
// This is a hacky way for white space fixup in legacy layout. With LayoutNG, |
// we can get rid of this function. |
@@ -912,9 +923,9 @@ bool TextIteratorAlgorithm<Strategy>::HandleReplacedElement() { |
return true; |
} |
- DCHECK_EQ(last_text_node_, text_node_); |
+ DCHECK_EQ(last_text_node_, text_node_handler_.GetNode()); |
if (last_text_node_) { |
- if (FixLeadingWhiteSpaceForReplacedElement( |
+ if (text_node_handler_.FixLeadingWhiteSpaceForReplacedElement( |
Strategy::Parent(*last_text_node_))) |
return false; |
} |
@@ -1216,8 +1227,7 @@ void TextIteratorAlgorithm<Strategy>::ExitNode() { |
1); |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::ResetCollapsedWhiteSpaceFixup() { |
+void TextIteratorTextNodeHandler::ResetCollapsedWhiteSpaceFixup() { |
// This is a hacky way for white space fixup in legacy layout. With LayoutNG, |
// we can get rid of this function. |
last_text_node_ended_with_collapsed_space_ = false; |
@@ -1231,14 +1241,23 @@ void TextIteratorAlgorithm<Strategy>::SpliceBuffer(UChar c, |
int text_end_offset) { |
text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset, |
text_end_offset); |
- ResetCollapsedWhiteSpaceFixup(); |
+ text_node_handler_.ResetCollapsedWhiteSpaceFixup(); |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::EmitText(Node* text_node, |
- LayoutText* layout_object, |
+void TextIteratorTextNodeHandler::SpliceBuffer(UChar c, |
+ Node* text_node, |
+ Node* offset_base_node, |
int text_start_offset, |
int text_end_offset) { |
+ text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset, |
+ text_end_offset); |
+ ResetCollapsedWhiteSpaceFixup(); |
+} |
+ |
+void TextIteratorTextNodeHandler::EmitText(Node* text_node, |
+ LayoutText* layout_object, |
+ int text_start_offset, |
+ int text_end_offset) { |
text_state_.EmitText(text_node, layout_object, text_start_offset, |
text_end_offset); |
ResetCollapsedWhiteSpaceFixup(); |