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 6aa72debc7f9020c41d6d310b9f74cb807320a55..31c02e0b0f78267a31fc25acff5213941febf42e 100644 |
--- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp |
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp |
@@ -152,29 +152,38 @@ bool IsRenderedAsTable(const Node* node) { |
} // namespace |
+TextNodeContentExtractor::TextNodeContentExtractor( |
+ const TextIteratorBehavior& behavior, |
+ TextIteratorTextState& text_state) |
+ : start_offset_(0), |
yosin_UTC9
2017/05/25 06:44:09
Initialization of member variables should be done
|
+ end_offset_(0), |
+ offset_(0), |
+ text_box_(nullptr), |
+ needs_handle_pre_formatted_text_node_(false), |
+ handled_first_letter_(false), |
+ remaining_text_box_(nullptr), |
+ first_letter_text_(nullptr), |
+ last_text_node_ended_with_collapsed_space_(false), |
+ sorted_text_boxes_position_(0), |
+ 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_extractor_(behavior_, text_state_) { |
DCHECK(start.IsNotNull()); |
DCHECK(end.IsNotNull()); |
@@ -195,6 +204,16 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm( |
end.ComputeContainerNode(), end.ComputeOffsetInContainerNode()); |
} |
+void TextNodeContentExtractor::SetBoundaries(Node* start_container, |
+ int start_offset, |
+ Node* end_container, |
+ int end_offset) { |
+ 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 +222,9 @@ void TextIteratorAlgorithm<Strategy>::Initialize(Node* start_container, |
DCHECK(start_container); |
DCHECK(end_container); |
+ text_extractor_.SetBoundaries(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 +286,7 @@ bool TextIteratorAlgorithm<Strategy>::IsInsideAtomicInlineElement() const { |
return layout_object && layout_object->IsAtomicInlineLevel(); |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::HandleRemainingTextRuns() { |
+bool TextNodeContentExtractor::HandleRemainingTextRuns() { |
if (ShouldProceedToRemainingText()) |
ProceedToRemainingText(); |
// handle remembered text box |
@@ -307,7 +328,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() { |
return; |
} |
- if (HandleRemainingTextRuns()) |
+ if (text_extractor_.HandleRemainingTextRuns()) |
return; |
while (node_ && (node_ != past_end_node_ || shadow_depth_ > 0)) { |
@@ -511,8 +532,7 @@ static bool HasVisibleTextNode(LayoutText* layout_object) { |
EVisibility::kVisible; |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::ShouldHandleFirstLetter( |
+bool TextNodeContentExtractor::ShouldHandleFirstLetter( |
const LayoutText& layout_text) const { |
if (handled_first_letter_) |
return false; |
@@ -522,8 +542,7 @@ bool TextIteratorAlgorithm<Strategy>::ShouldHandleFirstLetter( |
return offset_ < static_cast<int>(text_fragment.TextStartOffset()); |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::HandlePreFormattedTextNode() { |
+void TextNodeContentExtractor::HandlePreFormattedTextNode() { |
// TODO(xiaochengh): Get rid of repeated computation of these fields. |
LayoutText* const layout_object = text_node_->GetLayoutObject(); |
const String str = layout_object->GetText(); |
@@ -535,7 +554,8 @@ void TextIteratorAlgorithm<Strategy>::HandlePreFormattedTextNode() { |
if (HasVisibleTextNode(layout_object)) { |
if (!behavior_.CollapseTrailingSpace() || |
(offset_ > 0 && str[offset_ - 1] == ' ')) { |
- SpliceBuffer(kSpaceCharacter, text_node_, 0, offset_, offset_); |
+ text_state_.SpliceBuffer(kSpaceCharacter, text_node_, 0, offset_, |
+ offset_); |
needs_handle_pre_formatted_text_node_ = true; |
return; |
} |
@@ -551,7 +571,7 @@ void TextIteratorAlgorithm<Strategy>::HandlePreFormattedTextNode() { |
end_offset_ <= static_cast<int>(first_letter.length()); |
const unsigned run_end = |
stops_in_first_letter ? end_offset_ : first_letter.length(); |
- EmitText(text_node_, first_letter_text_, run_start, run_end); |
+ text_state_.EmitText(text_node_, first_letter_text_, run_start, run_end); |
first_letter_text_ = nullptr; |
text_box_ = 0; |
offset_ = run_end; |
@@ -578,7 +598,8 @@ void TextIteratorAlgorithm<Strategy>::HandlePreFormattedTextNode() { |
if (run_start >= run_end) |
return; |
- EmitText(text_node_, text_node_->GetLayoutObject(), run_start, run_end); |
+ text_state_.EmitText(text_node_, text_node_->GetLayoutObject(), run_start, |
+ run_end); |
} |
template <typename Strategy> |
@@ -594,8 +615,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_extractor_.HandleTextNode(ToText(node_)); |
+} |
- text_node_ = ToText(node_); |
+bool TextNodeContentExtractor::HandleTextNode(Text* node) { |
+ text_node_ = node; |
offset_ = text_node_ == start_container_ ? start_offset_ : 0; |
handled_first_letter_ = false; |
first_letter_text_ = nullptr; |
@@ -648,8 +672,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 TextNodeContentExtractor::RestoreCollapsedTrailingSpace( |
InlineTextBox* next_text_box, |
size_t subrun_end) { |
if (next_text_box || !text_box_->Root().NextRootBox() || |
@@ -677,8 +700,7 @@ size_t TextIteratorAlgorithm<Strategy>::RestoreCollapsedTrailingSpace( |
return subrun_end; |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
+void TextNodeContentExtractor::HandleTextBox() { |
LayoutText* layout_object = |
first_letter_text_ ? first_letter_text_ : text_node_->GetLayoutObject(); |
const unsigned text_start_offset = layout_object->TextStartOffset(); |
@@ -716,10 +738,11 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
unsigned space_run_start = run_start - 1; |
while (space_run_start > 0 && str[space_run_start - 1] == ' ') |
--space_run_start; |
- EmitText(text_node_, layout_object, space_run_start, |
- space_run_start + 1); |
+ text_state_.EmitText(text_node_, layout_object, space_run_start, |
yosin_UTC9
2017/05/25 06:44:09
Let's introduce TextNodeContentExtract::EmitText()
Xiaocheng
2017/05/25 23:47:58
Done.
|
+ space_run_start + 1); |
} else { |
- SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start, run_start); |
+ text_state_.SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start, |
yosin_UTC9
2017/05/25 06:44:09
Let's introduce TextNodeContentExtract::SpliceBuff
Xiaocheng
2017/05/25 23:47:58
Done.
|
+ run_start); |
} |
return; |
} |
@@ -757,10 +780,10 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
// We need to preserve new lines in case of PreLine. |
// See bug crbug.com/317365. |
if (layout_object->Style()->WhiteSpace() == EWhiteSpace::kPreLine) { |
- SpliceBuffer('\n', text_node_, 0, run_start, run_start); |
+ text_state_.SpliceBuffer('\n', text_node_, 0, run_start, run_start); |
} else { |
- SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start, |
- run_start + 1); |
+ text_state_.SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start, |
+ run_start + 1); |
} |
offset_ = text_start_offset + run_start + 1; |
} else { |
@@ -772,7 +795,8 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
} |
offset_ = text_start_offset + subrun_end; |
- EmitText(text_node_, layout_object, run_start, subrun_end); |
+ text_state_.EmitText(text_node_, layout_object, run_start, |
+ subrun_end); |
} |
// If we are doing a subrun that doesn't go to the end of the text box, |
@@ -817,8 +841,7 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() { |
} |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::ShouldProceedToRemainingText() const { |
+bool TextNodeContentExtractor::ShouldProceedToRemainingText() const { |
if (text_box_ || !remaining_text_box_) |
return false; |
if (text_node_ != end_container_) |
@@ -826,16 +849,14 @@ bool TextIteratorAlgorithm<Strategy>::ShouldProceedToRemainingText() const { |
return offset_ < end_offset_; |
} |
-template <typename Strategy> |
-void TextIteratorAlgorithm<Strategy>::ProceedToRemainingText() { |
+void TextNodeContentExtractor::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 TextNodeContentExtractor::HandleTextNodeFirstLetter( |
LayoutTextFragment* layout_object) { |
handled_first_letter_ = true; |
@@ -876,21 +897,20 @@ bool TextIteratorAlgorithm<Strategy>::SupportsAltText(Node* node) { |
return false; |
} |
-template <typename Strategy> |
-bool TextIteratorAlgorithm<Strategy>::FixLeadingWhiteSpaceForReplacedElement( |
+bool TextNodeContentExtractor::FixLeadingWhiteSpaceForReplacedElement( |
Node* parent) { |
if (!last_text_node_ended_with_collapsed_space_) |
return false; |
last_text_node_ended_with_collapsed_space_ = false; |
if (!behavior_.CollapseTrailingSpace()) { |
- SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1); |
+ text_state_.SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1); |
return true; |
} |
if (text_node_) { |
const String str = text_node_->GetLayoutObject()->GetText(); |
if (offset_ > 0 && str[offset_ - 1] == ' ') { |
- SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1); |
+ text_state_.SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1); |
return true; |
} |
} |
@@ -915,7 +935,7 @@ bool TextIteratorAlgorithm<Strategy>::HandleReplacedElement() { |
} |
if (last_text_node_) { |
- if (FixLeadingWhiteSpaceForReplacedElement( |
+ if (text_extractor_.FixLeadingWhiteSpaceForReplacedElement( |
Strategy::Parent(*last_text_node_))) |
return false; |
} |