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

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

Issue 2968803002: EXPERIMENT TextIterator built on Layout NG offset mapping
Patch Set: Mon Jul 17 15:55:29 PDT 2017 Created 3 years, 5 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/TextIteratorTextNodeHandler.cpp
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp
index e4bf6aeffaf43c2e7c4fd68178a07ba42be38811..d786b02ab5eebd5ae8879c4176be1b47d3fc8830 100644
--- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp
@@ -6,10 +6,13 @@
#include <algorithm>
#include "core/dom/FirstLetterPseudoElement.h"
+#include "core/editing/VisibleUnits.h"
#include "core/editing/iterators/TextIteratorTextState.h"
#include "core/layout/LayoutTextFragment.h"
#include "core/layout/line/InlineTextBox.h"
#include "core/layout/line/RootInlineBox.h"
+#include "core/layout/ng/inline/ng_inline_node.h"
+#include "core/layout/ng/layout_ng_block_flow.h"
namespace blink {
@@ -24,6 +27,11 @@ DEFINE_TRACE(TextIteratorTextNodeHandler) {
}
bool TextIteratorTextNodeHandler::HandleRemainingTextRuns() {
+ if (ng_block_flow_) {
+ HandleTextNodeInNGBlockFlow(*ng_block_flow_);
+ return text_state_->PositionNode();
+ }
+
if (ShouldProceedToRemainingText())
ProceedToRemainingText();
// Handle remembered text box
@@ -120,18 +128,62 @@ void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() {
EmitText(text_node_, text_node_->GetLayoutObject(), run_start, run_end);
}
+void TextIteratorTextNodeHandler::HandleTextNodeInNGBlockFlow(
+ const LayoutNGBlockFlow& block) {
+ if (block != ng_block_flow_) {
+ mapping_result_ = NGInlineNode(const_cast<LayoutNGBlockFlow*>(&block))
+ .BuildOffsetMapping();
+ ng_block_flow_ = &block;
+ }
+
+ const LayoutObject* layout_object =
+ AssociatedLayoutObjectOf(*text_node_, offset_);
+
+ // Skip invisible content.
+ if (layout_object->Style()->Display() == EDisplay::kNone ||
+ (layout_object->Style()->Visibility() != EVisibility::kVisible &&
+ !IgnoresStyleVisibility())) {
+ offset_ = end_offset_;
+ return;
+ }
+
+ while (offset_ < end_offset_ && !text_state_->PositionNode()) {
+ const NGOffsetMappingUnit* unit =
+ mapping_result_.GetMappingUnitForDOMOffset(*text_node_, offset_);
+ // No more text on this node to emit.
+ if (!unit || static_cast<unsigned>(offset_) == unit->dom_end) {
+ offset_ = end_offset_;
+ return;
+ }
+
+ const unsigned run_end =
+ std::min(static_cast<unsigned>(end_offset_), unit->dom_end);
+ if (unit->type == NGOffsetMappingUnitType::kCollapsed) {
+ offset_ = run_end;
+ continue;
+ }
+
+ // TODO(xiaochengh): Handle EmitsOriginalText.
+
+ String string =
+ NGInlineNode(const_cast<LayoutNGBlockFlow*>(ng_block_flow_)).Text();
+ if (behavior_.EmitsSpaceForNbsp())
+ string.Replace(kNoBreakSpaceCharacter, kSpaceCharacter);
+ const unsigned text_content_start = unit->DOMToTextContentOffset(offset_);
+ const unsigned text_content_end = unit->DOMToTextContentOffset(run_end);
+ text_state_->EmitText(text_node_, offset_, run_end, string,
+ text_content_start, text_content_end);
+ offset_ = run_end;
+ return;
+ }
+}
+
void TextIteratorTextNodeHandler::HandleTextNodeInRange(Text* node,
int start_offset,
int end_offset) {
DCHECK(node);
DCHECK_GE(start_offset, 0);
-
- // TODO(editing-dev): Add the following DCHECK once we stop assuming equal
- // number of code units in DOM string and LayoutText::GetText(). Currently
- // violated by
- // - external/wpt/innerText/getter.html
- // - fast/css/case-transform.html
- // DCHECK_LE(end_offset, static_cast<int>(node->data().length()));
+ DCHECK_LE(end_offset, static_cast<int>(node->data().length()));
// TODO(editing-dev): Stop passing in |start_offset == end_offset|.
DCHECK_LE(start_offset, end_offset);
@@ -143,6 +195,13 @@ void TextIteratorTextNodeHandler::HandleTextNodeInRange(Text* node,
first_letter_text_ = nullptr;
LayoutText* layout_object = text_node_->GetLayoutObject();
+ const LayoutBox* enclosing_box = layout_object->EnclosingBox();
+ if (enclosing_box && enclosing_box->IsLayoutNGBlockFlow()) {
+ HandleTextNodeInNGBlockFlow(ToLayoutNGBlockFlow(*enclosing_box));
+ return;
+ }
+ ng_block_flow_ = nullptr;
+
String str = layout_object->GetText();
// handle pre-formatted text
@@ -189,9 +248,7 @@ void TextIteratorTextNodeHandler::HandleTextNodeInRange(Text* node,
void TextIteratorTextNodeHandler::HandleTextNodeStartFrom(Text* node,
int start_offset) {
- HandleTextNodeInRange(node, start_offset,
- node->GetLayoutObject()->TextStartOffset() +
- node->GetLayoutObject()->GetText().length());
+ HandleTextNodeInRange(node, start_offset, node->data().length());
}
void TextIteratorTextNodeHandler::HandleTextNodeEndAt(Text* node,
@@ -411,6 +468,8 @@ 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.
+ if (ng_block_flow_)
+ return false;
if (behavior_.CollapseTrailingSpace()) {
if (text_node_) {

Powered by Google App Engine
This is Rietveld 408576698