Commit 90c2cf68 authored by Gayane Petrosyan's avatar Gayane Petrosyan Committed by Commit Bot

[SH-Blink] Add ranges to text fragment selector

Add range to text fragment selector when selection is too long is spans
across block boundaries.
Gradually add words from beginning and end of the selection until unique
match is found.

Bug: 1102382
Change-Id: I71ce2623dae410aa7f21861bf2a6de6911cfe692
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2412698
Commit-Queue: Gayane Petrosyan <gayane@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Reviewed-by: default avatarTommy Martino <tmartino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808404}
parent a9262353
...@@ -156,6 +156,7 @@ String GetWordsFromStart(String text, int word_num) { ...@@ -156,6 +156,7 @@ String GetWordsFromStart(String text, int word_num) {
constexpr int kExactTextMaxChars = 300; constexpr int kExactTextMaxChars = 300;
constexpr int kNoContextMinChars = 20; constexpr int kNoContextMinChars = 20;
constexpr int kMaxContextWords = 10; constexpr int kMaxContextWords = 10;
constexpr int kMaxRangeWords = 10;
void TextFragmentSelectorGenerator::UpdateSelection( void TextFragmentSelectorGenerator::UpdateSelection(
LocalFrame* selection_frame, LocalFrame* selection_frame,
...@@ -324,8 +325,73 @@ void TextFragmentSelectorGenerator::GenerateExactSelector() { ...@@ -324,8 +325,73 @@ void TextFragmentSelectorGenerator::GenerateExactSelector() {
} }
void TextFragmentSelectorGenerator::ExtendRangeSelector() { void TextFragmentSelectorGenerator::ExtendRangeSelector() {
// TODO(gayane): Generate range selector. DCHECK_EQ(kRange, step_);
DCHECK_EQ(kNeedsNewCandidate, state_);
// Give up if range is already too long.
if (num_range_start_words_ == kMaxRangeWords ||
num_range_end_words_ == kMaxRangeWords) {
step_ = kContext;
return;
}
// Initialize range start and end, if needed.
if (max_available_range_start_.IsEmpty() &&
max_available_range_end_.IsEmpty()) {
EphemeralRangeInFlatTree ephemeral_range(selection_range_);
Node& start_first_block_ancestor =
FindBuffer::GetFirstBlockLevelAncestorInclusive(
*ephemeral_range.StartPosition().ComputeContainerNode());
Node& end_first_block_ancestor =
FindBuffer::GetFirstBlockLevelAncestorInclusive(
*ephemeral_range.EndPosition().ComputeContainerNode());
// If selection starts and ends in the same block, then split selected text
// roughly in the middle.
// TODO(gayane): Should also check that there are no nested blocks.
if (start_first_block_ancestor.isSameNode(&end_first_block_ancestor)) {
String selection_text = PlainText(ephemeral_range);
selection_text.Ensure16Bit();
int selection_length = selection_text.length();
int mid_point =
FindNextWordForward(selection_text.Characters16(), selection_length,
selection_length / 2);
max_available_range_start_ = selection_text.Left(mid_point);
// If from middle till end of selection there is no word break, then we
// cannot use it for range end.
if (mid_point == selection_length) {
state_ = kFailure; state_ = kFailure;
return;
}
max_available_range_end_ =
selection_text.Right(selection_text.length() - mid_point - 1);
} else {
// If not the same node, then we use first and last block of the selection
// range.
max_available_range_start_ =
GetNextTextBlock(selection_range_->StartPosition());
max_available_range_end_ =
GetPreviousTextBlock(selection_range_->EndPosition());
}
}
String start =
GetWordsFromStart(max_available_range_start_, ++num_range_start_words_);
String end =
GetWordsFromEnd(max_available_range_end_, ++num_range_end_words_);
// If the start and end didn't change, it means we exhausted the selected
// text and should try adding context.
if (selector_ && start == selector_->Start() && end == selector_->End()) {
step_ = kContext;
return;
}
selector_ = std::make_unique<TextFragmentSelector>(
TextFragmentSelector::SelectorType::kRange, start, end, "", "");
state_ = kTestCandidate;
} }
void TextFragmentSelectorGenerator::ExtendContext() { void TextFragmentSelectorGenerator::ExtendContext() {
...@@ -347,9 +413,8 @@ void TextFragmentSelectorGenerator::ExtendContext() { ...@@ -347,9 +413,8 @@ void TextFragmentSelectorGenerator::ExtendContext() {
// Try initiating properties necessary for calculating prefix and suffix. // Try initiating properties necessary for calculating prefix and suffix.
if (max_available_prefix_.IsEmpty() && max_available_suffix_.IsEmpty()) { if (max_available_prefix_.IsEmpty() && max_available_suffix_.IsEmpty()) {
max_available_prefix_ = max_available_prefix_ =
GetAvailablePrefixAsText(selection_range_->StartPosition()); GetPreviousTextBlock(selection_range_->StartPosition());
max_available_suffix_ = max_available_suffix_ = GetNextTextBlock(selection_range_->EndPosition());
GetAvailableSuffixAsText(selection_range_->EndPosition());
} }
if (max_available_prefix_.IsEmpty() && max_available_suffix_.IsEmpty()) { if (max_available_prefix_.IsEmpty() && max_available_suffix_.IsEmpty()) {
...@@ -371,7 +436,7 @@ void TextFragmentSelectorGenerator::ExtendContext() { ...@@ -371,7 +436,7 @@ void TextFragmentSelectorGenerator::ExtendContext() {
state_ = kTestCandidate; state_ = kTestCandidate;
} }
String TextFragmentSelectorGenerator::GetAvailablePrefixAsText( String TextFragmentSelectorGenerator::GetPreviousTextBlock(
const Position& prefix_end_position) { const Position& prefix_end_position) {
Node* prefix_end = prefix_end_position.ComputeContainerNode(); Node* prefix_end = prefix_end_position.ComputeContainerNode();
unsigned prefix_end_offset = unsigned prefix_end_offset =
...@@ -399,7 +464,7 @@ String TextFragmentSelectorGenerator::GetAvailablePrefixAsText( ...@@ -399,7 +464,7 @@ String TextFragmentSelectorGenerator::GetAvailablePrefixAsText(
return PlainText(EphemeralRange(range_start, range_end)).StripWhiteSpace(); return PlainText(EphemeralRange(range_start, range_end)).StripWhiteSpace();
} }
String TextFragmentSelectorGenerator::GetAvailableSuffixAsText( String TextFragmentSelectorGenerator::GetNextTextBlock(
const Position& suffix_start_position) { const Position& suffix_start_position) {
Node* suffix_start = suffix_start_position.ComputeContainerNode(); Node* suffix_start = suffix_start_position.ComputeContainerNode();
unsigned suffix_start_offset = unsigned suffix_start_offset =
......
...@@ -54,11 +54,11 @@ class CORE_EXPORT TextFragmentSelectorGenerator final ...@@ -54,11 +54,11 @@ class CORE_EXPORT TextFragmentSelectorGenerator final
void NotifySelectorReady(const TextFragmentSelector& selector); void NotifySelectorReady(const TextFragmentSelector& selector);
// Wrappers for tests. // Wrappers for tests.
String GetAvailablePrefixAsTextForTesting(const Position& position) { String GetPreviousTextBlockForTesting(const Position& position) {
return GetAvailablePrefixAsText(position); return GetPreviousTextBlock(position);
} }
String GetAvailableSuffixAsTextForTesting(const Position& position) { String GetNextTextBlockForTesting(const Position& position) {
return GetAvailableSuffixAsText(position); return GetNextTextBlock(position);
} }
// Releases members if necessary. // Releases members if necessary.
...@@ -94,11 +94,11 @@ class CORE_EXPORT TextFragmentSelectorGenerator final ...@@ -94,11 +94,11 @@ class CORE_EXPORT TextFragmentSelectorGenerator final
// Returns max text preceding given position that doesn't cross block // Returns max text preceding given position that doesn't cross block
// boundaries. // boundaries.
String GetAvailablePrefixAsText(const Position& position); String GetPreviousTextBlock(const Position& position);
// Returns max text following given position that doesn't cross block // Returns max text following given position that doesn't cross block
// boundaries. // boundaries.
String GetAvailableSuffixAsText(const Position& position); String GetNextTextBlock(const Position& position);
void GenerateExactSelector(); void GenerateExactSelector();
void ExtendRangeSelector(); void ExtendRangeSelector();
...@@ -124,11 +124,17 @@ class CORE_EXPORT TextFragmentSelectorGenerator final ...@@ -124,11 +124,17 @@ class CORE_EXPORT TextFragmentSelectorGenerator final
String max_available_prefix_; String max_available_prefix_;
String max_available_suffix_; String max_available_suffix_;
String max_available_range_start_;
String max_available_range_end_;
// Indicates a number of words used from |max_available_prefix_| and // Indicates a number of words used from |max_available_prefix_| and
// |max_available_suffix_| for the current |selector_|. // |max_available_suffix_| for the current |selector_|.
int num_prefix_words_ = 0; int num_prefix_words_ = 0;
int num_suffix_words_ = 0; int num_suffix_words_ = 0;
int num_range_start_words_ = 0;
int num_range_end_words_ = 0;
DISALLOW_COPY_AND_ASSIGN(TextFragmentSelectorGenerator); DISALLOW_COPY_AND_ASSIGN(TextFragmentSelectorGenerator);
}; };
......
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