Commit 226a83f9 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Remove NGCaretNavigator

This is a follow-up of changing left/right caret movements from visual
to logical. As NGCaretNavigator is designed for visual caret movements,
it no longer serves any purpose here and hence is also removed.

Bug: 958831
Change-Id: I2b18cf81ca9a997851e05617927c608b4831abbe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1602975Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#658277}
parent 643463d3
...@@ -1982,7 +1982,6 @@ jumbo_source_set("unit_tests") { ...@@ -1982,7 +1982,6 @@ jumbo_source_set("unit_tests") {
"layout/ng/exclusions/ng_exclusion_space_test.cc", "layout/ng/exclusions/ng_exclusion_space_test.cc",
"layout/ng/geometry/ng_box_strut_test.cc", "layout/ng/geometry/ng_box_strut_test.cc",
"layout/ng/inline/ng_baseline_test.cc", "layout/ng/inline/ng_baseline_test.cc",
"layout/ng/inline/ng_caret_navigator_test.cc",
"layout/ng/inline/ng_caret_position_test.cc", "layout/ng/inline/ng_caret_position_test.cc",
"layout/ng/inline/ng_inline_fragment_traversal_test.cc", "layout/ng/inline/ng_inline_fragment_traversal_test.cc",
"layout/ng/inline/ng_inline_items_builder_test.cc", "layout/ng/inline/ng_inline_items_builder_test.cc",
......
...@@ -31,14 +31,13 @@ ...@@ -31,14 +31,13 @@
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/local_caret_rect.h"
#include "third_party/blink/renderer/core/editing/ng_flat_tree_shorthands.h" #include "third_party/blink/renderer/core/editing/ng_flat_tree_shorthands.h"
#include "third_party/blink/renderer/core/editing/text_affinity.h" #include "third_party/blink/renderer/core/editing/text_affinity.h"
#include "third_party/blink/renderer/core/editing/visible_units.h" #include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/float_quad.h"
...@@ -100,36 +99,10 @@ VisiblePositionTemplate<Strategy> VisiblePositionTemplate<Strategy>::Create( ...@@ -100,36 +99,10 @@ VisiblePositionTemplate<Strategy> VisiblePositionTemplate<Strategy>::Create(
const PositionWithAffinityTemplate<Strategy> upstream_position( const PositionWithAffinityTemplate<Strategy> upstream_position(
deep_position, TextAffinity::kUpstream); deep_position, TextAffinity::kUpstream);
if (!InSameLine(downstream_position, upstream_position)) if (AbsoluteCaretBoundsOf(downstream_position) !=
AbsoluteCaretBoundsOf(upstream_position)) {
return VisiblePositionTemplate<Strategy>(upstream_position); return VisiblePositionTemplate<Strategy>(upstream_position);
if (!NGOffsetMapping::AcceptsPosition(ToPositionInDOMTree(deep_position))) {
// editing/selection/mixed-editability-10.html reaches here.
// We can't check bidi in such case. Use downstream as the default.
// TODO(xiaochengh): Investigate why we reach here and how to work around.
return VisiblePositionTemplate<Strategy>(downstream_position);
} }
// Check if the position is at bidi boundary.
const LayoutObject* layout_object =
deep_position.AnchorNode()->GetLayoutObject();
DCHECK(layout_object) << position_with_affinity;
if (!layout_object->IsInline())
return VisiblePositionTemplate<Strategy>(downstream_position);
LayoutBlockFlow* const context =
NGOffsetMapping::GetInlineFormattingContextOf(*layout_object);
DCHECK(context);
DCHECK(context->IsLayoutNGMixin());
const NGOffsetMapping* mapping = NGInlineNode::GetOffsetMapping(context);
DCHECK(mapping);
const base::Optional<unsigned> offset =
mapping->GetTextContentOffset(ToPositionInDOMTree(deep_position));
DCHECK(offset.has_value());
if (NGCaretNavigator(*context).OffsetIsBidiBoundary(offset.value()))
return VisiblePositionTemplate<Strategy>(upstream_position);
return VisiblePositionTemplate<Strategy>(downstream_position); return VisiblePositionTemplate<Strategy>(downstream_position);
} }
......
...@@ -329,8 +329,6 @@ blink_core_sources("layout") { ...@@ -329,8 +329,6 @@ blink_core_sources("layout") {
"ng/inline/ng_baseline.h", "ng/inline/ng_baseline.h",
"ng/inline/ng_bidi_paragraph.cc", "ng/inline/ng_bidi_paragraph.cc",
"ng/inline/ng_bidi_paragraph.h", "ng/inline/ng_bidi_paragraph.h",
"ng/inline/ng_caret_navigator.cc",
"ng/inline/ng_caret_navigator.h",
"ng/inline/ng_caret_position.cc", "ng/inline/ng_caret_position.cc",
"ng/inline/ng_caret_position.h", "ng/inline/ng_caret_position.h",
"ng/inline/ng_caret_rect.cc", "ng/inline/ng_caret_rect.cc",
......
...@@ -309,11 +309,6 @@ In a bird's‐eye view, it consists of two parts: ...@@ -309,11 +309,6 @@ In a bird's‐eye view, it consists of two parts:
content of an inline formatting context (computed in [pre-layout]) and DOM content of an inline formatting context (computed in [pre-layout]) and DOM
positions in the context. See [design doc](https://goo.gl/CJbxky) for details. positions in the context. See [design doc](https://goo.gl/CJbxky) for details.
[NGCaretNavigator] provides functions for inspecting bidi levels and visual
ordering of text content, and supports visual left/right caret movements in the
text. See [design doc](http://bit.ly/2QVAwGq) for details.
[ICU BiDi]: http://userguide.icu-project.org/transforms/bidi [ICU BiDi]: http://userguide.icu-project.org/transforms/bidi
[UAX#9 Unicode Bidirectional Algorithm]: http://unicode.org/reports/tr9/ [UAX#9 Unicode Bidirectional Algorithm]: http://unicode.org/reports/tr9/
[UAX#9 Resolving Embedding Levels]: http://www.unicode.org/reports/tr9/#Resolving_Embedding_Levels [UAX#9 Resolving Embedding Levels]: http://www.unicode.org/reports/tr9/#Resolving_Embedding_Levels
...@@ -322,7 +317,6 @@ text. See [design doc](http://bit.ly/2QVAwGq) for details. ...@@ -322,7 +317,6 @@ text. See [design doc](http://bit.ly/2QVAwGq) for details.
[FontBaseline]: ../../../platform/fonts/FontBaseline.h [FontBaseline]: ../../../platform/fonts/FontBaseline.h
[NGBaselineAlgorithmType]: ng_baseline.h [NGBaselineAlgorithmType]: ng_baseline.h
[NGBaselineRequest]: ng_baseline.h [NGBaselineRequest]: ng_baseline.h
[NGCaretNavigator]: ng_caret_navigator.h
[NGBidiParagraph]: ng_bidi_paragraph.h [NGBidiParagraph]: ng_bidi_paragraph.h
[NGBlockNode]: ../ng_block_node.h [NGBlockNode]: ../ng_block_node.h
[NGBoxFragment]: ../ng_box_fragment.h [NGBoxFragment]: ../ng_box_fragment.h
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/editing/text_affinity.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include <unicode/ubidi.h>
namespace blink {
class LayoutBlockFlow;
struct NGInlineNodeData;
// Hosts the |text_content| of an inline formatting context and provides
// bidi-related utilities, including checking bidi levels, computing visual
// left/right characters and visual left/right caret movements.
// Design doc: http://bit.ly/2QVAwGq
class CORE_EXPORT NGCaretNavigator {
STACK_ALLOCATED();
public:
explicit NGCaretNavigator(const LayoutBlockFlow&);
~NGCaretNavigator();
const String& GetText() const;
bool IsBidiEnabled() const;
// Abstraction of a caret position in |text_|.
enum class PositionAnchorType { kBefore, kAfter };
struct Position {
// |index| is character index the |text_| string.
unsigned index;
PositionAnchorType type;
bool IsBeforeCharacter() const {
return type == PositionAnchorType::kBefore;
}
bool IsAfterCharacter() const { return type == PositionAnchorType::kAfter; }
bool operator==(const Position& other) const {
return index == other.index && type == other.type;
}
};
// Returns the bidi level or resolved direction of the character at the given
// logical |index|.
UBiDiLevel BidiLevelAt(unsigned index) const;
TextDirection TextDirectionAt(unsigned index) const;
// Returns true if the characters at indexes |offset - 1| and |offset| both
// exist and are at different bidi levels.
bool OffsetIsBidiBoundary(unsigned offset) const;
// Converts an (offset, affinity) pair into a |Position| type of this class.
// Intiontionally long name to indicate the hackiness for handling legacy
// callers.
Position CaretPositionFromTextContentOffsetAndAffinity(
unsigned offset,
TextAffinity affinity) const;
// Returns the visual left/right edge caret position of the character at the
// given logical |index|.
Position LeftEdgeOf(unsigned index) const;
Position RightEdgeOf(unsigned index) const;
// Left/right visual movements
// TODO(xiaochengh): Handle the following
// - Grapheme clusters
enum class VisualMovementResultType {
kWithinContext,
kBeforeContext,
kAfterContext,
kEnteredChildContext
};
// Given the character at the logical |index|, returns the logical index of
// the character at its left/right side.
struct VisualCharacterMovementResult {
bool IsWithinContext() const {
return type == VisualMovementResultType::kWithinContext;
}
bool IsBeforeContext() const {
return type == VisualMovementResultType::kBeforeContext;
}
bool IsAfterContext() const {
return type == VisualMovementResultType::kAfterContext;
}
VisualMovementResultType type;
base::Optional<unsigned> index;
};
VisualCharacterMovementResult LeftCharacterOf(unsigned index) const;
VisualCharacterMovementResult RightCharacterOf(unsigned index) const;
// Given a caret position, moves it left/right by one grapheme cluster and
// returns the result.
// Note: If we end up entering an inline block, the result |Position| is
// either before or after the inline block, depending on from which side the
// inline block is entered. For example:
// RightPositionOf(abc|<inline-block>def</inline-block>ghi)
// -> {inline-block, PositionAnchorType::kBefore}
// LeftPositionOf(abc<inline-block>def</inline-block>|ghi)
// -> {inline-block, PositionAnchorType::kAfter}
struct VisualCaretMovementResult {
bool IsWithinContext() const {
return type == VisualMovementResultType::kWithinContext;
}
bool IsBeforeContext() const {
return type == VisualMovementResultType::kBeforeContext;
}
bool IsAfterContext() const {
return type == VisualMovementResultType::kAfterContext;
}
bool HasEnteredChildContext() const {
return type == VisualMovementResultType::kEnteredChildContext;
}
VisualMovementResultType type;
base::Optional<Position> position;
};
VisualCaretMovementResult LeftPositionOf(const Position&) const;
VisualCaretMovementResult RightPositionOf(const Position&) const;
// TODO(xiaochengh): Specify and implement the behavior in edge cases, e.g.,
// when the leftmost character of the first line is CSS-generated.
Position LeftmostPositionInFirstLine() const;
Position RightmostPositionInFirstLine() const;
Position LeftmostPositionInLastLine() const;
Position RightmostPositionInLastLine() const;
private:
// A caret position is invalid if it is:
// - kAfter to a line break character.
// - Anchored to a collapsible space that's removed by line wrap.
// - Anchored to a character that's ignored in caret movement.
bool IsValidCaretPosition(const Position&) const;
bool IsLineBreak(unsigned index) const;
bool IsCollapsibleWhitespace(unsigned index) const;
bool IsCollapsedSpaceByLineWrap(unsigned index) const;
bool IsIgnoredInCaretMovement(unsigned index) const;
// Returns true if the character at |index| represents a child block
// formatting context that can be entered by caret navigation. Such contexts
// must be atomic inlines (inline block, inline table, ...) and must not host
// user agent shadow tree (which excludes, e.g., <input> and image alt text).
bool IsEnterableChildContext(unsigned index) const;
enum class MoveDirection { kTowardsLeft, kTowardsRight };
static MoveDirection OppositeDirectionOf(MoveDirection);
static bool TowardsSameDirection(MoveDirection, TextDirection);
// ------ Line-related functions ------
// A line contains a consecutive substring of |GetText()|. The lines should
// not overlap, and should together cover the entire |GetText()|.
struct Line {
unsigned start_offset;
unsigned end_offset;
TextDirection base_direction;
};
Line ContainingLineOf(unsigned index) const;
Vector<int32_t, 32> CharacterIndicesInVisualOrder(const Line&) const;
unsigned VisualMostForwardCharacterOf(const Line&,
MoveDirection direction) const;
unsigned VisualLastCharacterOf(const Line&) const;
unsigned VisualFirstCharacterOf(const Line&) const;
// ------ Implementation of public visual movement functions ------
Position EdgeOfInternal(unsigned index, MoveDirection) const;
VisualCharacterMovementResult MoveCharacterInternal(unsigned index,
MoveDirection) const;
VisualCaretMovementResult MoveCaretInternal(const Position&,
MoveDirection) const;
// Performs a "minimal" caret movement to the left/right without validating
// the result. The result might be invalid due to, e.g., anchored to an
// unallowed character, being visually the same as the input, etc. It's a
// subroutine of |MoveCaretInternal|, who keeps calling it until both of the
// folliwng are satisfied:
// - We've reached a valid caret position.
// - During the process, the caret has moved passing a character on which
// |IsIgnoredInCaretMovement| is false (indicated by |has_passed_character|).
struct UnvalidatedVisualCaretMovementResult {
VisualMovementResultType type;
base::Optional<Position> position;
bool has_passed_character = false;
};
UnvalidatedVisualCaretMovementResult MoveCaretWithoutValidation(
const Position&,
MoveDirection) const;
const NGInlineNodeData& GetData() const;
const LayoutBlockFlow& context_;
DocumentLifecycle::DisallowTransitionScope disallow_transition_;
};
CORE_EXPORT std::ostream& operator<<(std::ostream&,
const NGCaretNavigator::Position&);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/core/editing/ephemeral_range.h" #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/position.h" #include "third_party/blink/renderer/core/editing/position.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/platform/text/character.h" #include "third_party/blink/renderer/platform/text/character.h"
...@@ -509,16 +508,6 @@ Position NGOffsetMapping::GetLastPosition(unsigned offset) const { ...@@ -509,16 +508,6 @@ Position NGOffsetMapping::GetLastPosition(unsigned offset) const {
return CreatePositionForOffsetMapping(node, dom_offset); return CreatePositionForOffsetMapping(node, dom_offset);
} }
PositionWithAffinity NGOffsetMapping::GetPositionWithAffinity(
const NGCaretNavigator::Position& position) const {
if (position.IsBeforeCharacter()) {
return PositionWithAffinity(GetLastPosition(position.index),
TextAffinity::kDownstream);
}
return PositionWithAffinity(GetFirstPosition(position.index + 1),
TextAffinity::kUpstream);
}
bool NGOffsetMapping::HasBidiControlCharactersOnly(unsigned start, bool NGOffsetMapping::HasBidiControlCharactersOnly(unsigned start,
unsigned end) const { unsigned end) const {
DCHECK_LE(start, end); DCHECK_LE(start, end);
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/editing/forward.h" #include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator.h"
...@@ -219,13 +218,6 @@ class CORE_EXPORT NGOffsetMapping { ...@@ -219,13 +218,6 @@ class CORE_EXPORT NGOffsetMapping {
Position GetFirstPosition(unsigned) const; Position GetFirstPosition(unsigned) const;
Position GetLastPosition(unsigned) const; Position GetLastPosition(unsigned) const;
// Converts the given caret position on text content to a PositionWithAffinity
// in DOM. If |position| is before a character, the function creates a
// downstream position before |GetLastPosition()| of the character; otherwise,
// it returns an upstream position after |GetFirstPosition()| of the character
PositionWithAffinity GetPositionWithAffinity(
const NGCaretNavigator::Position& position) const;
// Returns all NGOffsetMappingUnits whose text content ranges has non-empty // Returns all NGOffsetMappingUnits whose text content ranges has non-empty
// (but possibly collapsed) intersection with (start, end). Note that units // (but possibly collapsed) intersection with (start, end). Note that units
// that only "touch" |start| or |end| are excluded. // that only "touch" |start| or |end| are excluded.
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <utility> #include <utility>
#include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
namespace blink { namespace blink {
......
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