Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1654)

Unified Diff: third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp

Issue 2903693005: Introduce a wrapper class to handle text node in TextIterator (Closed)
Patch Set: Fri May 26 14:55:33 PDT 2017 Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..434c103581ef597155e5f6defcf32a92b35b3c68 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,16 @@ TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm(
end.ComputeContainerNode(), end.ComputeOffsetInContainerNode());
}
+void TextIteratorTextNodeHandler::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 +211,11 @@ void TextIteratorAlgorithm<Strategy>::Initialize(Node* start_container,
DCHECK(start_container);
DCHECK(end_container);
+ // TODO(xiaochengh): There is no need to pass the entire range. Instead, we
+ // can pass the start and end offsets when calling HandleTextNode().
+ text_node_handler_.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,20 +277,19 @@ 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
if (text_box_) {
HandleTextBox();
- return text_state_.PositionNode();
+ return text_state_->PositionNode();
}
// Handle remembered pre-formatted text node.
if (!needs_handle_pre_formatted_text_node_)
return false;
HandlePreFormattedTextNode();
- return text_state_.PositionNode();
+ return text_state_->PositionNode();
}
template <typename Strategy>
@@ -307,7 +319,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 +523,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 +533,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 +602,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 +659,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 +687,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();
@@ -707,8 +718,8 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() {
text_box_start == run_start && run_start > 0);
if (need_space &&
!layout_object->Style()->IsCollapsibleWhiteSpace(
- text_state_.LastCharacter()) &&
- text_state_.LastCharacter()) {
+ text_state_->LastCharacter()) &&
+ text_state_->LastCharacter()) {
if (run_start > 0 && str[run_start - 1] == ' ') {
unsigned space_run_start = run_start - 1;
while (space_run_start > 0 && str[space_run_start - 1] == ' ')
@@ -775,7 +786,7 @@ void TextIteratorAlgorithm<Strategy>::HandleTextBox() {
// If we are doing a subrun that doesn't go to the end of the text box,
// come back again to finish handling this text box; don't advance to
// the next one.
- if (static_cast<unsigned>(text_state_.PositionEndOffset()) <
+ if (static_cast<unsigned>(text_state_->PositionEndOffset()) <
text_box_end)
return;
@@ -814,8 +825,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 +833,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 +881,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 +919,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 +1223,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,16 +1237,25 @@ 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_.EmitText(text_node, layout_object, text_start_offset,
- 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();
}

Powered by Google App Engine
This is Rietveld 408576698