Commit 4d281c8d authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Make InlineContents traverse flat tree for previous and next

Currently, InlineContents creation and previous/next movement are done
by different implementations:

- When creating from a position, it traverses the flat tree until
  finding a node in a usable block flow;
- When moving previous/next, it traverses the layout tree until finding
  a useable block flow.

Since these operations are very similar, this patch change the latter
to also traverse on flat tree and share the traversal algorithm to
reduce duplicated logic. This also makes it easier to change
TextOffsetMapping not to cross text control boundaries (*).

(*) crrev.com/c/1327962

Bug: 901492
Change-Id: If7c3dd262903c1a0f81166f729614a8d810f5d27
Reviewed-on: https://chromium-review.googlesource.com/c/1327531Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarYoichi Osato <yoichio@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606748}
parent 7d6ae34d
......@@ -235,6 +235,7 @@ TextOffsetMapping::ForwardRange TextOffsetMapping::ForwardRangeOf(
// static
TextOffsetMapping::InlineContents TextOffsetMapping::FindBackwardInlineContents(
const PositionInFlatTree& position) {
// TODO(xiaochengh): Make this function not cross text control boundaries.
for (const Node* node = position.NodeAsRangeLastNode(); node;
node = FlatTreeTraversal::Previous(*node)) {
const InlineContents inline_contents = ComputeInlineContentsFromNode(*node);
......@@ -249,6 +250,7 @@ TextOffsetMapping::InlineContents TextOffsetMapping::FindBackwardInlineContents(
// with AfterNode(IMG) for <body><img></body>
TextOffsetMapping::InlineContents TextOffsetMapping::FindForwardInlineContents(
const PositionInFlatTree& position) {
// TODO(xiaochengh): Make this function not cross text control boundaries.
for (const Node* node = position.NodeAsRangeFirstNode(); node;
node = FlatTreeTraversal::Next(*node)) {
const InlineContents inline_contents = ComputeInlineContentsFromNode(*node);
......@@ -323,38 +325,38 @@ EphemeralRangeInFlatTree TextOffsetMapping::InlineContents::GetRange() const {
: PositionInFlatTree::AfterNode(last_node));
}
PositionInFlatTree
TextOffsetMapping::InlineContents::LastPositionBeforeBlockFlow() const {
DCHECK(block_flow_);
if (const Node* node = block_flow_->NonPseudoNode())
return PositionInFlatTree::BeforeNode(*node);
DCHECK(first_);
DCHECK(first_->NonPseudoNode());
return PositionInFlatTree::BeforeNode(*first_->NonPseudoNode());
}
PositionInFlatTree
TextOffsetMapping::InlineContents::FirstPositionAfterBlockFlow() const {
DCHECK(block_flow_);
if (const Node* node = block_flow_->NonPseudoNode())
return PositionInFlatTree::AfterNode(*node);
DCHECK(last_);
DCHECK(last_->NonPseudoNode());
return PositionInFlatTree::AfterNode(*last_->NonPseudoNode());
}
// static
TextOffsetMapping::InlineContents TextOffsetMapping::InlineContents::NextOf(
const InlineContents& inline_contents) {
for (LayoutObject* runner =
inline_contents.block_flow_->NextInPreOrderAfterChildren();
runner; runner = runner->NextInPreOrder()) {
if (!CanBeInlineContentsContainer(*runner))
continue;
const LayoutBlockFlow& block_flow = ToLayoutBlockFlow(*runner);
if (block_flow.IsFloatingOrOutOfFlowPositioned())
continue;
DCHECK(!block_flow.IsAtomicInlineLevel()) << block_flow;
return CreateInlineContentsFromBlockFlow(block_flow);
}
return InlineContents();
return TextOffsetMapping::FindForwardInlineContents(
inline_contents.FirstPositionAfterBlockFlow());
}
// static
TextOffsetMapping::InlineContents TextOffsetMapping::InlineContents::PreviousOf(
const InlineContents& inline_contents) {
for (LayoutObject* runner = inline_contents.block_flow_->PreviousInPreOrder();
runner; runner = runner->PreviousInPreOrder()) {
const LayoutBlockFlow* const block_flow =
ComputeInlineContentsAsBlockFlow(*runner);
if (!block_flow || block_flow->IsFloatingOrOutOfFlowPositioned())
continue;
DCHECK(!block_flow->IsDescendantOf(inline_contents.block_flow_))
<< block_flow;
DCHECK(!block_flow->IsAtomicInlineLevel()) << block_flow;
return CreateInlineContentsFromBlockFlow(*block_flow);
}
return InlineContents();
return TextOffsetMapping::FindBackwardInlineContents(
inline_contents.LastPositionBeforeBlockFlow());
}
std::ostream& operator<<(
......
......@@ -71,6 +71,9 @@ class CORE_EXPORT TextOffsetMapping final {
private:
friend class TextOffsetMapping;
PositionInFlatTree FirstPositionAfterBlockFlow() const;
PositionInFlatTree LastPositionBeforeBlockFlow() const;
const LayoutBlockFlow* block_flow_ = nullptr;
const LayoutObject* first_ = nullptr;
const LayoutObject* last_ = nullptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment