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

Unified Diff: third_party/WebKit/Source/core/editing/VisibleUnits.cpp

Issue 2925063002: ALL-IN-ONE: Refactor ComputeInlineBoxPosition() (Closed)
Patch Set: 2017-06-08T19:15:47 Created 3 years, 6 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/VisibleUnits.cpp
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 8bf72e4bb23fdd0318d0ae852edb090b2a798f10..b9c70ccd23c3f09a9e39706d2d157ce810d3b37e 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -882,90 +882,127 @@ static bool IsStartOfDifferentDirection(const InlineBox* inline_box) {
return prev_box->BidiLevel() > inline_box->BidiLevel();
}
+// TODO(yosin): We have a forward declaration here to reduce patch size. We'll
+// replica this with an implementation once review finished.
+static InlineBoxPosition ComputeInlineBoxPositionInternal(LayoutObject*,
+ InlineBox*,
+ int,
+ TextDirection);
+
+// TODO(yosin): We have a forward declaration here to reduce patch size. We'll
+// replica this with an implementation once review finished.
+static InlineBoxPosition ComputeInlineBoxPositionForTextNode(LayoutText*,
+ int,
+ TextAffinity,
+ TextDirection);
+
template <typename Strategy>
static InlineBoxPosition ComputeInlineBoxPositionTemplate(
const PositionTemplate<Strategy>& position,
TextAffinity affinity,
TextDirection primary_direction) {
- InlineBox* inline_box = nullptr;
- int caret_offset = position.ComputeEditingOffset();
+ const int caret_offset = position.ComputeEditingOffset();
Node* const anchor_node = position.AnchorNode();
- LayoutObject* layout_object =
+ LayoutObject* const layout_object =
anchor_node->IsShadowRoot()
? ToShadowRoot(anchor_node)->host().GetLayoutObject()
: anchor_node->GetLayoutObject();
DCHECK(layout_object) << position;
- if (!layout_object->IsText()) {
- inline_box = 0;
- if (CanHaveChildrenForEditing(anchor_node) &&
- layout_object->IsLayoutBlockFlow() &&
- HasRenderedNonAnonymousDescendantsWithHeight(layout_object)) {
- // Try a visually equivalent position with possibly opposite
- // editability. This helps in case |this| is in an editable block
- // but surrounded by non-editable positions. It acts to negate the
- // logic at the beginning of
- // |LayoutObject::createPositionWithAffinity()|.
- PositionTemplate<Strategy> equivalent =
- DownstreamIgnoringEditingBoundaries(position);
- if (equivalent == position) {
- equivalent = UpstreamIgnoringEditingBoundaries(position);
- if (equivalent == position ||
- DownstreamIgnoringEditingBoundaries(equivalent) == position)
- return InlineBoxPosition(inline_box, caret_offset);
- }
-
- return ComputeInlineBoxPosition(equivalent, TextAffinity::kUpstream,
- primary_direction);
- }
- if (layout_object->IsBox()) {
- inline_box = ToLayoutBox(layout_object)->InlineBoxWrapper();
- if (!inline_box || (caret_offset > inline_box->CaretMinOffset() &&
- caret_offset < inline_box->CaretMaxOffset()))
- return InlineBoxPosition(inline_box, caret_offset);
+ if (layout_object->IsText()) {
+ return ComputeInlineBoxPositionForTextNode(
+ ToLayoutText(layout_object), caret_offset, affinity, primary_direction);
+ }
+ if (CanHaveChildrenForEditing(anchor_node) &&
+ layout_object->IsLayoutBlockFlow() &&
+ HasRenderedNonAnonymousDescendantsWithHeight(layout_object)) {
+ // Try a visually equivalent position with possibly opposite
+ // editability. This helps in case |this| is in an editable block
+ // but surrounded by non-editable positions. It acts to negate the
+ // logic at the beginning of
+ // |LayoutObject::createPositionWithAffinity()|.
+ const PositionTemplate<Strategy>& downstream_equivalent =
+ DownstreamIgnoringEditingBoundaries(position);
+ if (downstream_equivalent != position) {
+ return ComputeInlineBoxPosition(
+ downstream_equivalent, TextAffinity::kUpstream, primary_direction);
}
- } else {
- LayoutText* text_layout_object = ToLayoutText(layout_object);
-
- InlineTextBox* candidate = nullptr;
-
- for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) {
- int caret_min_offset = box->CaretMinOffset();
- int caret_max_offset = box->CaretMaxOffset();
+ const PositionTemplate<Strategy>& upstream_equivalent =
+ UpstreamIgnoringEditingBoundaries(position);
+ if (upstream_equivalent == position ||
+ DownstreamIgnoringEditingBoundaries(upstream_equivalent) == position)
+ return InlineBoxPosition();
+ return ComputeInlineBoxPosition(upstream_equivalent,
+ TextAffinity::kUpstream, primary_direction);
+ }
+ if (!layout_object->IsBox())
+ return InlineBoxPosition();
+ InlineBox* const box = ToLayoutBox(layout_object)->InlineBoxWrapper();
+ if (!box)
+ return InlineBoxPosition();
+ if (caret_offset > box->CaretMinOffset() &&
+ caret_offset < box->CaretMaxOffset()) {
+ return InlineBoxPosition(box, caret_offset);
+ }
+ return ComputeInlineBoxPositionInternal(layout_object, box, caret_offset,
+ primary_direction);
+}
- if (caret_offset < caret_min_offset || caret_offset > caret_max_offset ||
- (caret_offset == caret_max_offset && box->IsLineBreak()))
- continue;
+static InlineBoxPosition ComputeInlineBoxPositionForTextNode(
+ LayoutText* text_layout_object,
+ int caret_offset,
+ TextAffinity affinity,
+ TextDirection primary_direction) {
+ InlineTextBox* inline_box = nullptr;
+ InlineTextBox* candidate = nullptr;
+ for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) {
+ const int caret_min_offset = box->CaretMinOffset();
+ const int caret_max_offset = box->CaretMaxOffset();
- if (caret_offset > caret_min_offset && caret_offset < caret_max_offset)
- return InlineBoxPosition(box, caret_offset);
+ if (caret_offset < caret_min_offset || caret_offset > caret_max_offset ||
+ (caret_offset == caret_max_offset && box->IsLineBreak()))
+ continue;
- if (((caret_offset == caret_max_offset) ^
- (affinity == TextAffinity::kDownstream)) ||
- ((caret_offset == caret_min_offset) ^
- (affinity == TextAffinity::kUpstream)) ||
- (caret_offset == caret_max_offset && box->NextLeafChild() &&
- box->NextLeafChild()->IsLineBreak())) {
- inline_box = box;
- break;
- }
+ if (caret_offset > caret_min_offset && caret_offset < caret_max_offset)
+ return InlineBoxPosition(box, caret_offset);
- candidate = box;
+ if (((caret_offset == caret_max_offset) ^
+ (affinity == TextAffinity::kDownstream)) ||
+ ((caret_offset == caret_min_offset) ^
+ (affinity == TextAffinity::kUpstream)) ||
+ (caret_offset == caret_max_offset && box->NextLeafChild() &&
+ box->NextLeafChild()->IsLineBreak())) {
+ inline_box = box;
+ break;
}
- if (candidate && candidate == text_layout_object->LastTextBox() &&
- affinity == TextAffinity::kDownstream) {
- inline_box = SearchAheadForBetterMatch(text_layout_object);
Xiaocheng 2017/06/08 21:34:12 I don't understand this part. It seems to be sett
yosin_UTC9 2017/06/09 01:55:55 Setting |inline_box| is one in the loop at L976. A
- if (inline_box)
- caret_offset = inline_box->CaretMinOffset();
+
+ candidate = box;
+ }
+ if (candidate && candidate == text_layout_object->LastTextBox() &&
+ affinity == TextAffinity::kDownstream) {
+ if (InlineBox* found = SearchAheadForBetterMatch(text_layout_object)) {
+ return ComputeInlineBoxPositionInternal(text_layout_object, found,
+ found->CaretMinOffset(),
+ primary_direction);
}
- if (!inline_box)
- inline_box = candidate;
}
+ if (inline_box) {
+ return ComputeInlineBoxPositionInternal(text_layout_object, inline_box,
+ caret_offset, primary_direction);
+ }
+ if (candidate) {
+ return ComputeInlineBoxPositionInternal(text_layout_object, candidate,
+ caret_offset, primary_direction);
+ }
+ return InlineBoxPosition();
+}
- if (!inline_box)
- return InlineBoxPosition(inline_box, caret_offset);
-
+static InlineBoxPosition ComputeInlineBoxPositionInternal(
+ LayoutObject* layout_object,
+ InlineBox* inline_box,
+ int caret_offset,
+ TextDirection primary_direction) {
unsigned char level = inline_box->BidiLevel();
if (inline_box->Direction() == primary_direction) {
@@ -1040,8 +1077,7 @@ static InlineBoxPosition ComputeInlineBoxPositionTemplate(
return InlineBoxPosition(inline_box, caret_offset);
}
- if (layout_object &&
- layout_object->Style()->GetUnicodeBidi() == UnicodeBidi::kPlaintext) {
+ if (layout_object->Style()->GetUnicodeBidi() == UnicodeBidi::kPlaintext) {
if (inline_box->BidiLevel() < level)
return InlineBoxPosition(inline_box, inline_box->CaretLeftmostOffset());
return InlineBoxPosition(inline_box, inline_box->CaretRightmostOffset());
@@ -1128,12 +1164,14 @@ LayoutRect LocalCaretRectOfPositionTemplate(
InlineBoxPosition box_position =
ComputeInlineBoxPosition(position.GetPosition(), position.Affinity());
- if (box_position.inline_box)
- layout_object = LineLayoutAPIShim::LayoutObjectFrom(
- box_position.inline_box->GetLineLayoutItem());
+ if (box_position.inline_box) {
+ return LineLayoutAPIShim::LayoutObjectFrom(
+ box_position.inline_box->GetLineLayoutItem())
+ ->LocalCaretRect(box_position.inline_box, box_position.offset_in_box);
+ }
- return layout_object->LocalCaretRect(box_position.inline_box,
- box_position.offset_in_box);
+ return layout_object->LocalCaretRect(
yosin_UTC9 2017/06/08 10:19:24 Since ComputeInlineBoxPosition() returns offset ze
+ nullptr, position.GetPosition().ComputeEditingOffset());
}
// This function was added because the caret rect that is calculated by

Powered by Google App Engine
This is Rietveld 408576698